diff --git a/lib/libc/stdio/flags.c b/lib/libc/stdio/flags.c index e1efe4e..3b21e52 100644 --- a/lib/libc/stdio/flags.c +++ b/lib/libc/stdio/flags.c @@ -76,11 +76,28 @@ __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; + /* parse modifiers */ + while (*mode) { + switch(*mode++) { + case '+': /* rw mode */ + ret = __SRW; + m = O_RDWR; + break; + case 'b': /* binary mode */ + /* no need for special treatment */ + break; + case 'x': /* force creation */ + if ( (o & O_CREAT) && !(o & O_APPEND) ) { + o |= O_EXCL; + break; + } + /* fallthrough */ + default: + errno = EINVAL; + return (0); + } } + *optr = m | o; return (ret); } diff --git a/lib/libc/stdio/fopen.3 b/lib/libc/stdio/fopen.3 index a3a852f..dc727fb 100644 --- a/lib/libc/stdio/fopen.3 +++ b/lib/libc/stdio/fopen.3 @@ -73,10 +73,16 @@ The stream is positioned at the beginning of the file. .It Dq Li w Truncate to zero length or create text file for writing. The stream is positioned at the beginning of the file. +.It Dq Li wx +Create new file and open it for writing. It will fail if +the file already exists. .It Dq Li w+ Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file. +.It Dq Li w+x +Create new file and open it for reading and writing. It +will fail if the file already exists. .It Dq Li a Open for writing. The file is created if it does not exist. @@ -101,7 +107,7 @@ string can also include the letter ``b'' either as a third character or as a character between the characters in any of the two-character strings described above. This is strictly for compatibility with -.St -isoC +.St -isoC-2011 and has no effect; the ``b'' is ignored. .Pp Any created files will have mode @@ -276,7 +282,7 @@ and .Fn freopen functions conform to -.St -isoC . +.St -isoC-2011 . The .Fn fdopen function