aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--c/cloexec/.gitignore1
-rw-r--r--c/cloexec/Makefile8
-rw-r--r--c/cloexec/cloexec.c26
3 files changed, 35 insertions, 0 deletions
diff --git a/c/cloexec/.gitignore b/c/cloexec/.gitignore
new file mode 100644
index 0000000..089a255
--- /dev/null
+++ b/c/cloexec/.gitignore
@@ -0,0 +1 @@
+cloexec
diff --git a/c/cloexec/Makefile b/c/cloexec/Makefile
new file mode 100644
index 0000000..1c57a62
--- /dev/null
+++ b/c/cloexec/Makefile
@@ -0,0 +1,8 @@
+include ../base.mk
+
+all: cloexec
+cloexec: cloexec.c
+ $(CC) $(CFLAGS) -o $@ $<
+
+clean:
+ rm -f cloexec
diff --git a/c/cloexec/cloexec.c b/c/cloexec/cloexec.c
new file mode 100644
index 0000000..ba899ee
--- /dev/null
+++ b/c/cloexec/cloexec.c
@@ -0,0 +1,26 @@
+#define _GNU_SOURCE
+#include <assert.h>
+#include <err.h>
+#include <paths.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+int
+main(void)
+{
+ int fd, nfd;
+
+ if ((fd = open(_PATH_DEVNULL, O_RDONLY | O_CLOEXEC)) == -1)
+ err(1, "open: %s", _PATH_DEVNULL);
+
+ if ((nfd = dup(fd)) == -1)
+ err(1, "dup");
+ assert((fcntl(nfd, F_GETFD) & FD_CLOEXEC) == 0);
+ close(nfd);
+ if (dup3(fd, nfd, O_CLOEXEC) == -1)
+ err(1, "dup");
+ assert((fcntl(nfd, F_GETFD) & FD_CLOEXEC) != 0);
+
+ close(nfd);
+ close(fd);
+}