summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--stream.c24
-rw-r--r--stream.h7
-rw-r--r--txr.138
3 files changed, 61 insertions, 8 deletions
diff --git a/stream.c b/stream.c
index 953dc76a..7114a123 100644
--- a/stream.c
+++ b/stream.c
@@ -1584,6 +1584,20 @@ static struct stdio_mode do_parse_mode(val mode_str, struct stdio_mode m_dfl,
nredir++;
break;
}
+ case '?':
+ {
+ wchar_t *past;
+ long val = wcstol(ms + 1, &past, 10);
+
+ if (past == ms + 1 || val < 0 || val >= INT_MAX) {
+ m.malformed = 1;
+ return m;
+ }
+
+ m.streamfd = val;
+ ms = past - 1;
+ break;
+ }
case 'z':
m.gzip = 1;
if (isdigit(convert(unsigned char, ms[1]))) {
@@ -4526,6 +4540,8 @@ static val open_subprocess(val name, val mode_str, val args, val fun)
struct save_fds sfds;
val ret = nil;
int fds_flags = (input ? FDS_IN : FDS_OUT) | FDS_ERR;
+ int streamfd_in = m.streamfd != -1 ? m.streamfd : STDIN_FILENO;
+ int streamfd_out = m.streamfd != -1 ? m.streamfd : STDOUT_FILENO;
args = default_null_arg(args);
fun = default_null_arg(fun);
@@ -4579,13 +4595,13 @@ static val open_subprocess(val name, val mode_str, val args, val fun)
fds_clobber(&sfds, fds_flags);
if (input) {
- dup2(fd[1], STDOUT_FILENO);
- if (fd[1] != STDOUT_FILENO) /* You never know */
+ dup2(fd[1], streamfd_out);
+ if (fd[1] != streamfd_out) /* You never know */
close(fd[1]);
close(fd[0]);
} else {
- dup2(fd[0], STDIN_FILENO);
- if (fd[0] != STDIN_FILENO) /* You never know */
+ dup2(fd[0], streamfd_in);
+ if (fd[0] != streamfd_in) /* You never know */
close(fd[0]);
close(fd[1]);
}
diff --git a/stream.h b/stream.h
index d4300154..9b3adf1f 100644
--- a/stream.h
+++ b/stream.h
@@ -121,11 +121,12 @@ struct stdio_mode {
unsigned tmpfile : 1;
int buforder : 5;
int redir[STDIO_MODE_NREDIRS][2];
+ int streamfd;
};
-#define stdio_mode_init_blank { 0, 0, 0, 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, 0, 0, 0, -1, { { 0 } } }
-#define stdio_mode_init_rpb { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, { { 0 } } }
+#define stdio_mode_init_blank { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, { { 0 } }, -1 }
+#define stdio_mode_init_r { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, { { 0 } }, -1 }
+#define stdio_mode_init_rpb { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, { { 0 } }, -1 }
#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 ec0a09b9..f20e0963 100644
--- a/txr.1
+++ b/txr.1
@@ -62988,7 +62988,7 @@ Note that it permits no whitespace characters:
.mets < mode := { < selector [ + ] | + }
.mets < selector := { r | w | a | m | T }
.mets < options := { b | x | l | u | i | n | < digit |
-.mets \ \ \ \ \ \ \ \ \ \ \ \ \ \ <> z[ digit ] | < redirection }
+.mets \ \ \ \ \ \ \ \ \ \ \ \ \ \ <> z[ digit ] | < redirection | >> ? fdno }
.mets < digit := { 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 }
.onom
@@ -63160,6 +63160,17 @@ in mode strings that are passed to the
function; the syntax performs I/O redirections in the child process
created by that function, and is described in that function's
documentation.
+.meIP >> ? fdno
+Like
+.metn redirection ,
+this option refers to syntax which only has an effect in
+mode strings that are passed to the
+.code open-process
+function. The syntax selects an alternative file descriptor
+to connect to the returned stream. This is described in the
+documentation for
+.code open-process
+function.
.RE
.IP
The
@@ -66219,6 +66230,31 @@ to standard output, standard input is connected to the null device,
and descriptor 27 is redirected to descriptor 31.
The
+.meta mode-string
+argument of
+.code open-process
+also supports a special
+.mono
+.meti >> ? fdno
+.onom
+syntax. This syntax specifies an alternative file descriptor in
+the process to which the returned stream should be connected.
+By default, when the process is opened for writing, its standard
+output descriptpr 1 is used, and when it is opened for reading,
+its standard input descriptor 0 is used. This option overrides the
+choice of descriptor. The
+.meta fdno
+portion of the syntax must be a sequence of decimal digits, immediately
+following the
+.code ?
+character. For example, the mode string
+.str ?2
+specifies that the process is to be open for input, such that
+the input stream captures the standard error output of
+that process. In this situation, the standard output will not be
+captured; it remains unredirected.
+
+The
.code open-subprocess
function is a variant of
.codn open-process .