Split out io_pipe_t, let io_buffer_t inherit it

This commit is contained in:
Cheer Xiao 2013-01-15 17:31:36 +08:00
parent e020ad0c06
commit 00b6431ad9
5 changed files with 67 additions and 62 deletions

View file

@ -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
View file

@ -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
View file

@ -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:

View file

@ -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;

View file

@ -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)
{