47 |
u16_t lastoffset; |
u16_t lastoffset; |
48 |
u16_t rcvevent; |
u16_t rcvevent; |
49 |
u16_t sendevent; |
u16_t sendevent; |
50 |
u16_t flags; |
u16_t flags; |
51 |
int err; |
int err; |
52 |
}; |
}; |
53 |
|
|
71 |
event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len); |
event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len); |
72 |
|
|
73 |
static int err_to_errno_table[11] = { |
static int err_to_errno_table[11] = { |
74 |
0, /* ERR_OK 0 No error, everything OK. */ |
0, /* ERR_OK 0 No error, everything OK. */ |
75 |
ENOMEM, /* ERR_MEM -1 Out of memory error. */ |
ENOMEM, /* ERR_MEM -1 Out of memory error. */ |
76 |
ENOBUFS, /* ERR_BUF -2 Buffer error. */ |
ENOBUFS, /* ERR_BUF -2 Buffer error. */ |
77 |
ECONNABORTED, /* ERR_ABRT -3 Connection aborted. */ |
ECONNABORTED, /* ERR_ABRT -3 Connection aborted. */ |
78 |
ECONNRESET, /* ERR_RST -4 Connection reset. */ |
ECONNRESET, /* ERR_RST -4 Connection reset. */ |
79 |
ESHUTDOWN, /* ERR_CLSD -5 Connection closed. */ |
ESHUTDOWN, /* ERR_CLSD -5 Connection closed. */ |
80 |
ENOTCONN, /* ERR_CONN -6 Not connected. */ |
ENOTCONN, /* ERR_CONN -6 Not connected. */ |
81 |
EINVAL, /* ERR_VAL -7 Illegal value. */ |
EINVAL, /* ERR_VAL -7 Illegal value. */ |
82 |
EIO, /* ERR_ARG -8 Illegal argument. */ |
EIO, /* ERR_ARG -8 Illegal argument. */ |
83 |
EHOSTUNREACH, /* ERR_RTE -9 Routing problem. */ |
EHOSTUNREACH, /* ERR_RTE -9 Routing problem. */ |
84 |
EADDRINUSE /* ERR_USE -10 Address in use. */ |
EADDRINUSE /* ERR_USE -10 Address in use. */ |
85 |
}; |
}; |
86 |
|
|
87 |
#define err_to_errno(err) \ |
#define err_to_errno(err) \ |
88 |
((err) < (sizeof(err_to_errno_table)/sizeof(int))) ? \ |
((err) < (sizeof(err_to_errno_table)/sizeof(int))) ? \ |
89 |
err_to_errno_table[-(err)] : EIO |
err_to_errno_table[-(err)] : EIO |
90 |
|
|
91 |
#ifdef ERRNO |
#ifdef ERRNO |
92 |
#define set_errno(err) errno = (err) |
#define set_errno(err) errno = (err) |
95 |
#endif |
#endif |
96 |
|
|
97 |
#define sock_set_errno(sk, e) do { \ |
#define sock_set_errno(sk, e) do { \ |
98 |
sk->err = (e); \ |
sk->err = (e); \ |
99 |
set_errno(sk->err); \ |
set_errno(sk->err); \ |
100 |
} while (0) |
} while (0) |
101 |
|
|
102 |
/*-----------------------------------------------------------------------------------*/ |
/*-----------------------------------------------------------------------------------*/ |
106 |
struct lwip_socket *sock; |
struct lwip_socket *sock; |
107 |
|
|
108 |
if ((s < 0) || (s > NUM_SOCKETS)) { |
if ((s < 0) || (s > NUM_SOCKETS)) { |
109 |
DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s)); |
DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s)); |
110 |
set_errno(EBADF); |
set_errno(EBADF); |
111 |
return NULL; |
return NULL; |
112 |
} |
} |
113 |
|
|
114 |
sock = &sockets[s]; |
sock = &sockets[s]; |
115 |
|
|
116 |
if (!sock->conn) { |
if (!sock->conn) { |
117 |
DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s)); |
DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s)); |
118 |
set_errno(EBADF); |
set_errno(EBADF); |
119 |
return NULL; |
return NULL; |
120 |
} |
} |
121 |
|
|
186 |
newsock = alloc_socket(newconn); |
newsock = alloc_socket(newconn); |
187 |
if (newsock == -1) { |
if (newsock == -1) { |
188 |
netconn_delete(newconn); |
netconn_delete(newconn); |
189 |
sock_set_errno(sock, ENOBUFS); |
sock_set_errno(sock, ENOBUFS); |
190 |
return -1; |
return -1; |
191 |
} |
} |
192 |
newconn->callback = event_callback; |
newconn->callback = event_callback; |
193 |
sock = get_socket(newsock); |
sock = get_socket(newsock); |
232 |
err = netconn_bind(sock->conn, &local_addr, ntohs(local_port)); |
err = netconn_bind(sock->conn, &local_addr, ntohs(local_port)); |
233 |
|
|
234 |
if (err != ERR_OK) { |
if (err != ERR_OK) { |
235 |
DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err)); |
236 |
sock_set_errno(sock, err_to_errno(err)); |
sock_set_errno(sock, err_to_errno(err)); |
237 |
return -1; |
return -1; |
238 |
} |
} |
239 |
|
|
284 |
} |
} |
285 |
|
|
286 |
if (((struct sockaddr_in *)name)->sin_family == AF_UNSPEC) { |
if (((struct sockaddr_in *)name)->sin_family == AF_UNSPEC) { |
287 |
DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); |
288 |
err = netconn_disconnect(sock->conn); |
err = netconn_disconnect(sock->conn); |
289 |
} else { |
} else { |
290 |
struct ip_addr remote_addr; |
struct ip_addr remote_addr; |
291 |
u16_t remote_port; |
u16_t remote_port; |
292 |
|
|
293 |
remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr; |
remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr; |
294 |
remote_port = ((struct sockaddr_in *)name)->sin_port; |
remote_port = ((struct sockaddr_in *)name)->sin_port; |
295 |
|
|
296 |
#if SOCKETS_DEBUG |
#if SOCKETS_DEBUG |
297 |
DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); |
298 |
ip_addr_debug_print(&remote_addr); |
ip_addr_debug_print(&remote_addr); |
299 |
DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(remote_port))); |
DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(remote_port))); |
300 |
#endif |
#endif |
301 |
|
|
302 |
err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port)); |
err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port)); |
303 |
} |
} |
304 |
|
|
305 |
if (err != ERR_OK) { |
if (err != ERR_OK) { |
306 |
DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err)); |
307 |
sock_set_errno(sock, err_to_errno(err)); |
sock_set_errno(sock, err_to_errno(err)); |
308 |
return -1; |
return -1; |
309 |
} |
} |
310 |
|
|
328 |
err = netconn_listen(sock->conn); |
err = netconn_listen(sock->conn); |
329 |
|
|
330 |
if (err != ERR_OK) { |
if (err != ERR_OK) { |
331 |
DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); |
332 |
sock_set_errno(sock, err_to_errno(err)); |
sock_set_errno(sock, err_to_errno(err)); |
333 |
return -1; |
return -1; |
334 |
} |
} |
335 |
|
|
339 |
/*-----------------------------------------------------------------------------------*/ |
/*-----------------------------------------------------------------------------------*/ |
340 |
int |
int |
341 |
lwip_recvfrom(int s, void *mem, int len, unsigned int flags, |
lwip_recvfrom(int s, void *mem, int len, unsigned int flags, |
342 |
struct sockaddr *from, socklen_t *fromlen) |
struct sockaddr *from, socklen_t *fromlen) |
343 |
{ |
{ |
344 |
struct lwip_socket *sock; |
struct lwip_socket *sock; |
345 |
struct netbuf *buf; |
struct netbuf *buf; |
360 |
} else { |
} else { |
361 |
/* If this is non-blocking call, then check first */ |
/* If this is non-blocking call, then check first */ |
362 |
if (((flags & MSG_DONTWAIT) || (sock->flags & O_NONBLOCK)) |
if (((flags & MSG_DONTWAIT) || (sock->flags & O_NONBLOCK)) |
363 |
&& !sock->rcvevent) |
&& !sock->rcvevent) |
364 |
{ |
{ |
365 |
DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s)); |
366 |
sock_set_errno(sock, EWOULDBLOCK); |
sock_set_errno(sock, EWOULDBLOCK); |
477 |
buf = netbuf_new(); |
buf = netbuf_new(); |
478 |
|
|
479 |
if (!buf) { |
if (!buf) { |
480 |
DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ENOBUFS\n", s)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ENOBUFS\n", s)); |
481 |
sock_set_errno(sock, ENOBUFS); |
sock_set_errno(sock, ENOBUFS); |
482 |
return -1; |
return -1; |
483 |
} |
} |
484 |
|
|
500 |
break; |
break; |
501 |
} |
} |
502 |
if (err != ERR_OK) { |
if (err != ERR_OK) { |
503 |
DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d\n", s, err)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d\n", s, err)); |
504 |
sock_set_errno(sock, err_to_errno(err)); |
sock_set_errno(sock, err_to_errno(err)); |
505 |
return -1; |
return -1; |
506 |
} |
} |
507 |
|
|
543 |
/* reset the remote address and port number |
/* reset the remote address and port number |
544 |
of the connection */ |
of the connection */ |
545 |
if (connected) |
if (connected) |
546 |
netconn_connect(sock->conn, &addr, port); |
netconn_connect(sock->conn, &addr, port); |
547 |
else |
else |
548 |
netconn_disconnect(sock->conn); |
netconn_disconnect(sock->conn); |
549 |
return ret; |
return ret; |
550 |
} |
} |
551 |
/*-----------------------------------------------------------------------------------*/ |
/*-----------------------------------------------------------------------------------*/ |
559 |
switch (type) { |
switch (type) { |
560 |
case SOCK_DGRAM: |
case SOCK_DGRAM: |
561 |
conn = netconn_new_with_callback(NETCONN_UDP, event_callback); |
conn = netconn_new_with_callback(NETCONN_UDP, event_callback); |
562 |
DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); |
563 |
break; |
break; |
564 |
case SOCK_STREAM: |
case SOCK_STREAM: |
565 |
conn = netconn_new_with_callback(NETCONN_TCP, event_callback); |
conn = netconn_new_with_callback(NETCONN_TCP, event_callback); |
566 |
DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); |
567 |
break; |
break; |
568 |
default: |
default: |
569 |
DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", domain, type, protocol)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", domain, type, protocol)); |
570 |
set_errno(EINVAL); |
set_errno(EINVAL); |
571 |
return -1; |
return -1; |
572 |
} |
} |
573 |
|
|
574 |
if (!conn) { |
if (!conn) { |
575 |
DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n")); |
DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n")); |
576 |
set_errno(ENOBUFS); |
set_errno(ENOBUFS); |
577 |
return -1; |
return -1; |
578 |
} |
} |
579 |
|
|
581 |
|
|
582 |
if (i == -1) { |
if (i == -1) { |
583 |
netconn_delete(conn); |
netconn_delete(conn); |
584 |
set_errno(ENOBUFS); |
set_errno(ENOBUFS); |
585 |
return -1; |
return -1; |
586 |
} |
} |
587 |
conn->socket = i; |
conn->socket = i; |
588 |
DEBUGF(SOCKETS_DEBUG, ("%d\n", i)); |
DEBUGF(SOCKETS_DEBUG, ("%d\n", i)); |
619 |
if (p_sock && (p_sock->lastdata || p_sock->rcvevent)) |
if (p_sock && (p_sock->lastdata || p_sock->rcvevent)) |
620 |
{ |
{ |
621 |
FD_SET(i, &lreadset); |
FD_SET(i, &lreadset); |
622 |
DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i)); |
623 |
nready++; |
nready++; |
624 |
} |
} |
625 |
} |
} |
630 |
if (p_sock && p_sock->sendevent) |
if (p_sock && p_sock->sendevent) |
631 |
{ |
{ |
632 |
FD_SET(i, &lwriteset); |
FD_SET(i, &lwriteset); |
633 |
DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i)); |
634 |
nready++; |
nready++; |
635 |
} |
} |
636 |
} |
} |
655 |
struct lwip_select_cb select_cb; |
struct lwip_select_cb select_cb; |
656 |
struct lwip_select_cb *p_selcb; |
struct lwip_select_cb *p_selcb; |
657 |
|
|
658 |
DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%ld tvusec=%ld)\n", maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, timeout ? timeout->tv_sec : -1L, timeout ? timeout->tv_usec : -1L)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%ld tvusec=%ld)\n", maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, timeout ? timeout->tv_sec : -1L, timeout ? timeout->tv_usec : -1L)); |
659 |
select_cb.next = 0; |
select_cb.next = 0; |
660 |
select_cb.readset = readset; |
select_cb.readset = readset; |
661 |
select_cb.writeset = writeset; |
select_cb.writeset = writeset; |
697 |
if (exceptset) |
if (exceptset) |
698 |
FD_ZERO(exceptset); |
FD_ZERO(exceptset); |
699 |
|
|
700 |
DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n")); |
DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n")); |
701 |
set_errno(0); |
set_errno(0); |
702 |
return 0; |
return 0; |
703 |
} |
} |
704 |
|
|
748 |
FD_ZERO(writeset); |
FD_ZERO(writeset); |
749 |
if (exceptset) |
if (exceptset) |
750 |
FD_ZERO(exceptset); |
FD_ZERO(exceptset); |
751 |
DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n")); |
DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n")); |
752 |
set_errno(0); |
set_errno(0); |
753 |
return 0; |
return 0; |
754 |
} |
} |
755 |
|
|
778 |
*writeset = lwriteset; |
*writeset = lwriteset; |
779 |
if (exceptset) |
if (exceptset) |
780 |
*exceptset = lexceptset; |
*exceptset = lexceptset; |
781 |
DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); |
782 |
set_errno(0); |
set_errno(0); |
783 |
return nready; |
return nready; |
784 |
} |
} |
785 |
|
|
877 |
|
|
878 |
int lwip_shutdown(int s, int how) |
int lwip_shutdown(int s, int how) |
879 |
{ |
{ |
880 |
DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how)); |
881 |
return lwip_close(s); /* XXX temporary hack until proper implementation */ |
return lwip_close(s); /* XXX temporary hack until proper implementation */ |
882 |
} |
} |
883 |
|
|
953 |
|
|
954 |
int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen) |
int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen) |
955 |
{ |
{ |
956 |
int err = ENOSYS; |
int err = ENOSYS; |
957 |
struct lwip_socket *sock = get_socket(s); |
struct lwip_socket *sock = get_socket(s); |
958 |
|
|
959 |
|
if (!sock) { |
960 |
|
return -1; |
961 |
|
} |
962 |
|
|
963 |
if (!sock) { |
if (level == SOL_SOCKET) { |
964 |
return -1; |
switch (optname) { |
965 |
} |
case SO_ERROR: |
966 |
|
if (!optval || !optlen || (*optlen != sizeof(int))) { |
967 |
if (level == SOL_SOCKET) { |
err = EINVAL; |
968 |
switch (optname) { |
break; |
969 |
case SO_ERROR: |
} |
970 |
if (!optval || !optlen || (*optlen != sizeof(int))) { |
*(int *)optval = sock->err; |
971 |
err = EINVAL; |
sock->err = 0; |
972 |
break; |
DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", s, *(int *)optval)); |
973 |
} |
err = 0; |
974 |
*(int *)optval = sock->err; |
break; |
975 |
sock->err = 0; |
default: |
976 |
DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", s, *(int *)optval)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname)); |
977 |
err = 0; |
break; |
978 |
break; |
} |
979 |
default: |
} else { |
980 |
DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname)); |
981 |
break; |
} |
982 |
} |
sock_set_errno(sock, err); |
983 |
} else { |
return err ? -1 : 0; |
|
DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname)); |
|
|
} |
|
|
sock_set_errno(sock, err); |
|
|
return err ? -1 : 0; |
|
984 |
} |
} |
985 |
|
|
986 |
int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen) |
int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen) |
987 |
{ |
{ |
988 |
struct lwip_socket *sock = get_socket(s); |
struct lwip_socket *sock = get_socket(s); |
989 |
int err = ENOSYS; |
int err = ENOSYS; |
990 |
|
|
991 |
if (!sock) { |
if (!sock) { |
992 |
return -1; |
return -1; |
993 |
} |
} |
|
|
|
|
if (level == SOL_SOCKET) { |
|
|
switch (optname) { |
|
|
case SO_REUSEADDR: |
|
|
DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, SO_REUSEADDR, ..)\n", s)); |
|
|
/* XXX just pretend we support this for now */ |
|
|
err = 0; |
|
|
break; |
|
|
default: |
|
|
DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname)); |
|
|
break; |
|
|
} |
|
|
} else { |
|
|
DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname)); |
|
|
} |
|
994 |
|
|
995 |
sock_set_errno(sock, err); |
if (level == SOL_SOCKET) { |
996 |
return err ? -1 : 0; |
switch (optname) { |
997 |
|
case SO_REUSEADDR: |
998 |
|
DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, SO_REUSEADDR, ..)\n", s)); |
999 |
|
/* XXX just pretend we support this for now */ |
1000 |
|
err = 0; |
1001 |
|
break; |
1002 |
|
default: |
1003 |
|
DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname)); |
1004 |
|
break; |
1005 |
|
} |
1006 |
|
} else { |
1007 |
|
DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname)); |
1008 |
|
} |
1009 |
|
|
1010 |
|
sock_set_errno(sock, err); |
1011 |
|
return err ? -1 : 0; |
1012 |
} |
} |
1013 |
|
|
1014 |
int lwip_ioctl(int s, long cmd, void *argp) |
int lwip_ioctl(int s, long cmd, void *argp) |
1015 |
{ |
{ |
1016 |
struct lwip_socket *sock = get_socket(s); |
struct lwip_socket *sock = get_socket(s); |
1017 |
|
|
1018 |
|
if (!sock) { |
1019 |
|
return -1; |
1020 |
|
} |
1021 |
|
|
1022 |
|
switch (cmd) { |
1023 |
|
case FIONREAD: |
1024 |
|
if (!argp) { |
1025 |
|
sock_set_errno(sock, EINVAL); |
1026 |
|
return -1; |
1027 |
|
} |
1028 |
|
|
1029 |
if (!sock) { |
*((u16_t*)argp) = sock->conn->recv_avail; |
1030 |
return -1; |
|
1031 |
} |
DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %u\n", s, argp, *((u16_t*)argp))); |
1032 |
|
sock_set_errno(sock, 0); |
1033 |
switch (cmd) { |
return 0; |
1034 |
case FIONREAD: |
|
1035 |
if (!argp) { |
case FIONBIO: |
1036 |
sock_set_errno(sock, EINVAL); |
if (argp && *(u32_t*)argp) |
1037 |
return -1; |
sock->flags |= O_NONBLOCK; |
1038 |
} |
else |
1039 |
|
sock->flags &= ~O_NONBLOCK; |
1040 |
*((u16_t*)argp) = sock->conn->recv_avail; |
DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, !!(sock->flags & O_NONBLOCK))); |
1041 |
|
sock_set_errno(sock, 0); |
1042 |
DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %u\n", s, argp, *((u16_t*)argp))); |
return 0; |
1043 |
sock_set_errno(sock, 0); |
|
1044 |
return 0; |
default: |
1045 |
|
DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp)); |
1046 |
case FIONBIO: |
sock_set_errno(sock, ENOSYS); /* not yet implemented */ |
1047 |
if (argp && *(u32_t*)argp) |
return -1; |
1048 |
sock->flags |= O_NONBLOCK; |
} |
|
else |
|
|
sock->flags &= ~O_NONBLOCK; |
|
|
DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, !!(sock->flags & O_NONBLOCK))); |
|
|
sock_set_errno(sock, 0); |
|
|
return 0; |
|
|
|
|
|
default: |
|
|
DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp)); |
|
|
sock_set_errno(sock, ENOSYS); /* not yet implemented */ |
|
|
return -1; |
|
|
} |
|
1049 |
} |
} |
1050 |
|
|