Rollback to NET_STACK_GET_COOKIE trick for accept() implementation.

Use the stack_driver_args union even more...


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3927 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Philippe Houdoin
2003-07-10 01:08:49 +00:00
parent 2a1f1e5a23
commit c692649c22
2 changed files with 82 additions and 62 deletions
+8 -8
View File
@@ -31,7 +31,7 @@ _EXPORT int select(int nbits, struct fd_set * rbits,
{ {
int fd; int fd;
int n; int n;
struct select_args args; struct stack_driver_args args;
status_t status; status_t status;
area_id area; area_id area;
struct r5_selectsync * rss; struct r5_selectsync * rss;
@@ -74,7 +74,7 @@ _EXPORT int select(int nbits, struct fd_set * rbits,
/* Beware, ugly hacky hack: we pass the area_id of our shared r5_selectsync, /* Beware, ugly hacky hack: we pass the area_id of our shared r5_selectsync,
that net_stack_driver should udate directly that net_stack_driver should udate directly
*/ */
args.sync = (struct selectsync *) area; args.u.select.sync = (struct selectsync *) area;
/* call, indirectly, net_stack_select() for each event to monitor /* call, indirectly, net_stack_select() for each event to monitor
* as we are not the vfs, we can't call this device hook ourself, but * as we are not the vfs, we can't call this device hook ourself, but
@@ -83,17 +83,17 @@ _EXPORT int select(int nbits, struct fd_set * rbits,
n = 0; n = 0;
for (fd = 0; fd < nbits; fd++) { for (fd = 0; fd < nbits; fd++) {
if (rbits && FD_ISSET(fd, rbits)) { if (rbits && FD_ISSET(fd, rbits)) {
args.ref = (fd << 8) | 1; args.u.select.ref = (fd << 8) | 1;
if (ioctl(fd, NET_STACK_SELECT, &args, sizeof(args)) >= 0) if (ioctl(fd, NET_STACK_SELECT, &args, sizeof(args)) >= 0)
n++; n++;
}; };
if (wbits && FD_ISSET(fd, wbits)) { if (wbits && FD_ISSET(fd, wbits)) {
args.ref = (fd << 8) | 2; args.u.select.ref = (fd << 8) | 2;
if (ioctl(fd, NET_STACK_SELECT, &args, sizeof(args)) >= 0) if (ioctl(fd, NET_STACK_SELECT, &args, sizeof(args)) >= 0)
n++; n++;
}; };
if (ebits && FD_ISSET(fd, ebits)) { if (ebits && FD_ISSET(fd, ebits)) {
args.ref = (fd << 8) | 3; args.u.select.ref = (fd << 8) | 3;
if (ioctl(fd, NET_STACK_SELECT, &args, sizeof(args)) >= 0) if (ioctl(fd, NET_STACK_SELECT, &args, sizeof(args)) >= 0)
n++; n++;
}; };
@@ -126,15 +126,15 @@ _EXPORT int select(int nbits, struct fd_set * rbits,
// unregister socket event notification // unregister socket event notification
for(fd = 0; fd < nbits; fd++) { for(fd = 0; fd < nbits; fd++) {
if (rbits && FD_ISSET(fd, rbits)) { if (rbits && FD_ISSET(fd, rbits)) {
args.ref = (fd << 8) | 1; args.u.select.ref = (fd << 8) | 1;
ioctl(fd, NET_STACK_DESELECT, &args, sizeof(args)); ioctl(fd, NET_STACK_DESELECT, &args, sizeof(args));
}; };
if (wbits && FD_ISSET(fd, wbits)) { if (wbits && FD_ISSET(fd, wbits)) {
args.ref = (fd << 8) | 2; args.u.select.ref = (fd << 8) | 2;
ioctl(fd, NET_STACK_DESELECT, &args, sizeof(args)); ioctl(fd, NET_STACK_DESELECT, &args, sizeof(args));
}; };
if (ebits && FD_ISSET(fd, ebits)) { if (ebits && FD_ISSET(fd, ebits)) {
args.ref = (fd << 8) | 3; args.u.select.ref = (fd << 8) | 3;
ioctl(fd, NET_STACK_DESELECT, &args, sizeof(args)); ioctl(fd, NET_STACK_DESELECT, &args, sizeof(args));
}; };
}; };
+74 -54
View File
@@ -35,7 +35,7 @@ _EXPORT int socket(int family, int type, int protocol)
{ {
int sock; int sock;
int rv; int rv;
struct socket_args args; struct stack_driver_args args;
sock = open(get_stack_driver_path(), O_RDWR); sock = open(get_stack_driver_path(), O_RDWR);
if (sock < 0) if (sock < 0)
@@ -75,9 +75,9 @@ _EXPORT int socket(int family, int type, int protocol)
family = AF_INET; family = AF_INET;
}; };
args.family = family; args.u.socket.family = family;
args.type = type; args.u.socket.type = type;
args.proto = protocol; args.u.socket.proto = protocol;
rv = ioctl(sock, NET_STACK_SOCKET, &args, sizeof(args)); rv = ioctl(sock, NET_STACK_SOCKET, &args, sizeof(args));
if (rv < 0) { if (rv < 0) {
@@ -92,7 +92,7 @@ _EXPORT int socket(int family, int type, int protocol)
_EXPORT int bind(int sock, const struct sockaddr *addr, int addrlen) _EXPORT int bind(int sock, const struct sockaddr *addr, int addrlen)
{ {
struct sockaddr temp; struct sockaddr temp;
struct sockaddr_args args; struct stack_driver_args args;
if (g_beos_r5_compatibility) { if (g_beos_r5_compatibility) {
convert_from_beos_r5_sockaddr(&temp, addr); convert_from_beos_r5_sockaddr(&temp, addr);
@@ -100,8 +100,8 @@ _EXPORT int bind(int sock, const struct sockaddr *addr, int addrlen)
addrlen = sizeof(struct sockaddr_in); addrlen = sizeof(struct sockaddr_in);
} }
args.addr = (struct sockaddr *) addr; args.u.sockaddr.addr = (struct sockaddr *) addr;
args.addrlen = addrlen; args.u.sockaddr.addrlen = addrlen;
return ioctl(sock, NET_STACK_BIND, &args, sizeof(args)); return ioctl(sock, NET_STACK_BIND, &args, sizeof(args));
} }
@@ -109,9 +109,9 @@ _EXPORT int bind(int sock, const struct sockaddr *addr, int addrlen)
_EXPORT int shutdown(int sock, int how) _EXPORT int shutdown(int sock, int how)
{ {
struct int_args args; struct stack_driver_args args;
args.value = how; args.u.integer = how;
return ioctl(sock, NET_STACK_SHUTDOWN, &args, sizeof(args)); return ioctl(sock, NET_STACK_SHUTDOWN, &args, sizeof(args));
} }
@@ -120,7 +120,7 @@ _EXPORT int shutdown(int sock, int how)
_EXPORT int connect(int sock, const struct sockaddr *addr, int addrlen) _EXPORT int connect(int sock, const struct sockaddr *addr, int addrlen)
{ {
struct sockaddr temp; struct sockaddr temp;
struct sockaddr_args args; struct stack_driver_args args;
if (g_beos_r5_compatibility) { if (g_beos_r5_compatibility) {
convert_from_beos_r5_sockaddr(&temp, addr); convert_from_beos_r5_sockaddr(&temp, addr);
@@ -128,8 +128,8 @@ _EXPORT int connect(int sock, const struct sockaddr *addr, int addrlen)
addrlen = sizeof(struct sockaddr_in); addrlen = sizeof(struct sockaddr_in);
} }
args.addr = (struct sockaddr *) addr; args.u.sockaddr.addr = (struct sockaddr *) addr;
args.addrlen = addrlen; args.u.sockaddr.addrlen = addrlen;
return ioctl(sock, NET_STACK_CONNECT, &args, sizeof(args)); return ioctl(sock, NET_STACK_CONNECT, &args, sizeof(args));
} }
@@ -137,9 +137,9 @@ _EXPORT int connect(int sock, const struct sockaddr *addr, int addrlen)
_EXPORT int listen(int sock, int backlog) _EXPORT int listen(int sock, int backlog)
{ {
struct int_args args; struct stack_driver_args args;
args.value = backlog; args.u.integer = backlog;
return ioctl(sock, NET_STACK_LISTEN, &args, sizeof(args)); return ioctl(sock, NET_STACK_LISTEN, &args, sizeof(args));
} }
@@ -148,21 +148,41 @@ _EXPORT int listen(int sock, int backlog)
_EXPORT int accept(int sock, struct sockaddr *addr, int *addrlen) _EXPORT int accept(int sock, struct sockaddr *addr, int *addrlen)
{ {
struct sockaddr temp; struct sockaddr temp;
struct sockaddr_args args; struct stack_driver_args args;
int rv;
int new_sock; int new_sock;
void *cookie;
args.addr = g_beos_r5_compatibility ? &temp : addr;
args.addrlen = g_beos_r5_compatibility ? sizeof(temp) : *addrlen; new_sock = open(get_stack_driver_path(), O_RDWR);
new_sock = ioctl(sock, NET_STACK_ACCEPT, &args, sizeof(args));
if (new_sock < 0) if (new_sock < 0)
return new_sock; return new_sock;
// The network stack driver will need to know to which net_stack_cookie to
// *bind* with the new accepted socket. He can't know himself find out
// the net_stack_cookie of our new_sock file descriptor, the just open() one...
// So, here, we ask him the net_stack_cookie value for our fd... :-)
rv = ioctl(new_sock, NET_STACK_GET_COOKIE, &cookie);
if (rv < 0) {
close(new_sock);
return rv;
};
args.u.accept.cookie = cookie; // this way driver can use the right fd/cookie for the new_sock!
args.u.accept.addr = g_beos_r5_compatibility ? &temp : addr;
args.u.accept.addrlen = g_beos_r5_compatibility ? sizeof(temp) : *addrlen;
rv = ioctl(sock, NET_STACK_ACCEPT, &args, sizeof(args));
if (rv < 0) {
close(new_sock);
return rv;
};
if (g_beos_r5_compatibility) { if (g_beos_r5_compatibility) {
convert_to_beos_r5_sockaddr(addr, &temp); convert_to_beos_r5_sockaddr(addr, &temp);
*addrlen = sizeof(struct beosr5_sockaddr_in); *addrlen = sizeof(struct beosr5_sockaddr_in);
} else } else
*addrlen = args.addrlen; *addrlen = args.u.accept.addrlen;
return new_sock; return new_sock;
} }
@@ -237,45 +257,45 @@ _EXPORT ssize_t sendto(int sock, const void *buffer, size_t buflen, int flags,
*/ */
_EXPORT ssize_t recv(int sock, void *data, size_t datalen, int flags) _EXPORT ssize_t recv(int sock, void *data, size_t datalen, int flags)
{ {
struct xfer_args args; struct stack_driver_args args;
int rv; int rv;
args.data = data; args.u.transfer.data = data;
args.datalen = datalen; args.u.transfer.datalen = datalen;
args.flags = flags; args.u.transfer.flags = flags;
args.addr = NULL; args.u.transfer.addr = NULL;
args.addrlen = 0; args.u.transfer.addrlen = 0;
rv = ioctl(sock, NET_STACK_RECV, &args, sizeof(args)); rv = ioctl(sock, NET_STACK_RECV, &args, sizeof(args));
if (rv < 0) if (rv < 0)
return rv; return rv;
return args.datalen; return args.u.transfer.datalen;
} }
_EXPORT ssize_t send(int sock, const void *data, size_t datalen, int flags) _EXPORT ssize_t send(int sock, const void *data, size_t datalen, int flags)
{ {
struct xfer_args args; struct stack_driver_args args;
int rv; int rv;
args.data = (void *) data; args.u.transfer.data = (void *) data;
args.datalen = datalen; args.u.transfer.datalen = datalen;
args.flags = flags; args.u.transfer.flags = flags;
args.addr = NULL; args.u.transfer.addr = NULL;
args.addrlen = 0; args.u.transfer.addrlen = 0;
rv = ioctl(sock, NET_STACK_SEND, &args, sizeof(args)); rv = ioctl(sock, NET_STACK_SEND, &args, sizeof(args));
if (rv < 0) if (rv < 0)
return rv; return rv;
return args.datalen; return args.u.transfer.datalen;
} }
_EXPORT int getsockopt(int sock, int level, int option, void *optval, size_t *optlen) _EXPORT int getsockopt(int sock, int level, int option, void *optval, size_t *optlen)
{ {
struct sockopt_args args; struct stack_driver_args args;
int rv; int rv;
if (g_beos_r5_compatibility && option == 5) { // BeOS R5 SO_FIONREAD if (g_beos_r5_compatibility && option == 5) { // BeOS R5 SO_FIONREAD
@@ -290,20 +310,20 @@ _EXPORT int getsockopt(int sock, int level, int option, void *optval, size_t *op
if (g_beos_r5_compatibility) if (g_beos_r5_compatibility)
convert_from_beos_r5_sockopt(&level, &option); convert_from_beos_r5_sockopt(&level, &option);
args.level = level; args.u.sockopt.level = level;
args.option = option; args.u.sockopt.option = option;
args.optval = optval; args.u.sockopt.optval = optval;
args.optlen = *optlen; args.u.sockopt.optlen = *optlen;
rv = ioctl(sock, NET_STACK_GETSOCKOPT, &args, sizeof(args)); rv = ioctl(sock, NET_STACK_GETSOCKOPT, &args, sizeof(args));
if (rv ==0) if (rv ==0)
*optlen = args.optlen; *optlen = args.u.sockopt.optlen;
return rv; return rv;
} }
_EXPORT int setsockopt(int sock, int level, int option, const void *optval, size_t optlen) _EXPORT int setsockopt(int sock, int level, int option, const void *optval, size_t optlen)
{ {
struct sockopt_args args; struct stack_driver_args args;
/* BeOS R5 uses /* BeOS R5 uses
* setsockopt(sock, SOL_SOCKET, SO_NONBLOCK, &i, sizeof(i)); * setsockopt(sock, SOL_SOCKET, SO_NONBLOCK, &i, sizeof(i));
@@ -317,10 +337,10 @@ _EXPORT int setsockopt(int sock, int level, int option, const void *optval, size
if (g_beos_r5_compatibility) if (g_beos_r5_compatibility)
convert_from_beos_r5_sockopt(&level, &option); convert_from_beos_r5_sockopt(&level, &option);
args.level = level; args.u.sockopt.level = level;
args.option = option; args.u.sockopt.option = option;
args.optval = (void *) optval; args.u.sockopt.optval = (void *) optval;
args.optlen = optlen; args.u.sockopt.optlen = optlen;
return ioctl(sock, NET_STACK_SETSOCKOPT, &args, sizeof(args)); return ioctl(sock, NET_STACK_SETSOCKOPT, &args, sizeof(args));
} }
@@ -328,11 +348,11 @@ _EXPORT int setsockopt(int sock, int level, int option, const void *optval, size
_EXPORT int getpeername(int sock, struct sockaddr *addr, int *addrlen) _EXPORT int getpeername(int sock, struct sockaddr *addr, int *addrlen)
{ {
struct sockaddr temp; struct sockaddr temp;
struct sockaddr_args args; struct stack_driver_args args;
int rv; int rv;
args.addr = g_beos_r5_compatibility ? &temp : addr; args.u.sockaddr.addr = g_beos_r5_compatibility ? &temp : addr;
args.addrlen = g_beos_r5_compatibility ? sizeof(temp) : *addrlen; args.u.sockaddr.addrlen = g_beos_r5_compatibility ? sizeof(temp) : *addrlen;
rv = ioctl(sock, NET_STACK_GETPEERNAME, &args, sizeof(args)); rv = ioctl(sock, NET_STACK_GETPEERNAME, &args, sizeof(args));
if (rv < 0) if (rv < 0)
@@ -342,7 +362,7 @@ _EXPORT int getpeername(int sock, struct sockaddr *addr, int *addrlen)
convert_to_beos_r5_sockaddr(addr, &temp); convert_to_beos_r5_sockaddr(addr, &temp);
*addrlen = sizeof(struct beosr5_sockaddr_in); *addrlen = sizeof(struct beosr5_sockaddr_in);
} else } else
*addrlen = args.addrlen; *addrlen = args.u.sockaddr.addrlen;
return rv; return rv;
} }
@@ -350,11 +370,11 @@ _EXPORT int getpeername(int sock, struct sockaddr *addr, int *addrlen)
_EXPORT int getsockname(int sock, struct sockaddr *addr, int *addrlen) _EXPORT int getsockname(int sock, struct sockaddr *addr, int *addrlen)
{ {
struct sockaddr temp; struct sockaddr temp;
struct sockaddr_args args; struct stack_driver_args args;
int rv; int rv;
args.addr = g_beos_r5_compatibility ? &temp : addr; args.u.sockaddr.addr = g_beos_r5_compatibility ? &temp : addr;
args.addrlen = g_beos_r5_compatibility ? sizeof(temp) : *addrlen; args.u.sockaddr.addrlen = g_beos_r5_compatibility ? sizeof(temp) : *addrlen;
rv = ioctl(sock, NET_STACK_GETSOCKNAME, &args, sizeof(args)); rv = ioctl(sock, NET_STACK_GETSOCKNAME, &args, sizeof(args));
if (rv < 0) if (rv < 0)
@@ -364,7 +384,7 @@ _EXPORT int getsockname(int sock, struct sockaddr *addr, int *addrlen)
convert_to_beos_r5_sockaddr(addr, &temp); convert_to_beos_r5_sockaddr(addr, &temp);
*addrlen = sizeof(struct beosr5_sockaddr_in); *addrlen = sizeof(struct beosr5_sockaddr_in);
} else } else
*addrlen = args.addrlen; *addrlen = args.u.sockaddr.addrlen;
return rv; return rv;
} }