summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/flags.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/stdio/flags.c')
-rw-r--r--lib/libc/stdio/flags.c55
1 files changed, 28 insertions, 27 deletions
diff --git a/lib/libc/stdio/flags.c b/lib/libc/stdio/flags.c
index 1878c2f..b7552a4 100644
--- a/lib/libc/stdio/flags.c
+++ b/lib/libc/stdio/flags.c
@@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$");
int
__sflags(const char *mode, int *optr)
{
- int ret, m, o;
+ int ret, m, o, known;
switch (*mode++) {
@@ -78,34 +78,35 @@ __sflags(const char *mode, int *optr)
return (0);
}
- /* 'b' (binary) is ignored */
- if (*mode == 'b')
- mode++;
-
- /* [rwa][b]\+ means read and write */
- if (*mode == '+') {
- mode++;
- ret = __SRW;
- m = O_RDWR;
- }
-
- /* 'b' (binary) can appear here, too -- and is ignored again */
- if (*mode == 'b')
- mode++;
-
- /* 'x' means exclusive (fail if the file exists) */
- if (*mode == 'x') {
- mode++;
- if (m == O_RDONLY) {
- errno = EINVAL;
- return (0);
+ do {
+ known = 1;
+ switch (*mode++) {
+ case 'b':
+ /* 'b' (binary) is ignored */
+ break;
+ case '+':
+ /* [rwa][b]\+ means read and write */
+ ret = __SRW;
+ m = O_RDWR;
+ break;
+ case 'x':
+ /* 'x' means exclusive (fail if the file exists) */
+ o |= O_EXCL;
+ break;
+ case 'e':
+ /* set close-on-exec */
+ o |= O_CLOEXEC;
+ break;
+ default:
+ known = 0;
+ break;
}
- o |= O_EXCL;
- }
+ } while (known);
- /* set close-on-exec */
- if (*mode == 'e')
- o |= O_CLOEXEC;
+ if ((o & O_EXCL) != 0 && m == O_RDONLY) {
+ errno = EINVAL;
+ return (0);
+ }
*optr = m | o;
return (ret);
OpenPOWER on IntegriCloud