mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Split out io_file_t
This commit is contained in:
parent
6f35792c74
commit
4b6bd7cae5
5 changed files with 90 additions and 81 deletions
17
exec.cpp
17
exec.cpp
|
@ -407,11 +407,12 @@ static bool io_transmogrify(const io_chain_t &in_chain, io_chain_t &out_chain, s
|
||||||
case IO_FILE:
|
case IO_FILE:
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
if ((fd=open(in->filename_cstr, in->param2.flags, OPEN_MASK))==-1)
|
CAST_INIT(io_file_t *, in_file, in.get());
|
||||||
|
if ((fd=open(in_file->filename_cstr, in_file->flags, OPEN_MASK))==-1)
|
||||||
{
|
{
|
||||||
debug(1,
|
debug(1,
|
||||||
FILE_ERROR,
|
FILE_ERROR,
|
||||||
in->filename_cstr);
|
in_file->filename_cstr);
|
||||||
|
|
||||||
wperror(L"open");
|
wperror(L"open");
|
||||||
success = false;
|
success = false;
|
||||||
|
@ -516,7 +517,8 @@ static bool can_use_posix_spawn_for_job(const job_t *job, const process_t *proce
|
||||||
const shared_ptr<const io_data_t> &io = job->io.at(idx);
|
const shared_ptr<const io_data_t> &io = job->io.at(idx);
|
||||||
if (io->io_mode == IO_FILE)
|
if (io->io_mode == IO_FILE)
|
||||||
{
|
{
|
||||||
const char *path = io->filename_cstr;
|
CAST_INIT(const io_file_t *, io_file, io.get());
|
||||||
|
const char *path = io_file->filename_cstr;
|
||||||
/* This IO action is a file redirection. Only allow /dev/null, which is a common case we assume won't fail. */
|
/* This IO action is a file redirection. Only allow /dev/null, which is a common case we assume won't fail. */
|
||||||
if (strcmp(path, "/dev/null") != 0)
|
if (strcmp(path, "/dev/null") != 0)
|
||||||
{
|
{
|
||||||
|
@ -860,13 +862,14 @@ void exec(parser_t &parser, job_t *j)
|
||||||
case IO_FILE:
|
case IO_FILE:
|
||||||
{
|
{
|
||||||
/* Do not set CLO_EXEC because child needs access */
|
/* Do not set CLO_EXEC because child needs access */
|
||||||
builtin_stdin=open(in->filename_cstr,
|
CAST_INIT(const io_file_t *, in_file, in.get());
|
||||||
in->param2.flags, OPEN_MASK);
|
builtin_stdin=open(in_file->filename_cstr,
|
||||||
|
in_file->flags, OPEN_MASK);
|
||||||
if (builtin_stdin == -1)
|
if (builtin_stdin == -1)
|
||||||
{
|
{
|
||||||
debug(1,
|
debug(1,
|
||||||
FILE_ERROR,
|
FILE_ERROR,
|
||||||
in->filename_cstr);
|
in_file->filename_cstr);
|
||||||
wperror(L"open");
|
wperror(L"open");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1158,7 +1161,7 @@ void exec(parser_t &parser, job_t *j)
|
||||||
for (io_chain_t::iterator iter = j->io.begin(); iter != j->io.end(); iter++)
|
for (io_chain_t::iterator iter = j->io.begin(); iter != j->io.end(); iter++)
|
||||||
{
|
{
|
||||||
const shared_ptr<io_data_t> &tmp_io = *iter;
|
const shared_ptr<io_data_t> &tmp_io = *iter;
|
||||||
if (tmp_io->io_mode == IO_FILE && strcmp(tmp_io->filename_cstr, "/dev/null") != 0)
|
if (tmp_io->io_mode == IO_FILE && strcmp(static_cast<const io_file_t *>(tmp_io.get())->filename_cstr, "/dev/null") != 0)
|
||||||
{
|
{
|
||||||
skip_fork = false;
|
skip_fork = false;
|
||||||
break;
|
break;
|
||||||
|
|
8
io.cpp
8
io.cpp
|
@ -55,9 +55,6 @@ void io_data_t::print() const
|
||||||
{
|
{
|
||||||
switch (io_mode)
|
switch (io_mode)
|
||||||
{
|
{
|
||||||
case IO_FILE:
|
|
||||||
fprintf(stderr, "file (%s)\n", filename_cstr);
|
|
||||||
break;
|
|
||||||
case IO_PIPE:
|
case IO_PIPE:
|
||||||
fprintf(stderr, "pipe {%d, %d}\n", param1.pipe_fd[0], param1.pipe_fd[1]);
|
fprintf(stderr, "pipe {%d, %d}\n", param1.pipe_fd[0], param1.pipe_fd[1]);
|
||||||
break;
|
break;
|
||||||
|
@ -77,6 +74,11 @@ void io_fd_t::print() const
|
||||||
fprintf(stderr, "FD map %d -> %d\n", old_fd, fd);
|
fprintf(stderr, "FD map %d -> %d\n", old_fd, fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void io_file_t::print() const
|
||||||
|
{
|
||||||
|
fprintf(stderr, "file (%s)\n", filename_cstr);
|
||||||
|
}
|
||||||
|
|
||||||
void io_buffer_read(io_data_t *d)
|
void io_buffer_read(io_data_t *d)
|
||||||
{
|
{
|
||||||
exec_close(d->param1.pipe_fd[1]);
|
exec_close(d->param1.pipe_fd[1]);
|
||||||
|
|
51
io.h
51
io.h
|
@ -39,24 +39,6 @@ public:
|
||||||
int pipe_fd[2];
|
int pipe_fd[2];
|
||||||
} param1;
|
} param1;
|
||||||
|
|
||||||
|
|
||||||
/** Second type-specific paramter for redirection */
|
|
||||||
union
|
|
||||||
{
|
|
||||||
/** file creation flags to send to open for IO_FILE */
|
|
||||||
int flags;
|
|
||||||
} param2;
|
|
||||||
|
|
||||||
/** Filename IO_FILE. malloc'd. This needs to be used after fork, so don't use wcstring here. */
|
|
||||||
const char *filename_cstr;
|
|
||||||
|
|
||||||
/** Convenience to set filename_cstr via wcstring */
|
|
||||||
void set_filename(const wcstring &str)
|
|
||||||
{
|
|
||||||
free((void *)filename_cstr);
|
|
||||||
filename_cstr = wcs2str(str.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Function to create the output buffer */
|
/** Function to create the output buffer */
|
||||||
void out_buffer_create()
|
void out_buffer_create()
|
||||||
{
|
{
|
||||||
|
@ -100,15 +82,12 @@ public:
|
||||||
io_mode(m),
|
io_mode(m),
|
||||||
fd(f),
|
fd(f),
|
||||||
param1(),
|
param1(),
|
||||||
param2(),
|
|
||||||
filename_cstr(NULL),
|
|
||||||
is_input(0)
|
is_input(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~io_data_t()
|
virtual ~io_data_t()
|
||||||
{
|
{
|
||||||
free((void *)filename_cstr);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -141,6 +120,36 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class io_file_t : public io_data_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Filename, malloc'd. This needs to be used after fork, so don't use wcstring here. */
|
||||||
|
const char *filename_cstr;
|
||||||
|
/** file creation flags to send to open */
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
/** Convenience to set filename_cstr via wcstring */
|
||||||
|
void set_filename(const wcstring &str)
|
||||||
|
{
|
||||||
|
free((void *)filename_cstr);
|
||||||
|
filename_cstr = wcs2str(str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void print() const;
|
||||||
|
|
||||||
|
io_file_t(int f, const char *fname = NULL, int fl = 0) :
|
||||||
|
io_data_t(IO_FILE, f),
|
||||||
|
filename_cstr(fname ? strdup(fname) : NULL),
|
||||||
|
flags(fl)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~io_file_t()
|
||||||
|
{
|
||||||
|
free((void *)filename_cstr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class io_chain_t : public std::vector<shared_ptr<io_data_t> >
|
class io_chain_t : public std::vector<shared_ptr<io_data_t> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
81
parser.cpp
81
parser.cpp
|
@ -1568,67 +1568,60 @@ void parser_t::parse_job_argument_list(process_t *p,
|
||||||
_(L"Invalid IO redirection"));
|
_(L"Invalid IO redirection"));
|
||||||
tok_next(tok);
|
tok_next(tok);
|
||||||
}
|
}
|
||||||
|
else if (type == TOK_REDIRECT_FD)
|
||||||
|
{
|
||||||
|
if (target == L"-")
|
||||||
|
{
|
||||||
|
new_io.reset(new io_close_t(fd));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wchar_t *end;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
int old_fd = fish_wcstoi(target.c_str(), &end, 10);
|
||||||
|
|
||||||
|
if (old_fd < 0 || errno || *end)
|
||||||
|
{
|
||||||
|
error(SYNTAX_ERROR,
|
||||||
|
tok_get_pos(tok),
|
||||||
|
_(L"Requested redirection to something that is not a file descriptor %ls"),
|
||||||
|
target.c_str());
|
||||||
|
|
||||||
|
tok_next(tok);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_io.reset(new io_fd_t(fd, old_fd));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int flags = 0;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case TOK_REDIRECT_APPEND:
|
case TOK_REDIRECT_APPEND:
|
||||||
new_io.reset(new io_data_t(IO_FILE, fd));
|
flags = O_CREAT | O_APPEND | O_WRONLY;
|
||||||
new_io->param2.flags = O_CREAT | O_APPEND | O_WRONLY;
|
|
||||||
new_io->set_filename(target);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_REDIRECT_OUT:
|
case TOK_REDIRECT_OUT:
|
||||||
new_io.reset(new io_data_t(IO_FILE, fd));
|
flags = O_CREAT | O_WRONLY | O_TRUNC;
|
||||||
new_io->param2.flags = O_CREAT | O_WRONLY | O_TRUNC;
|
|
||||||
new_io->set_filename(target);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_REDIRECT_NOCLOB:
|
case TOK_REDIRECT_NOCLOB:
|
||||||
new_io.reset(new io_data_t(IO_FILE, fd));
|
flags = O_CREAT | O_EXCL | O_WRONLY;
|
||||||
new_io->param2.flags = O_CREAT | O_EXCL | O_WRONLY;
|
|
||||||
new_io->set_filename(target);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_REDIRECT_IN:
|
case TOK_REDIRECT_IN:
|
||||||
new_io.reset(new io_data_t(IO_FILE, fd));
|
flags = O_RDONLY;
|
||||||
new_io->param2.flags = O_RDONLY;
|
|
||||||
new_io->set_filename(target);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_REDIRECT_FD:
|
|
||||||
{
|
|
||||||
if (target == L"-")
|
|
||||||
{
|
|
||||||
new_io.reset(new io_close_t(fd));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wchar_t *end;
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
int old_fd = fish_wcstoi(target.c_str(), &end, 10);
|
|
||||||
|
|
||||||
if (old_fd < 0 || errno || *end)
|
|
||||||
{
|
|
||||||
error(SYNTAX_ERROR,
|
|
||||||
tok_get_pos(tok),
|
|
||||||
_(L"Requested redirection to something that is not a file descriptor %ls"),
|
|
||||||
target.c_str());
|
|
||||||
|
|
||||||
tok_next(tok);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
new_io.reset(new io_fd_t(fd, old_fd));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
io_file_t *new_io_file = new io_file_t(fd, NULL, flags);
|
||||||
|
new_io_file->set_filename(target);
|
||||||
|
new_io.reset(new_io_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
postfork.cpp
14
postfork.cpp
|
@ -189,17 +189,18 @@ static int handle_child_io(io_chain_t &io_chain)
|
||||||
case IO_FILE:
|
case IO_FILE:
|
||||||
{
|
{
|
||||||
// Here we definitely do not want to set CLO_EXEC because our child needs access
|
// Here we definitely do not want to set CLO_EXEC because our child needs access
|
||||||
if ((tmp=open(io->filename_cstr,
|
CAST_INIT(io_file_t *, io_file, io);
|
||||||
io->param2.flags, OPEN_MASK))==-1)
|
if ((tmp=open(io_file->filename_cstr,
|
||||||
|
io_file->flags, OPEN_MASK))==-1)
|
||||||
{
|
{
|
||||||
if ((io->param2.flags & O_EXCL) &&
|
if ((io_file->flags & O_EXCL) &&
|
||||||
(errno ==EEXIST))
|
(errno ==EEXIST))
|
||||||
{
|
{
|
||||||
debug_safe(1, NOCLOB_ERROR, io->filename_cstr);
|
debug_safe(1, NOCLOB_ERROR, io_file->filename_cstr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debug_safe(1, FILE_ERROR, io->filename_cstr);
|
debug_safe(1, FILE_ERROR, io_file->filename_cstr);
|
||||||
safe_perror("open");
|
safe_perror("open");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,8 +468,9 @@ bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_fil
|
||||||
|
|
||||||
case IO_FILE:
|
case IO_FILE:
|
||||||
{
|
{
|
||||||
|
CAST_INIT(const io_file_t *, io_file, io.get());
|
||||||
if (! err)
|
if (! err)
|
||||||
err = posix_spawn_file_actions_addopen(actions, io->fd, io->filename_cstr, io->param2.flags /* mode */, OPEN_MASK);
|
err = posix_spawn_file_actions_addopen(actions, io->fd, io_file->filename_cstr, io_file->flags /* mode */, OPEN_MASK);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue