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:
|
||||
{
|
||||
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,
|
||||
FILE_ERROR,
|
||||
in->filename_cstr);
|
||||
in_file->filename_cstr);
|
||||
|
||||
wperror(L"open");
|
||||
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);
|
||||
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. */
|
||||
if (strcmp(path, "/dev/null") != 0)
|
||||
{
|
||||
|
@ -860,13 +862,14 @@ void exec(parser_t &parser, job_t *j)
|
|||
case IO_FILE:
|
||||
{
|
||||
/* Do not set CLO_EXEC because child needs access */
|
||||
builtin_stdin=open(in->filename_cstr,
|
||||
in->param2.flags, OPEN_MASK);
|
||||
CAST_INIT(const io_file_t *, in_file, in.get());
|
||||
builtin_stdin=open(in_file->filename_cstr,
|
||||
in_file->flags, OPEN_MASK);
|
||||
if (builtin_stdin == -1)
|
||||
{
|
||||
debug(1,
|
||||
FILE_ERROR,
|
||||
in->filename_cstr);
|
||||
in_file->filename_cstr);
|
||||
wperror(L"open");
|
||||
}
|
||||
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++)
|
||||
{
|
||||
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;
|
||||
break;
|
||||
|
|
8
io.cpp
8
io.cpp
|
@ -55,9 +55,6 @@ void io_data_t::print() const
|
|||
{
|
||||
switch (io_mode)
|
||||
{
|
||||
case IO_FILE:
|
||||
fprintf(stderr, "file (%s)\n", filename_cstr);
|
||||
break;
|
||||
case IO_PIPE:
|
||||
fprintf(stderr, "pipe {%d, %d}\n", param1.pipe_fd[0], param1.pipe_fd[1]);
|
||||
break;
|
||||
|
@ -77,6 +74,11 @@ void io_fd_t::print() const
|
|||
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)
|
||||
{
|
||||
exec_close(d->param1.pipe_fd[1]);
|
||||
|
|
51
io.h
51
io.h
|
@ -39,24 +39,6 @@ public:
|
|||
int pipe_fd[2];
|
||||
} 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 */
|
||||
void out_buffer_create()
|
||||
{
|
||||
|
@ -100,15 +82,12 @@ public:
|
|||
io_mode(m),
|
||||
fd(f),
|
||||
param1(),
|
||||
param2(),
|
||||
filename_cstr(NULL),
|
||||
is_input(0)
|
||||
{
|
||||
}
|
||||
|
||||
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> >
|
||||
{
|
||||
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"));
|
||||
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
|
||||
{
|
||||
|
||||
int flags = 0;
|
||||
switch (type)
|
||||
{
|
||||
case TOK_REDIRECT_APPEND:
|
||||
new_io.reset(new io_data_t(IO_FILE, fd));
|
||||
new_io->param2.flags = O_CREAT | O_APPEND | O_WRONLY;
|
||||
new_io->set_filename(target);
|
||||
flags = O_CREAT | O_APPEND | O_WRONLY;
|
||||
break;
|
||||
|
||||
case TOK_REDIRECT_OUT:
|
||||
new_io.reset(new io_data_t(IO_FILE, fd));
|
||||
new_io->param2.flags = O_CREAT | O_WRONLY | O_TRUNC;
|
||||
new_io->set_filename(target);
|
||||
flags = O_CREAT | O_WRONLY | O_TRUNC;
|
||||
break;
|
||||
|
||||
case TOK_REDIRECT_NOCLOB:
|
||||
new_io.reset(new io_data_t(IO_FILE, fd));
|
||||
new_io->param2.flags = O_CREAT | O_EXCL | O_WRONLY;
|
||||
new_io->set_filename(target);
|
||||
flags = O_CREAT | O_EXCL | O_WRONLY;
|
||||
break;
|
||||
|
||||
case TOK_REDIRECT_IN:
|
||||
new_io.reset(new io_data_t(IO_FILE, fd));
|
||||
new_io->param2.flags = O_RDONLY;
|
||||
new_io->set_filename(target);
|
||||
flags = O_RDONLY;
|
||||
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:
|
||||
{
|
||||
// Here we definitely do not want to set CLO_EXEC because our child needs access
|
||||
if ((tmp=open(io->filename_cstr,
|
||||
io->param2.flags, OPEN_MASK))==-1)
|
||||
CAST_INIT(io_file_t *, io_file, io);
|
||||
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))
|
||||
{
|
||||
debug_safe(1, NOCLOB_ERROR, io->filename_cstr);
|
||||
debug_safe(1, NOCLOB_ERROR, io_file->filename_cstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_safe(1, FILE_ERROR, io->filename_cstr);
|
||||
debug_safe(1, FILE_ERROR, io_file->filename_cstr);
|
||||
safe_perror("open");
|
||||
}
|
||||
|
||||
|
@ -467,8 +468,9 @@ bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_fil
|
|||
|
||||
case IO_FILE:
|
||||
{
|
||||
CAST_INIT(const io_file_t *, io_file, io.get());
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue