/* Create a new socket of type TYPE in domain DOMAIN, using protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically. Returns a file descriptor for the new socket, or -1 for errors. */ int __socket (int domain, int type, int protocol) { error_t err; socket_t sock, server; /* Find the socket server for DOMAIN. */ server = _hurd_socket_server (domain, 0); if (server == MACH_PORT_NULL) return -1; err = __socket_create (server, type, protocol, &sock); if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED || err == MIG_BAD_ID || err == EOPNOTSUPP) { /* On the first use of the socket server during the operation, allow for the old server port dying. */ server = _hurd_socket_server (domain, 1); if (server == MACH_PORT_NULL) return -1; err = __socket_create (server, type, protocol, &sock); } /* These errors all mean that the server node doesn't support the socket.defs protocol, which we'll take to mean that the protocol isn't supported. */ if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED || err == MIG_BAD_ID || err == EOPNOTSUPP) err = EAFNOSUPPORT; if (err) return __hurd_fail (err); return _hurd_intern_fd (sock, O_IGNORE_CTTY, 1); }
/* 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. */ int __socketpair (int domain, int type, int protocol, int fds[2]) { error_t err; socket_t server, sock1, sock2; int d1, d2; if (fds == NULL) return __hurd_fail (EINVAL); /* Find the domain's socket server. */ server = _hurd_socket_server (domain, 0); if (server == MACH_PORT_NULL) return -1; /* Create two sockets and connect them together. */ err = __socket_create (server, type, protocol, &sock1); if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED || err == MIG_BAD_ID || err == EOPNOTSUPP) { /* On the first use of the socket server during the operation, allow for the old server port dying. */ server = _hurd_socket_server (domain, 1); if (server == MACH_PORT_NULL) return -1; err = __socket_create (server, type, protocol, &sock1); } if (err) return __hurd_fail (err); if (err = __socket_create (server, type, protocol, &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); } /* 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; }