diff options
author | Paul A. Patience <paul@apatience.com> | 2021-08-29 04:42:04 -0400 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-08-29 08:06:58 -0700 |
commit | 469cd5ab27bba7679bebe60cd0617e09f4838e50 (patch) | |
tree | f4b10bd2b1555a274ecdf9df9d3d63511d8b60c3 /stream.c | |
parent | 702d02d7958a20e8cd0e6872ca12540c84cdca55 (diff) | |
download | txr-469cd5ab27bba7679bebe60cd0617e09f4838e50.tar.gz txr-469cd5ab27bba7679bebe60cd0617e09f4838e50.tar.bz2 txr-469cd5ab27bba7679bebe60cd0617e09f4838e50.zip |
open-file: add mode option "x".
* stream.h (struct stdio_mode): New member, excl flag.
(stdio_mode_init_blank, stdio_mode_init_r, stdio_mode_init_rpb):
Add initializer for excl flag.
* stream.c (do_parse_mode): Handle 'x' in mode string.
(w_fopen_mode): Add O_EXCL flag if m.excl is set. Throw an error
if we don't HAVE_FCNTL and m.excl is set.
* txr.1: Document mode option "x".
Diffstat (limited to 'stream.c')
-rw-r--r-- | stream.c | 12 |
1 files changed, 11 insertions, 1 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; |