bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

About SOCK_CLOEXEC, SOCK_NONBLOCK flags, accept4, etc.


From: Thomas Schwinge
Subject: About SOCK_CLOEXEC, SOCK_NONBLOCK flags, accept4, etc.
Date: Mon, 8 Dec 2008 15:33:10 +0100
User-agent: Mutt/1.5.11

Hello!

Further work on getting glibc HEAD going again.

I made some thouhts.  Please see through the following and tell me what's
right and what's wrong.  We yet need more implementations, but these are
a start.


diff --git a/sysdeps/unix/bsd/bsd4.4/bits/socket.h 
b/sysdeps/unix/bsd/bsd4.4/bits/socket.h
index 2ccd01d..9855130 100644
--- a/sysdeps/unix/bsd/bsd4.4/bits/socket.h
+++ b/sysdeps/unix/bsd/bsd4.4/bits/socket.h
@@ -54,6 +54,33 @@ enum __socket_type
   SOCK_SEQPACKET = 5           /* Sequenced, reliable, connection-based,
                                   datagrams of fixed maximum length.  */
 #define SOCK_SEQPACKET SOCK_SEQPACKET
+
+#ifdef NOTYET
+  /* TODO.  Define here our SOCK_CLOEXEC and SOCK_NONBLOCK to the same values
+     as O_CLOEXEC and O_NONBLOCK (that's what Linux does in
+     sysdeps/unix/sysv/linux/bits/socket.h).  These are just -- boiled down --
+     new socket-specific names for O_CLOEXEC, O_NONBLOCK AIUI.  */
+  /* TODO.  Before: check for conflicts.  */
+  /* TODO.  Instead of adding here rather clone this file into a hurd-specific
+     one, as this is the BSD4.4 one?  */
+  /* TODO.  O_NONBLOCK: Already defined and handled locally within pflocal.
+     Will have to change that (and align to glibc?).  */
+  /* These flags are used (in glibc) like this: ``socket (..., SOCK_CLOEXEC |
+     SOCK_NONBLOCK, ...)''  and ``accept4 (..., ..., ..., SOCK_CLOEXEC |
+     SOCK_NONBLOCK)''  */
+  /* Doc by Drepper: <http://udrepper.livejournal.com/20407.html>  */
+
+  /* TODO.  What about MSG_CMSG_CLOEXEC from
+     sysdeps/unix/sysv/linux/bits/socket.h?  Have not yet checked whether /
+     where this has to be implemented.  Used (in glibc) like this: ``recvmsg
+     (..., ..., MSG_CMSG_CLOEXEC)''  */
+#ifdef NOTYET
+     MSG_CMSG_CLOEXEC  = 0x40000000    /* Set close_on_exit for file
+                                           descriptor received through
+                                           SCM_RIGHTS.  */
+#define MSG_CMSG_CLOEXEC MSG_CMSG_CLOEXEC
+#endif /* NOTYET */
+#endif
 };
 
 /* Protocol families.  */
diff --git a/hurd/port2fd.c b/hurd/port2fd.c
index 262e6d9..390603a 100644
--- a/hurd/port2fd.c
+++ b/hurd/port2fd.c
@@ -55,6 +55,19 @@ _hurd_port2fd (struct hurd_fd *d, io_t dport, int flags)
     mach_port_t old
       = _hurd_userlink_clear (&d->port.users) ? d->port.port : MACH_PORT_NULL;
     d->port.port = dport;
+#ifdef NOTYET
+    /* Sanitize FLAGS.  The SOCK_* vs. O_* values should be the same ones, but
+       that isn't strictly needed.  */
+    /* TODO.  Where to put this?  Would be cumbersome to have to repeat this in
+       every socket-related file (accept.c, socket.c, ...), but here is also
+       not the right place, as this here isn't even aware about SOCK_*
+       flags.  */
+    /* TODO.  Also needed for SOCK_NONBLOCK?  Don't think so, as glibc isn't
+       interested (or is it?) in knowing whether a sockes is in non-blocking
+       mode or not.  */
+    if (SOCK_CLOEXEC != O_CLOEXEC && (flags & SOCK_CLOEXEC))
+      flags = (flags & ~SOCK_CLOEXEC) | O_CLOEXEC;
+#endif
     d->flags = (flags & O_CLOEXEC) ? FD_CLOEXEC : 0;
     if (old != MACH_PORT_NULL)
       __mach_port_deallocate (__mach_task_self (), old);
diff --git a/sysdeps/mach/hurd/accept.c b/sysdeps/mach/hurd/accept.c
index 362c42c..c38c22d 100644
--- a/sysdeps/mach/hurd/accept.c
+++ b/sysdeps/mach/hurd/accept.c
@@ -35,6 +35,24 @@ accept (fd, addrarg, addr_len)
       __SOCKADDR_ARG addrarg;
       socklen_t *addr_len;
 {
+  return accept4 (fd, addrarg, addr_len, 0);
+}
+libc_hidden_def (accept)
+
+/* TODO.  Rather put this into a new file accept4.c?  */
+/* Await a connection on socket FD.
+   When a connection arrives, open a new socket to communicate with it,
+   set *ADDRARG (which is *ADDR_LEN bytes long) to the address of the 
connecting
+   peer and *ADDR_LEN to the address's actual length, and return the
+   new socket's descriptor, or -1 for errors.  The operation can be influenced
+   by the FLAGS parameter.  */
+int
+accept4 (fd, addrarg, addr_len, flags)
+     int fd;
+     __SOCKADDR_ARG addrarg;
+     socklen_t *addr_len;
+     int flags;
+{
   error_t err;
   socket_t new;
   addr_port_t aport;
@@ -43,6 +61,10 @@ accept (fd, addrarg, addr_len)
   mach_msg_type_number_t buflen;
   int type;
 
+  /* TODO.  Have to pass the flags to __socket_accept -- means adding a new
+     socket RPC accept4 AIUI.  */
+  /* TODO.  pfinet / pflocal changes.  */
+
   if (err = HURD_DPORT_USE (fd, __socket_accept (port, &new, &aport)))
     return __hurd_dfail (fd, err);
 
@@ -82,6 +104,6 @@ accept (fd, addrarg, addr_len)
        addr->sa_family = type;
     }
 
