mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-25 18:03:37 +08:00
Split out io_pipe_t, let io_buffer_t inherit it
This commit is contained in:
parent
e020ad0c06
commit
00b6431ad9
29
exec.cpp
29
exec.cpp
|
@ -164,8 +164,8 @@ static bool use_fd_in_pipe(int fd, const io_chain_t &io_chain)
|
|||
if ((io->io_mode == IO_BUFFER) ||
|
||||
(io->io_mode == IO_PIPE))
|
||||
{
|
||||
if (io->param1.pipe_fd[0] == fd ||
|
||||
io->param1.pipe_fd[1] == fd)
|
||||
CAST_INIT(const io_pipe_t *, io_pipe, io.get());
|
||||
if (io_pipe->pipe_fd[0] == fd || io_pipe->pipe_fd[1] == fd)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -615,17 +615,13 @@ void exec(parser_t &parser, job_t *j)
|
|||
|
||||
}
|
||||
|
||||
shared_ptr<io_data_t> pipe_read(new io_data_t);
|
||||
pipe_read->fd = 0;
|
||||
pipe_read->io_mode = IO_PIPE;
|
||||
shared_ptr<io_pipe_t> pipe_read(new io_pipe_t(0));
|
||||
pipe_read->is_input = 1;
|
||||
pipe_read->param1.pipe_fd[0] = pipe_read->param1.pipe_fd[1] = -1;
|
||||
pipe_read->pipe_fd[0] = pipe_read->pipe_fd[1] = -1;
|
||||
|
||||
shared_ptr<io_data_t> pipe_write(new io_data_t);
|
||||
pipe_write->fd = 1;
|
||||
pipe_write->io_mode = IO_PIPE;
|
||||
shared_ptr<io_pipe_t> pipe_write(new io_pipe_t(1));
|
||||
pipe_write->is_input = 0;
|
||||
pipe_write->param1.pipe_fd[0] = pipe_write->param1.pipe_fd[1] = -1;
|
||||
pipe_write->pipe_fd[0] = pipe_write->pipe_fd[1] = -1;
|
||||
|
||||
j->io.push_back(pipe_write);
|
||||
|
||||
|
@ -738,7 +734,7 @@ void exec(parser_t &parser, job_t *j)
|
|||
break;
|
||||
}
|
||||
|
||||
memcpy(pipe_write->param1.pipe_fd, mypipe, sizeof(int)*2);
|
||||
memcpy(pipe_write->pipe_fd, mypipe, sizeof(int)*2);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -855,7 +851,8 @@ void exec(parser_t &parser, job_t *j)
|
|||
}
|
||||
case IO_PIPE:
|
||||
{
|
||||
builtin_stdin = in->param1.pipe_fd[0];
|
||||
CAST_INIT(const io_pipe_t *, in_pipe, in.get());
|
||||
builtin_stdin = in_pipe->pipe_fd[0];
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -908,7 +905,7 @@ void exec(parser_t &parser, job_t *j)
|
|||
}
|
||||
else
|
||||
{
|
||||
builtin_stdin = pipe_read->param1.pipe_fd[0];
|
||||
builtin_stdin = pipe_read->pipe_fd[0];
|
||||
}
|
||||
|
||||
if (builtin_stdin == -1)
|
||||
|
@ -1332,14 +1329,14 @@ void exec(parser_t &parser, job_t *j)
|
|||
Close the pipe the current process uses to read from the
|
||||
previous process_t
|
||||
*/
|
||||
if (pipe_read->param1.pipe_fd[0] >= 0)
|
||||
exec_close(pipe_read->param1.pipe_fd[0]);
|
||||
if (pipe_read->pipe_fd[0] >= 0)
|
||||
exec_close(pipe_read->pipe_fd[0]);
|
||||
/*
|
||||
Set up the pipe the next process uses to read from the
|
||||
current process_t
|
||||
*/
|
||||
if (p_wants_pipe)
|
||||
pipe_read->param1.pipe_fd[0] = mypipe[0];
|
||||
pipe_read->pipe_fd[0] = mypipe[0];
|
||||
|
||||
/*
|
||||
If there is a next process in the pipeline, close the
|
||||
|
|
29
io.cpp
29
io.cpp
|
@ -53,12 +53,6 @@ Utilities for io redirection.
|
|||
|
||||
void io_data_t::print() const
|
||||
{
|
||||
switch (io_mode)
|
||||
{
|
||||
case IO_PIPE:
|
||||
fprintf(stderr, "pipe {%d, %d}\n", param1.pipe_fd[0], param1.pipe_fd[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void io_close_t::print() const
|
||||
|
@ -76,6 +70,11 @@ void io_file_t::print() const
|
|||
fprintf(stderr, "file (%s)\n", filename_cstr);
|
||||
}
|
||||
|
||||
void io_pipe_t::print() const
|
||||
{
|
||||
fprintf(stderr, "pipe {%d, %d}\n", pipe_fd[0], pipe_fd[1]);
|
||||
}
|
||||
|
||||
void io_buffer_t::print() const
|
||||
{
|
||||
fprintf(stderr, "buffer %p (size %lu)\n", out_buffer_ptr(), out_buffer_size());
|
||||
|
@ -83,21 +82,21 @@ void io_buffer_t::print() const
|
|||
|
||||
void io_buffer_t::read()
|
||||
{
|
||||
exec_close(param1.pipe_fd[1]);
|
||||
exec_close(pipe_fd[1]);
|
||||
|
||||
if (io_mode == IO_BUFFER)
|
||||
{
|
||||
/* if( fcntl( param1.pipe_fd[0], F_SETFL, 0 ) )
|
||||
/* if( fcntl( pipe_fd[0], F_SETFL, 0 ) )
|
||||
{
|
||||
wperror( L"fcntl" );
|
||||
return;
|
||||
} */
|
||||
debug(4, L"io_buffer_t::read: blocking read on fd %d", param1.pipe_fd[0]);
|
||||
debug(4, L"io_buffer_t::read: blocking read on fd %d", pipe_fd[0]);
|
||||
while (1)
|
||||
{
|
||||
char b[4096];
|
||||
long l;
|
||||
l=read_blocked(param1.pipe_fd[0], b, 4096);
|
||||
l=read_blocked(pipe_fd[0], b, 4096);
|
||||
if (l==0)
|
||||
{
|
||||
break;
|
||||
|
@ -115,7 +114,7 @@ void io_buffer_t::read()
|
|||
{
|
||||
debug(1,
|
||||
_(L"An error occured while reading output from code block on file descriptor %d"),
|
||||
param1.pipe_fd[0]);
|
||||
pipe_fd[0]);
|
||||
wperror(L"io_buffer_t::read");
|
||||
}
|
||||
|
||||
|
@ -137,13 +136,13 @@ io_buffer_t *io_buffer_t::create(bool is_input)
|
|||
buffer_redirect->out_buffer_create();
|
||||
buffer_redirect->is_input = is_input ? true : false;
|
||||
|
||||
if (exec_pipe(buffer_redirect->param1.pipe_fd) == -1)
|
||||
if (exec_pipe(buffer_redirect->pipe_fd) == -1)
|
||||
{
|
||||
debug(1, PIPE_ERROR);
|
||||
wperror(L"pipe");
|
||||
success = false;
|
||||
}
|
||||
else if (fcntl(buffer_redirect->param1.pipe_fd[0],
|
||||
else if (fcntl(buffer_redirect->pipe_fd[0],
|
||||
F_SETFL,
|
||||
O_NONBLOCK))
|
||||
{
|
||||
|
@ -170,10 +169,10 @@ io_buffer_t::~io_buffer_t()
|
|||
*/
|
||||
if (is_input)
|
||||
{
|
||||
exec_close(param1.pipe_fd[1]);
|
||||
exec_close(pipe_fd[1]);
|
||||
}
|
||||
|
||||
exec_close(param1.pipe_fd[0]);
|
||||
exec_close(pipe_fd[0]);
|
||||
|
||||
/*
|
||||
Dont free fd for writing. This should already be free'd before
|
||||
|
|
29
io.h
29
io.h
|
@ -27,15 +27,6 @@ public:
|
|||
/** FD to redirect */
|
||||
int fd;
|
||||
|
||||
/**
|
||||
Type-specific parameter for redirection
|
||||
*/
|
||||
union
|
||||
{
|
||||
/** Fds for IO_PIPE and for IO_BUFFER */
|
||||
int pipe_fd[2];
|
||||
} param1;
|
||||
|
||||
virtual void print() const;
|
||||
|
||||
/** Set to true if this is an input io redirection */
|
||||
|
@ -44,7 +35,6 @@ public:
|
|||
io_data_t(io_mode_t m = IO_INVALID, int f=0) :
|
||||
io_mode(m),
|
||||
fd(f),
|
||||
param1(),
|
||||
is_input(0)
|
||||
{
|
||||
}
|
||||
|
@ -113,16 +103,31 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class io_buffer_t : public io_data_t
|
||||
class io_pipe_t : public io_data_t
|
||||
{
|
||||
public:
|
||||
int pipe_fd[2];
|
||||
|
||||
virtual void print() const;
|
||||
|
||||
io_pipe_t(int f):
|
||||
io_data_t(IO_PIPE, f),
|
||||
pipe_fd()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class io_buffer_t : public io_pipe_t
|
||||
{
|
||||
private:
|
||||
/** buffer to save output in */
|
||||
shared_ptr<std::vector<char> > out_buffer;
|
||||
|
||||
io_buffer_t(int f):
|
||||
io_data_t(IO_BUFFER, f),
|
||||
io_pipe_t(f),
|
||||
out_buffer()
|
||||
{
|
||||
io_mode = IO_BUFFER;
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
33
postfork.cpp
33
postfork.cpp
|
@ -117,15 +117,16 @@ static void free_redirected_fds_from_pipes(io_chain_t &io_chain)
|
|||
for (size_t j = 0; j < max; j++)
|
||||
{
|
||||
/* We're only interested in pipes */
|
||||
io_data_t *possible_conflict = io_chain.at(j).get();
|
||||
if (possible_conflict->io_mode != IO_PIPE && possible_conflict->io_mode != IO_BUFFER)
|
||||
io_data_t *io = io_chain.at(j).get();
|
||||
if (io->io_mode != IO_PIPE && io->io_mode != IO_BUFFER)
|
||||
continue;
|
||||
|
||||
CAST_INIT(io_pipe_t *, possible_conflict, io);
|
||||
/* If the pipe is a conflict, dup it to some other value */
|
||||
for (int k=0; k<2; k++)
|
||||
{
|
||||
/* If it's not a conflict, we don't care */
|
||||
if (possible_conflict->param1.pipe_fd[k] != fd_to_free)
|
||||
if (possible_conflict->pipe_fd[k] != fd_to_free)
|
||||
continue;
|
||||
|
||||
/* Repeat until we have a replacement fd */
|
||||
|
@ -140,7 +141,7 @@ static void free_redirected_fds_from_pipes(io_chain_t &io_chain)
|
|||
FATAL_EXIT();
|
||||
}
|
||||
}
|
||||
possible_conflict->param1.pipe_fd[k] = replacement_fd;
|
||||
possible_conflict->pipe_fd[k] = replacement_fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -245,6 +246,7 @@ static int handle_child_io(io_chain_t &io_chain)
|
|||
case IO_BUFFER:
|
||||
case IO_PIPE:
|
||||
{
|
||||
CAST_INIT(io_pipe_t *, io_pipe, io);
|
||||
/* If write_pipe_idx is 0, it means we're connecting to the read end (first pipe fd). If it's 1, we're connecting to the write end (second pipe fd). */
|
||||
unsigned int write_pipe_idx = (io->is_input ? 0 : 1);
|
||||
/*
|
||||
|
@ -253,20 +255,20 @@ static int handle_child_io(io_chain_t &io_chain)
|
|||
write_pipe?L"write":L"read",
|
||||
(io->io_mode == IO_BUFFER)?L"buffer":L"pipe",
|
||||
io->fd,
|
||||
io->param1.pipe_fd[0],
|
||||
io->param1.pipe_fd[1]);
|
||||
io->pipe_fd[0],
|
||||
io->pipe_fd[1]);
|
||||
*/
|
||||
if (dup2(io->param1.pipe_fd[write_pipe_idx], io->fd) != io->fd)
|
||||
if (dup2(io_pipe->pipe_fd[write_pipe_idx], io->fd) != io->fd)
|
||||
{
|
||||
debug_safe(1, LOCAL_PIPE_ERROR);
|
||||
safe_perror("dup2");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (io->param1.pipe_fd[0] >= 0)
|
||||
exec_close(io->param1.pipe_fd[0]);
|
||||
if (io->param1.pipe_fd[1] >= 0)
|
||||
exec_close(io->param1.pipe_fd[1]);
|
||||
if (io_pipe->pipe_fd[0] >= 0)
|
||||
exec_close(io_pipe->pipe_fd[0]);
|
||||
if (io_pipe->pipe_fd[1] >= 0)
|
||||
exec_close(io_pipe->pipe_fd[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -485,8 +487,9 @@ bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_fil
|
|||
case IO_BUFFER:
|
||||
case IO_PIPE:
|
||||
{
|
||||
CAST_INIT(const io_pipe_t *, io_pipe, io.get());
|
||||
unsigned int write_pipe_idx = (io->is_input ? 0 : 1);
|
||||
int from_fd = io->param1.pipe_fd[write_pipe_idx];
|
||||
int from_fd = io_pipe->pipe_fd[write_pipe_idx];
|
||||
int to_fd = io->fd;
|
||||
if (! err)
|
||||
err = posix_spawn_file_actions_adddup2(actions, from_fd, to_fd);
|
||||
|
@ -495,14 +498,14 @@ bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_fil
|
|||
if (write_pipe_idx > 0)
|
||||
{
|
||||
if (! err)
|
||||
err = posix_spawn_file_actions_addclose(actions, io->param1.pipe_fd[0]);
|
||||
err = posix_spawn_file_actions_addclose(actions, io_pipe->pipe_fd[0]);
|
||||
if (! err)
|
||||
err = posix_spawn_file_actions_addclose(actions, io->param1.pipe_fd[1]);
|
||||
err = posix_spawn_file_actions_addclose(actions, io_pipe->pipe_fd[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! err)
|
||||
err = posix_spawn_file_actions_addclose(actions, io->param1.pipe_fd[0]);
|
||||
err = posix_spawn_file_actions_addclose(actions, io_pipe->pipe_fd[0]);
|
||||
|
||||
}
|
||||
break;
|
||||
|
|
9
proc.cpp
9
proc.cpp
|
@ -869,10 +869,11 @@ static int select_try(job_t *j)
|
|||
|
||||
for (size_t idx = 0; idx < j->io.size(); idx++)
|
||||
{
|
||||
const io_data_t *d = j->io.at(idx).get();
|
||||
if (d->io_mode == IO_BUFFER)
|
||||
const io_data_t *io = j->io.at(idx).get();
|
||||
if (io->io_mode == IO_BUFFER)
|
||||
{
|
||||
int fd = d->param1.pipe_fd[0];
|
||||
CAST_INIT(const io_pipe_t *, io_pipe, io);
|
||||
int fd = io_pipe->pipe_fd[0];
|
||||
// fwprintf( stderr, L"fd %d on job %ls\n", fd, j->command );
|
||||
FD_SET(fd, &fds);
|
||||
maxfd = maxi(maxfd, fd);
|
||||
|
@ -924,7 +925,7 @@ static void read_try(job_t *j)
|
|||
char b[BUFFER_SIZE];
|
||||
long l;
|
||||
|
||||
l=read_blocked(buff->param1.pipe_fd[0],
|
||||
l=read_blocked(buff->pipe_fd[0],
|
||||
b, BUFFER_SIZE);
|
||||
if (l==0)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user