diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2020-04-15 06:45:13 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2020-04-15 06:45:13 -0700 |
commit | 3f83104f00ce3818a3ea257be7ea8a7b4134e9be (patch) | |
tree | 60f7dcd98c6bc31169495f8fa40f308cd741ae6b /stream.c | |
parent | a3d57c4d0a70adb874afc9d74321494ff9367e0f (diff) | |
download | txr-3f83104f00ce3818a3ea257be7ea8a7b4134e9be.tar.gz txr-3f83104f00ce3818a3ea257be7ea8a7b4134e9be.tar.bz2 txr-3f83104f00ce3818a3ea257be7ea8a7b4134e9be.zip |
New "n" open file mode option: nonblocking.
* stream.c (w_fopen_mode): Special handling via open and
fdopen is now required if either the m.notrunc or m.nonblock
is present. Since m.nonblock is just an option that can be
used with any open mode, we must handle the mode flags more
fully, to generate more possible combinations of open flags.
(do_parse_mode): Check for 'n', and set nonblock flag.
* stream.h (struct stdio_mode): New member, nonblock.
(stdio_moe_init_blank, stdio_mode_init_r,
stdio_mode_init_rpb): Update initalizers to set nonblock to
zero.
* txr.1: Documented, and also added missing i option to the
mode string syntax grammar summary.
Diffstat (limited to 'stream.c')
-rw-r--r-- | stream.c | 17 |
1 files changed, 12 insertions, 5 deletions
@@ -1085,21 +1085,25 @@ static struct strm_ops stdio_sock_ops; static FILE *w_fopen_mode(const wchar_t *wname, const wchar_t *mode, const struct stdio_mode m) { + if (m.notrunc || m.nonblock) { #if HAVE_FCNTL - if (m.notrunc) { char *name = utf8_dup_to(wname); - int flags = (m.read ? O_RDWR : O_WRONLY) | O_CREAT; + int flags = (if3(m.read && m.write, O_RDWR, 0) | + if3(m.read && !m.write, O_RDONLY, 0) | + if3(!m.read && m.write, + if3(!m.notrunc, O_TRUNC, 0) | O_WRONLY | O_CREAT, 0) | + if3(m.nonblock, O_NONBLOCK, 0)); int fd = open(name, flags, 0666); free(name); if (fd < 0) return NULL; return (fd < 0) ? NULL : w_fdopen(fd, mode); - } #else - if (m.notrunc) uw_throwf(file_error_s, - lit("open-file: \"m\" mode not supported on this system"), nao); + lit("open-file: specified mode not supported on this system"), + nao); #endif + } return w_fopen(wname, mode); } @@ -1451,6 +1455,9 @@ static struct stdio_mode do_parse_mode(val mode_str, struct stdio_mode m_dfl) } m.unbuf = 1; break; + case 'n': + m.nonblock = 1; + break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (m.unbuf) { |