summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/flags.c
diff options
context:
space:
mode:
authorguenther <guenther@openbsd.org>2014-08-31 02:21:18 +0000
committerguenther <guenther@openbsd.org>2014-08-31 02:21:18 +0000
commited42a740c17f7bea88482a716bacbc46a06b7249 (patch)
tree41266fb76fcd0cc0229b872cae91df94a24ad430 /lib/libc/stdio/flags.c
parentregen (diff)
downloadwireguard-openbsd-ed42a740c17f7bea88482a716bacbc46a06b7249.tar.xz
wireguard-openbsd-ed42a740c17f7bea88482a716bacbc46a06b7249.zip
Add additional userland interfaces for setting close-on-exec on fds
when creating them: mkostemp(), mkostemps(), the 'e' mode letter for fopen(), freopen(), fdopen(), and popen(). The close-on-exec flag will be cleared by the action created by posix_spawn_file_actions_adddup2(). Also, add support for the C11 'x' mode letter for fopen() and freopen(), setting O_EXCL when possibly creating files. Note: this requires kernel support for pipe2() and dup3()! ok millert@
Diffstat (limited to 'lib/libc/stdio/flags.c')
-rw-r--r--lib/libc/stdio/flags.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/lib/libc/stdio/flags.c b/lib/libc/stdio/flags.c
index 8cd1ce279d0..d6df6daab88 100644
--- a/lib/libc/stdio/flags.c
+++ b/lib/libc/stdio/flags.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: flags.c,v 1.7 2013/11/12 07:04:35 deraadt Exp $ */
+/* $OpenBSD: flags.c,v 1.8 2014/08/31 02:21:18 guenther Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -72,11 +72,34 @@ __sflags(const char *mode, int *optr)
return (0);
}
- /* [rwa]\+ or [rwa]b\+ means read and write */
- if (*mode == '+' || (*mode == 'b' && mode[1] == '+')) {
- ret = __SRW;
- m = O_RDWR;
- }
+ while (*mode != '\0')
+ switch (*mode++) {
+ case 'b':
+ break;
+ case '+':
+ ret = __SRW;
+ m = O_RDWR;
+ break;
+ case 'e':
+ o |= O_CLOEXEC;
+ break;
+ case 'x':
+ if (o & O_CREAT)
+ o |= O_EXCL;
+ break;
+ default:
+ /*
+ * Lots of software passes other extension mode
+ * letters, like Window's 't'
+ */
+#if 0
+ errno = EINVAL;
+ return (0);
+#else
+ break;
+#endif
+ }
+
*optr = m | o;
return (ret);
}