diff options
-rw-r--r-- | stream.c | 12 | ||||
-rw-r--r-- | stream.h | 7 | ||||
-rw-r--r-- | txr.1 | 12 |
3 files changed, 26 insertions, 5 deletions
@@ -1130,6 +1130,7 @@ static FILE *w_fopen_mode(const wchar_t *wname, const wchar_t *mode, if3(m.create || m.append, if3(!m.notrunc, O_TRUNC, 0) | O_CREAT, 0) | if3(m.append, O_APPEND, 0) | + if3(m.excl, O_EXCL, 0) | if3(m.nonblock, O_NONBLOCK, 0)); char *stkname = coerce(char *, alloca(nsiz)); int fd; @@ -1143,7 +1144,8 @@ static FILE *w_fopen_mode(const wchar_t *wname, const wchar_t *mode, return (fd < 0) ? NULL : w_fdopen(fd, mode); #else - if (m.notrunc || m.nonblock) + /* TODO: detect if fopen supports "x" in mode */ + if (m.notrunc || m.excl || m.nonblock) uw_throwf(file_error_s, lit("open-file: specified mode not supported on this system"), nao); @@ -1484,6 +1486,14 @@ static struct stdio_mode do_parse_mode(val mode_str, struct stdio_mode m_dfl, case 'b': m.binary = 1; break; + case 'x': + /* Ensure only "w" and "w+" can have the "x" option. */ + if (!m.write || !m.create || m.notrunc) { + m.malformed = 1; + return m; + } + m.excl = 1; + break; case 'i': m.interactive = 1; break; @@ -111,6 +111,7 @@ struct stdio_mode { unsigned append : 1; unsigned binary : 1; unsigned notrunc : 1; + unsigned excl : 1; unsigned nonblock : 1; unsigned interactive : 1; unsigned unbuf : 1; @@ -119,9 +120,9 @@ struct stdio_mode { int redir[STDIO_MODE_NREDIRS][2]; }; -#define stdio_mode_init_blank { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, { { 0 } } } -#define stdio_mode_init_r { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, { { 0 } } } -#define stdio_mode_init_rpb { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, -1, { { 0 } } } +#define stdio_mode_init_blank { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, { { 0 } } } +#define stdio_mode_init_r { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, { { 0 } } } +#define stdio_mode_init_rpb { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, { { 0 } } } #define std_input (deref(lookup_var_l(nil, stdin_s))) #define std_output (deref(lookup_var_l(nil, stdout_s))) @@ -56510,7 +56510,7 @@ Note that it permits no whitespace characters: .mets < mode-string := [ < mode ] [ < options ] .mets < mode := { < selector [ + ] | + } .mets < selector := { r | w | a | m } -.mets < options := { b | l | u | i | n | < digit | < redirection } +.mets < options := { b | x | l | u | i | n | < digit | < redirection } .mets < digit := { 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 } .onom @@ -56578,6 +56578,16 @@ The file is opened in binary mode: no line ending translation takes place. In the absence of this option, files are opened in text mode, in which newline characters in the stream are an abstract indication of the end of a line, translate to a system-specific way of terminating lines in text files. +.coIP x +The file is created and opened only if it does not already exist. +Otherwise, a +.code file-error +exception is thrown. +This option is allowed only with the +.code w +and +.code w+ +modes. .coIP l Specifies that the stream will be line buffered. This means that an implicit flush operation takes place whenever the newline character is output. |