Revision e1c5a2b3

b/slirp/libslirp.h
20 20

  
21 21
int slirp_redir(int is_udp, int host_port,
22 22
                struct in_addr guest_addr, int guest_port);
23
int slirp_add_exec(int do_pty, const char *args, int addr_low_byte,
23
int slirp_add_exec(int do_pty, const void *args, int addr_low_byte,
24 24
                   int guest_port);
25 25

  
26 26
extern const char *tftp_prefix;
27 27
extern char slirp_hostname[33];
28 28

  
29 29
void slirp_stats(void);
30
void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf,
31
		int size);
32
size_t slirp_socket_can_recv(int addr_low_byte, int guest_port);
30 33

  
31 34
#ifdef __cplusplus
32 35
}
b/slirp/main.h
51 51
#endif
52 52

  
53 53
void if_encap(const uint8_t *ip_data, int ip_data_len);
54
ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags);
b/slirp/misc.c
169 169
	(*ex_ptr)->ex_fport = port;
170 170
	(*ex_ptr)->ex_addr = addr;
171 171
	(*ex_ptr)->ex_pty = do_pty;
172
	(*ex_ptr)->ex_exec = strdup(exec);
172
	(*ex_ptr)->ex_exec = (do_pty == 3) ? exec : strdup(exec);
173 173
	(*ex_ptr)->ex_next = tmp_ptr;
174 174
	return 0;
175 175
}
b/slirp/sbuf.c
108 108
	 * ottherwise it'll arrive out of order, and hence corrupt
109 109
	 */
110 110
	if (!so->so_rcv.sb_cc)
111
	   ret = send(so->s, m->m_data, m->m_len, 0);
111
	   ret = slirp_send(so, m->m_data, m->m_len, 0);
112 112

  
113 113
	if (ret <= 0) {
114 114
		/*
b/slirp/slirp.c
21 21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 22
 * THE SOFTWARE.
23 23
 */
24
#include "qemu-common.h"
24 25
#include "slirp.h"
25 26

  
26 27
/* host address */
......
736 737
    return 0;
737 738
}
738 739

  
739
int slirp_add_exec(int do_pty, const char *args, int addr_low_byte,
740
int slirp_add_exec(int do_pty, const void *args, int addr_low_byte,
740 741
                  int guest_port)
741 742
{
742 743
    return add_exec(&exec_list, do_pty, (char *)args,
743 744
                    addr_low_byte, htons(guest_port));
744 745
}
746

  
747
ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
748
{
749
	if (so->s == -1 && so->extra) {
750
		qemu_chr_write(so->extra, buf, len);
751
		return len;
752
	}
753

  
754
	return send(so->s, buf, len, flags);
755
}
756

  
757
static struct socket *slirp_find_ctl_socket(int addr_low_byte, int guest_port)
758
{
759
	struct socket *so;
760

  
761
	for (so = tcb.so_next; so != &tcb; so = so->so_next) {
762
		if ((so->so_faddr.s_addr & htonl(0xffffff00)) ==
763
				special_addr.s_addr
764
				&& (ntohl(so->so_faddr.s_addr) & 0xff) ==
765
				addr_low_byte
766
				&& htons(so->so_fport) == guest_port)
767
			return so;
768
	}
769

  
770
	return NULL;
771
}
772

  
773
size_t slirp_socket_can_recv(int addr_low_byte, int guest_port)
774
{
775
	struct iovec iov[2];
776
	struct socket *so;
777

  
778
    if (!link_up)
779
        return 0;
780

  
781
	so = slirp_find_ctl_socket(addr_low_byte, guest_port);
782

  
783
	if (!so || so->so_state & SS_NOFDREF)
784
		return 0;
785

  
786
	if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2))
787
		return 0;
788

  
789
	return sopreprbuf(so, iov, NULL);
790
}
791

  
792
void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf,
793
        int size)
794
{
795
    int ret;
796
    struct socket *so = slirp_find_ctl_socket(addr_low_byte, guest_port);
797
   
798
    if (!so)
799
        return;
800

  
801
    ret = soreadbuf(so, buf, size);
802

  
803
    if (ret > 0)
804
        tcp_output(sototcpcb(so));
805
}
b/slirp/socket.c
5 5
 * terms and conditions of the copyright.
6 6
 */
7 7

  
8
#include "qemu-common.h"
8 9
#define WANT_SYS_IOCTL_H
9 10
#include <slirp.h>
10 11
#include "ip_icmp.h"
11 12
#ifdef __sun__
12 13
#include <sys/filio.h>
13 14
#endif
14
#include "qemu-common.h"
15 15

  
16 16
static void sofcantrcvmore(struct socket *so);
17 17
static void sofcantsendmore(struct socket *so);
......
91 91
  free(so);
92 92
}
93 93

  
94
/*
95
 * Read from so's socket into sb_snd, updating all relevant sbuf fields
96
 * NOTE: This will only be called if it is select()ed for reading, so
97
 * a read() of 0 (or less) means it's disconnected
98
 */
99
int
100
soread(so)
101
	struct socket *so;