-  return _hurd_intern_fd (new, O_IGNORE_CTTY, 1);
+  return _hurd_intern_fd (new, /* TODO flags | */ O_IGNORE_CTTY, 1);
 }
-libc_hidden_def (accept)
+libc_hidden_def (accept4)
diff --git a/sysdeps/mach/hurd/socket.c b/sysdeps/mach/hurd/socket.c
index a707ed9..55270da 100644
--- a/sysdeps/mach/hurd/socket.c
+++ b/sysdeps/mach/hurd/socket.c
@@ -34,6 +34,13 @@ __socket (domain, type, protocol)
 {
   error_t err;
   socket_t sock, server;
+#ifdef NOTYET
+  /* Could it do any harm to pass the flags through unfiltered?  */
+  int flags = type & ~TODO;
+  /* No, I think don't do the following -- the socket server also needs to know
+     about these flags.  */
+  /* type &= ~TODO; */
+#endif
 
   /* Find the socket server for DOMAIN.  */
   server = _hurd_socket_server (domain, 0);
@@ -62,7 +69,7 @@ __socket (domain, type, protocol)
   if (err)
     return __hurd_fail (err);
 
-  return _hurd_intern_fd (sock, O_IGNORE_CTTY, 1);
+  return _hurd_intern_fd (sock, /* TODO flags | */ O_IGNORE_CTTY, 1);
 }
 
 weak_alias (__socket, socket)
diff --git a/sysdeps/mach/hurd/socketpair.c b/sysdeps/mach/hurd/socketpair.c
index b124d20..ac6989b 100644
--- a/sysdeps/mach/hurd/socketpair.c
+++ b/sysdeps/mach/hurd/socketpair.c
@@ -35,6 +35,7 @@ __socketpair (int domain, int type, int protocol, int fds[2])
   error_t err;
   socket_t server, sock1, sock2;
   int d1, d2;
+  /* TODO.  Changes as in socket.c.  */
 
   if (fds == NULL)
     return __hurd_fail (EINVAL);
diff --git a/sysdeps/mach/hurd/kernel-features.h 
b/sysdeps/mach/hurd/kernel-features.h
index ad159aa..c641531 100644
--- a/sysdeps/mach/hurd/kernel-features.h
+++ b/sysdeps/mach/hurd/kernel-features.h
@@ -29,3 +29,8 @@
 #ifdef O_CLOEXEC
 # define __ASSUME_O_CLOEXEC    1
 #endif
+
+/* TODO.  Define __ASSUME_ACCEPT4 as soon as we have the new accept4 RPC.  */
+/* TODO.  __ASSUME_SOCK_CLOEXEC doesn't even have to wait so long, as it only
+   needs glibc support AIUI.  BUT: IIRC __ASSUME_SOCK_CLOEXEC also guards
+   SOCK_NONBLOCK use and this DOES need changes in the pf* servers.  */
diff --git a/socket/opensock.c b/socket/opensock.c
index 4a4d5dd..8fb8811 100644
--- a/socket/opensock.c
+++ b/socket/opensock.c
@@ -22,6 +22,7 @@
 
 /* Return a socket of any type.  The socket can be used in subsequent
    ioctl calls to talk to the kernel.  */
+/* TODO.  Also use SOCK_CLOEXEC like in sysdeps/unix/sysv/linux/opensock.c?  */
 int internal_function
 __opensock (void)
 {
diff --git a/include/sys/socket.h b/include/sys/socket.h
index df89278..09f56a6 100644
--- a/include/sys/socket.h
+++ b/include/sys/socket.h
@@ -158,6 +158,8 @@ extern int __have_sock_cloexec;
 /* At lot of other functionality became available at the same time as
    SOCK_CLOEXEC.  Avoid defining separate variables for all of them
    unless it is really necessary.  */
+/* TODO.  This is of course only true on Linux.  But we can simply ignore this
+   and implement all of these at the same time.  */
 # define __have_paccept __have_sock_cloexec
 #endif
 
diff --git a/include/unistd.h b/include/unistd.h
index 34d7477..123729b 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -170,6 +170,8 @@ extern int __have_sock_cloexec;
 /* At lot of other functionality became available at the same time as
    SOCK_CLOEXEC.  Avoid defining separate variables for all of them
    unless it is really necessary.  */
+/* TODO.  This is of course only true on Linux.  But we can simply ignore this
+   and implement all of these at the same time.  */
 #define __have_pipe2 __have_sock_cloexec
 
 #endif


Regards,
 Thomas

Attachment: signature.asc
Description: Digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]