summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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