chiark / gitweb /
Introduce setnonblock()
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 27 Sep 2014 12:26:17 +0000 (13:26 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 8 Oct 2014 17:25:18 +0000 (18:25 +0100)
This involves reworking setcloexec()'s implementation so that we can
reuse it.

We now treat a failure to set O_NONBLOCK in udp_make_socket as a
fatal, rather than recoverable, error.  This is fine.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
process.c
secnet.h
udp.c
util.c

index edc87ac..12e2caa 100644 (file)
--- a/process.c
+++ b/process.c
@@ -301,9 +301,7 @@ void start_signal_handling(void)
     pipe_cloexec(p);
     spw=p[1];
     spr=p[0];
-    if (fcntl(spw, F_SETFL, fcntl(spw, F_GETFL)|O_NONBLOCK)==-1) {
-       fatal_perror("start_signal_handling: fcntl(O_NONBLOCK)");
-    }
+    setnonblock(spw);
 
     register_for_poll(NULL,signal_beforepoll,signal_afterpoll,"signal");
     signal_handling=True;
index 1bfe8a1..b2f6927 100644 (file)
--- a/secnet.h
+++ b/secnet.h
@@ -174,6 +174,7 @@ extern void *safe_realloc_ary(void *p, size_t size, size_t count,
                              const char *message);
 
 void setcloexec(int fd); /* cannot fail */
+void setnonblock(int fd); /* cannot fail */
 void pipe_cloexec(int fd[2]); /* pipe(), setcloexec() twice; cannot fail */
 
 extern int sys_cmd(const char *file, const char *argc, ...);
diff --git a/udp.c b/udp.c
index 8947058..5ad0fd4 100644 (file)
--- a/udp.c
+++ b/udp.c
@@ -206,8 +206,7 @@ bool_t udp_make_socket(struct udpcommon *uc, struct udpsock *us,
 
     us->fd=socket(addr->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP);
     if (us->fd<0) FAIL("socket");
-    if (fcntl(us->fd, F_SETFL, fcntl(us->fd, F_GETFL)|O_NONBLOCK)==-1)
-       FAIL("fcntl(set O_NONBLOCK)");
+    setnonblock(us->fd);
     setcloexec(us->fd);
 #ifdef CONFIG_IPV6
     if (addr->sa.sa_family==AF_INET6) {
diff --git a/util.c b/util.c
index e34336c..7d102b1 100644 (file)
--- a/util.c
+++ b/util.c
@@ -177,13 +177,17 @@ int32_t write_mpbin(MP_INT *a, uint8_t *buffer, int32_t buflen)
     return i;
 }
 
-void setcloexec(int fd) {
-    int r=fcntl(fd, F_GETFD);
-    if (r<0) fatal_perror("fcntl(,F_GETFD) failed");
-    r=fcntl(fd, F_SETFD, r|FD_CLOEXEC);
-    if (r<0) fatal_perror("fcntl(,F_SETFD,|FD_CLOEXEC) failed");
+#define DEFINE_SETFDFLAG(fn,FL,FLAG)                                   \
+void fn(int fd) {                                                      \
+    int r=fcntl(fd, F_GET##FL);                                                \
+    if (r<0) fatal_perror("fcntl(,F_GET" #FL ") failed");              \
+    r=fcntl(fd, F_SET##FL, r|FLAG);                                    \
+    if (r<0) fatal_perror("fcntl(,F_SET" #FL ",|" #FLAG ") failed");   \
 }
 
+DEFINE_SETFDFLAG(setcloexec,FD,FD_CLOEXEC);
+DEFINE_SETFDFLAG(setnonblock,FL,O_NONBLOCK);
+
 void pipe_cloexec(int fd[2]) {
     int r=pipe(fd);
     if (r) fatal_perror("pipe");