diff options
-rw-r--r-- | stream.c | 24 | ||||
-rw-r--r-- | stream.h | 7 | ||||
-rw-r--r-- | txr.1 | 38 |
3 files changed, 61 insertions, 8 deletions
@@ -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]); } @@ -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))) @@ -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 . |