diff --git a/ChangeLog b/ChangeLog index 7d8343fcd8..7848dfcbe0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2000-08-02 Mark Kettenis + + * sysdeps/mach/hurd/socketpair.c (__socketpair): Renamed from + socketpair. Made socketpair a weak alias. + * sysdeps/mach/hurd/pipe.c (__pipe): Reimplemented using + __socketpair. Use S_IFIFO protocol to make pipes POSIX + conforming, but fall back on the old protocol if the socket server + doesn't support it. + * include/sys/socket.h: Add prototype for __socketpair. + 2000-08-09 Andreas Schwab * stdio-common/vfprintf.c (vfprintf): Also set `is_long' if the diff --git a/include/sys/socket.h b/include/sys/socket.h index 2e91fb3e0a..576c5934bb 100644 --- a/include/sys/socket.h +++ b/include/sys/socket.h @@ -4,6 +4,13 @@ /* Now define the internal interfaces. */ extern int __socket (int __domain, int __type, int __protocol); +/* Create two new sockets, of type TYPE in domain DOMAIN and using + protocol PROTOCOL, which are connected to each other, and put file + descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero, + one will be chosen automatically. Returns 0 on success, -1 for errors. */ +extern int __socketpair (int __domain, int __type, int __protocol, + int __fds[2]); + /* Return a socket of any type. The socket can be used in subsequent ioctl calls to talk to the kernel. */ extern int __opensock (void) internal_function; diff --git a/sysdeps/mach/hurd/pipe.c b/sysdeps/mach/hurd/pipe.c index 9d62c8ca28..717fb005aa 100644 --- a/sysdeps/mach/hurd/pipe.c +++ b/sysdeps/mach/hurd/pipe.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1992, 93, 94, 95, 96, 99 Free Software Foundation, Inc. +/* Copyright (C) 1992, 93, 94, 95, 96, 99, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,80 +17,34 @@ Boston, MA 02111-1307, USA. */ #include -#include -#include -#include -#include #include -#include -#include +#include /* Create a one-way communication channel (pipe). + Actually the channel is two-way on the Hurd. If successful, two file descriptors are stored in FDS; bytes written on FDS[1] can be read from FDS[0]. Returns 0 if successful, -1 if not. */ int -__pipe (fds) - int fds[2]; +__pipe (int fds[2]) { - error_t err; - socket_t server, sock1, sock2; - int d1, d2; + int save_errno = errno; + int result; - if (fds == NULL) - return __hurd_fail (EINVAL); - - /* Find the local domain socket server. */ - server = _hurd_socket_server (PF_LOCAL, 0); - if (server == MACH_PORT_NULL) - return -1; - - /* Create two local domain sockets and connect them together. */ - - err = __socket_create (server, SOCK_STREAM, 0, &sock1); - if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED - || err == MIG_BAD_ID || err == EOPNOTSUPP) + /* The magic S_IFIFO protocol tells the pflocal server to create + sockets which report themselves as FIFOs, as POSIX requires for + pipes. */ + result = __socketpair (PF_LOCAL, SOCK_STREAM, S_IFIFO, fds); + if (result == -1 && errno == EPROTONOSUPPORT) { - /* On the first use of the socket server during the operation, - allow for the old server port dying. */ - server = _hurd_socket_server (PF_LOCAL, 1); - if (server == MACH_PORT_NULL) - return -1; - err = __socket_create (server, SOCK_STREAM, 0, &sock1); - } - if (err) - return __hurd_fail (err); - if (err = __socket_create (server, SOCK_STREAM, 0, &sock2)) - { - __mach_port_deallocate (__mach_task_self (), sock1); - return __hurd_fail (err); - } - if (err = __socket_connect2 (sock1, sock2)) - { - __mach_port_deallocate (__mach_task_self (), sock1); - __mach_port_deallocate (__mach_task_self (), sock2); - return __hurd_fail (err); + /* We contacted an "old" pflocal server that doesn't support the + magic S_IFIFO protocol. + FIXME: Remove this junk somewhere in the future. */ + __set_errno (save_errno); + return __socketpair (PF_LOCAL, SOCK_STREAM, 0, fds); } - /* Put the sockets into file descriptors. */ - - d1 = _hurd_intern_fd (sock1, O_IGNORE_CTTY, 1); - if (d1 < 0) - { - __mach_port_deallocate (__mach_task_self (), sock2); - return -1; - } - d2 = _hurd_intern_fd (sock2, O_IGNORE_CTTY, 1); - if (d2 < 0) - { - err = errno; - (void) close (d1); - return __hurd_fail (err); - } - - fds[0] = d1; - fds[1] = d2; - return 0; + return result; } weak_alias (__pipe, pipe) diff --git a/sysdeps/mach/hurd/socketpair.c b/sysdeps/mach/hurd/socketpair.c index fa9837dfd2..c1fb227596 100644 --- a/sysdeps/mach/hurd/socketpair.c +++ b/sysdeps/mach/hurd/socketpair.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1992, 1994, 1995, 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1992, 94, 95, 96, 97, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,24 +17,20 @@ Boston, MA 02111-1307, USA. */ #include -#include -#include -#include -#include -#include #include +#include +#include + +#include +#include +#include /* Create two new sockets, of type TYPE in domain DOMAIN and using protocol PROTOCOL, which are connected to each other, and put file descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero, one will be chosen automatically. Returns 0 on success, -1 for errors. */ -/* XXX should be __socketpair ? */ int -socketpair (domain, type, protocol, fds) - int domain; - int type; - int protocol; - int fds[2]; +__socketpair (int domain, int type, int protocol, int fds[2]) { error_t err; socket_t server, sock1, sock2; @@ -95,3 +91,5 @@ socketpair (domain, type, protocol, fds) fds[1] = d2; return 0; } + +weak_alias (__socketpair, socketpair)