summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAriadne Conill <ariadne@dereferenced.org>2021-12-27 14:44:29 -0600
committerTimo Teräs <timo.teras@iki.fi>2021-12-29 20:14:41 +0200
commite6b1b2902824a4adca313503280563ee7114c6c8 (patch)
tree88f402e6369aed9a71390f1490baf5dc2de1a7cd
parentfade8b1ef21f9e1c7f905215ac7209c6160a2b7a (diff)
downloadapk-tools-e6b1b2902824a4adca313503280563ee7114c6c8.tar.gz
apk-tools-e6b1b2902824a4adca313503280563ee7114c6c8.tar.bz2
apk-tools-e6b1b2902824a4adca313503280563ee7114c6c8.tar.xz
apk-tools-e6b1b2902824a4adca313503280563ee7114c6c8.zip
portability: implement pipe2 and mknodat
-rw-r--r--portability/meson.build2
-rw-r--r--portability/mknodat.c30
-rw-r--r--portability/pipe2.c22
-rw-r--r--portability/sys/stat.h5
-rw-r--r--portability/unistd.h5
5 files changed, 64 insertions, 0 deletions
diff --git a/portability/meson.build b/portability/meson.build
index 3a680fe..a16cc77 100644
--- a/portability/meson.build
+++ b/portability/meson.build
@@ -7,6 +7,8 @@ libportability_src = []
check_functions = [
['memrchr', 'memrchr.c', 'NEED_MEMRCHR', 'string.h'],
['strlcpy', 'strlcpy.c', 'NEED_STRLCPY', 'string.h'],
+ ['pipe2', 'pipe2.c', 'NEED_PIPE2', 'unistd.h'],
+ ['mknodat', 'mknodat.c', 'NEED_MKNODAT', 'sys/stat.h'],
]
diff --git a/portability/mknodat.c b/portability/mknodat.c
new file mode 100644
index 0000000..0d5c459
--- /dev/null
+++ b/portability/mknodat.c
@@ -0,0 +1,30 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+int mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev)
+{
+ int ret = 0;
+ int curdir_fd = open(".", O_DIRECTORY | O_CLOEXEC);
+ if (curdir_fd < 0)
+ return -1;
+
+ if (fchdir(dirfd) < 0) {
+ ret = -1;
+ goto cleanup;
+ }
+
+ /* if mknod fails, fall through and restore the original dirfd */
+ if (mknod(pathname, mode, dev) < 0) {
+ ret = -1;
+ }
+
+ if (fchdir(curdir_fd) < 0) {
+ ret = -1;
+ goto cleanup;
+ }
+
+cleanup:
+ close(curdir_fd);
+ return ret;
+}
diff --git a/portability/pipe2.c b/portability/pipe2.c
new file mode 100644
index 0000000..e39834f
--- /dev/null
+++ b/portability/pipe2.c
@@ -0,0 +1,22 @@
+#include <fcntl.h>
+#include <unistd.h>
+
+int pipe2(int pipefd[2], int flags)
+{
+ int r;
+
+ if ((r = pipe(pipefd)) < 0)
+ return r;
+
+ if (flags & O_CLOEXEC) {
+ (void) fcntl(pipefd[0], F_SETFD, FD_CLOEXEC);
+ (void) fcntl(pipefd[1], F_SETFD, FD_CLOEXEC);
+ }
+
+ if (flags & O_NONBLOCK) {
+ (void) fcntl(pipefd[0], F_SETFL, O_NONBLOCK);
+ (void) fcntl(pipefd[1], F_SETFL, O_NONBLOCK);
+ }
+
+ return 0;
+}
diff --git a/portability/sys/stat.h b/portability/sys/stat.h
new file mode 100644
index 0000000..1d3e5f8
--- /dev/null
+++ b/portability/sys/stat.h
@@ -0,0 +1,5 @@
+#include_next <sys/stat.h>
+
+#ifdef NEED_MKNODAT
+int mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev);
+#endif
diff --git a/portability/unistd.h b/portability/unistd.h
new file mode 100644
index 0000000..4d0cef8
--- /dev/null
+++ b/portability/unistd.h
@@ -0,0 +1,5 @@
+#include_next <unistd.h>
+
+#ifdef NEED_PIPE2
+int pipe2(int pipefd[2], int flags);
+#endif