mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-01-19 16:02:44 +08:00
Teach builtin_string to recognize redirections, not just pipes
Allows cases like `string split \n < file.txt` to work. Fixes 2422
This commit is contained in:
parent
d591cebf44
commit
abeaac6632
|
@ -54,7 +54,7 @@ static void string_unknown_option(parser_t &parser, io_streams_t &streams, const
|
|||
/* We read from stdin if we are the second or later process in a pipeline. */
|
||||
static bool string_args_from_stdin(const io_streams_t &streams)
|
||||
{
|
||||
return ! streams.is_first_process_in_pipeline;
|
||||
return streams.stdin_is_directly_redirected;
|
||||
}
|
||||
|
||||
static const wchar_t *string_get_arg_stdin(wcstring *storage, const io_streams_t &streams)
|
||||
|
|
16
src/exec.cpp
16
src/exec.cpp
|
@ -953,11 +953,25 @@ void exec_job(parser_t &parser, job_t *j)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Determine if we have a "direct" redirection for stdin
|
||||
bool stdin_is_directly_redirected;
|
||||
if (p != j->first_process)
|
||||
{
|
||||
// We must have a pipe
|
||||
stdin_is_directly_redirected = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We are not a pipe. Check if there is a redirection local to the process that's not IO_CLOSE
|
||||
const shared_ptr<const io_data_t> stdin_io = io_chain_get(p->io_chain(), STDIN_FILENO);
|
||||
stdin_is_directly_redirected = stdin_io && stdin_io->io_mode != IO_CLOSE;
|
||||
}
|
||||
|
||||
builtin_io_streams.reset(new io_streams_t());
|
||||
builtin_io_streams->stdin_fd = local_builtin_stdin;
|
||||
builtin_io_streams->out_is_redirected = has_fd(process_net_io_chain, STDOUT_FILENO);
|
||||
builtin_io_streams->err_is_redirected = has_fd(process_net_io_chain, STDERR_FILENO);
|
||||
builtin_io_streams->is_first_process_in_pipeline = (p == j->first_process);
|
||||
builtin_io_streams->stdin_is_directly_redirected = stdin_is_directly_redirected;
|
||||
builtin_io_streams->io_chain = &process_net_io_chain;
|
||||
|
||||
|
||||
|
|
|
@ -4024,7 +4024,7 @@ static void run_one_string_test(const wchar_t **argv, int expected_rc, const wch
|
|||
{
|
||||
parser_t parser(PARSER_TYPE_GENERAL, true);
|
||||
io_streams_t streams;
|
||||
streams.is_first_process_in_pipeline = true; // read from argv instead of stdin
|
||||
streams.stdin_is_directly_redirected = false; // read from argv instead of stdin
|
||||
int rc = builtin_string(parser, streams, const_cast<wchar_t**>(argv));
|
||||
wcstring args;
|
||||
for (int i = 0; argv[i] != 0; i++)
|
||||
|
|
7
src/io.h
7
src/io.h
|
@ -288,8 +288,9 @@ struct io_streams_t
|
|||
// fd representing stdin. This is not closed by the destructor.
|
||||
int stdin_fd;
|
||||
|
||||
// Whether this is the first process in a pipeline
|
||||
bool is_first_process_in_pipeline;
|
||||
// Whether stdin is "directly redirected," meaning it is the recipient of a pipe (foo | cmd) or direct redirection (cmd < foo.txt)
|
||||
// An "indirect redirection" would be e.g. begin ; cmd ; end < foo.txt
|
||||
bool stdin_is_directly_redirected;
|
||||
|
||||
// Indicates whether stdout and stderr are redirected (e.g. to a file or piped)
|
||||
bool out_is_redirected;
|
||||
|
@ -298,7 +299,7 @@ struct io_streams_t
|
|||
// Actual IO redirections. This is only used by the source builtin. Unowned.
|
||||
const io_chain_t *io_chain;
|
||||
|
||||
io_streams_t() : stdin_fd(-1), is_first_process_in_pipeline(false), out_is_redirected(false), err_is_redirected(false), io_chain(NULL)
|
||||
io_streams_t() : stdin_fd(-1), stdin_is_directly_redirected(false), out_is_redirected(false), err_is_redirected(false), io_chain(NULL)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user