summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-04-15 06:45:13 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-04-15 06:45:13 -0700
commit0cd2b3e18515de4f49b438f095015ee58cd46f97 (patch)
tree60f7dcd98c6bc31169495f8fa40f308cd741ae6b
parent4421b92f2f2c85fc167d3d011ad9e9188095b3cb (diff)
downloadtxr-0cd2b3e18515de4f49b438f095015ee58cd46f97.tar.gz
txr-0cd2b3e18515de4f49b438f095015ee58cd46f97.tar.bz2
txr-0cd2b3e18515de4f49b438f095015ee58cd46f97.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.
-rw-r--r--stream.c17
-rw-r--r--stream.h7
-rw-r--r--txr.14
3 files changed, 19 insertions, 9 deletions
diff --git a/stream.c b/stream.c
index a8177ff3..15da2d25 100644
--- a/stream.c
+++ b/stream.c
@@ -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) {
diff --git a/stream.h b/stream.h
index 14204d81..5a628d9b 100644
--- a/stream.h
+++ b/stream.h
@@ -109,6 +109,7 @@ struct stdio_mode {
unsigned append : 1;
unsigned binary : 1;
unsigned notrunc : 1;
+ unsigned nonblock : 1;
unsigned interactive : 1;
unsigned unbuf : 1;
unsigned linebuf : 1;
@@ -116,9 +117,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, -1, { { 0 } } }
-#define stdio_mode_init_r { 0, 1, 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, -1, { { 0 } } }
+#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 std_input (deref(lookup_var_l(nil, stdin_s)))
#define std_output (deref(lookup_var_l(nil, stdout_s)))
diff --git a/txr.1 b/txr.1
index 8cfd6aa7..102a6a74 100644
--- a/txr.1
+++ b/txr.1
@@ -49226,7 +49226,7 @@ grammar. 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 | < digit | < redirection }
+.mets < options := { b | l | u | i | n | < digit | < redirection }
.mets < digit := { 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 }
.onom
@@ -49314,6 +49314,8 @@ In addition, for a stream opened for writing or reading and writing, the
mode letter specifies that the stream will be line buffered, unless
specified as unbuffered with
.codn u .
+.coIP n
+Specifies that the operation shall not block.
.meIP digit
A decimal digit specifies the the stream buffer size
as binary exponential buffer size order, such that