94
size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np)
102 95
{
103
	int n, nn, lss, total;
96
	int n, lss, total;
104 97
	struct sbuf *sb = &so->so_snd;
105 98
	int len = sb->sb_datalen - sb->sb_cc;
106
	struct iovec iov[2];
107 99
	int mss = so->so_tcpcb->t_maxseg;
108 100

  
109
	DEBUG_CALL("soread");
101
	DEBUG_CALL("sopreprbuf");
110 102
	DEBUG_ARG("so = %lx", (long )so);
111 103

  
112
	/*
113
	 * No need to check if there's enough room to read.
114
	 * soread wouldn't have been called if there weren't
115
	 */
116

  
117 104
	len = sb->sb_datalen - sb->sb_cc;
118 105

  
106
	if (len <= 0)
107
		return 0;
108

  
119 109
	iov[0].iov_base = sb->sb_wptr;
120 110
        iov[1].iov_base = NULL;
121 111
        iov[1].iov_len = 0;
......
156 146
			n = 1;
157 147
		}
158 148
	}
149
	if (np)
150
		*np = n;
151

  
152
	return iov[0].iov_len + (n - 1) * iov[1].iov_len;
153
}
154

  
155
/*
156
 * Read from so's socket into sb_snd, updating all relevant sbuf fields
157
 * NOTE: This will only be called if it is select()ed for reading, so
158
 * a read() of 0 (or less) means it's disconnected
159
 */
160
int
161
soread(so)
162
	struct socket *so;
163
{
164
	int n, nn;
165
	struct sbuf *sb = &so->so_snd;
166
	struct iovec iov[2];
167

  
168
	DEBUG_CALL("soread");
169
	DEBUG_ARG("so = %lx", (long )so);
170

  
171
	/*
172
	 * No need to check if there's enough room to read.
173
	 * soread wouldn't have been called if there weren't
174
	 */
175
	sopreprbuf(so, iov, &n);
159 176

  
160 177
#ifdef HAVE_READV
161 178
	nn = readv(so->s, (struct iovec *)iov, n);
......
202 219
	return nn;
203 220
}
204 221

  
222
int soreadbuf(struct socket *so, const char *buf, int size)
223
{
224
    int n, nn, copy = size;
225
	struct sbuf *sb = &so->so_snd;
226
	struct iovec iov[2];
227

  
228
	DEBUG_CALL("soreadbuf");
229
	DEBUG_ARG("so = %lx", (long )so);
230

  
231
	/*
232
	 * No need to check if there's enough room to read.
233
	 * soread wouldn't have been called if there weren't
234
	 */
235
	if (sopreprbuf(so, iov, &n) < size)
236
        goto err;
237

  
238
    nn = MIN(iov[0].iov_len, copy);
239
    memcpy(iov[0].iov_base, buf, nn);
240

  
241
    copy -= nn;
242
    buf += nn;
243

  
244
    if (copy == 0)
245
        goto done;
246

  
247
    memcpy(iov[1].iov_base, buf, copy);
248

  
249
done:
250
    /* Update fields */
251
	sb->sb_cc += size;
252
	sb->sb_wptr += size;
253
	if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
254
		sb->sb_wptr -= sb->sb_datalen;
255
    return size;
256
err:
257

  
258
    sofcantrcvmore(so);
259
    tcp_sockclosed(sototcpcb(so));
260
    fprintf(stderr, "soreadbuf buffer to small");
261
    return -1;
262
}
263

  
205 264
/*
206 265
 * Get urgent data
207 266
 *
......
255 314

  
256 315
	if (sb->sb_rptr < sb->sb_wptr) {
257 316
		/* We can send it directly */
258
		n = send(so->s, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
317
		n = slirp_send(so, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
259 318
		so->so_urgc -= n;
260 319

  
261 320
		DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
......
276 335
			so->so_urgc -= n;
277 336
			len += n;
278 337
		}
279
		n = send(so->s, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
338
		n = slirp_send(so, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
280 339
#ifdef DEBUG
281 340
		if (n != len)
282 341
		   DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
......
348 407

  
349 408
	DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
350 409
#else
351
	nn = send(so->s, iov[0].iov_base, iov[0].iov_len,0);
410
	nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len,0);
352 411
#endif
353 412
	/* This should never happen, but people tell me it does *shrug* */
354 413
	if (nn < 0 && (errno == EAGAIN || errno == EINTR))
......
365 424
#ifndef HAVE_READV
366 425
	if (n == 2 && nn == iov[0].iov_len) {
367 426
            int ret;
368
            ret = send(so->s, iov[1].iov_base, iov[1].iov_len,0);
427
            ret = slirp_send(so, iov[1].iov_base, iov[1].iov_len,0);
369 428
            if (ret > 0)
370 429
                nn += ret;
371 430
        }
b/slirp/socket.h
87 87
void soisfconnected _P((register struct socket *));
88 88
void soisfdisconnected _P((struct socket *));
89 89
void sofwdrain _P((struct socket *));
90
size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np);
91
int soreadbuf(struct socket *so, const char *buf, int size);
90 92

  
91 93
#endif /* _SOCKET_H_ */
b/slirp/tcp_subr.c
1281 1281
		for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
1282 1282
			if (ex_ptr->ex_fport == so->so_fport &&
1283 1283
			    command == ex_ptr->ex_addr) {
1284
				if (ex_ptr->ex_pty == 3) {
1285
					so->s = -1;
1286
					so->extra = ex_ptr->ex_exec;
1287
					return 1;
1288
				}
1284 1289
				do_pty = ex_ptr->ex_pty;
1285 1290
				goto do_exec;
1286 1291
			}

Also available in: Unified diff