Commit dd444aac authored by Andrey Vagin's avatar Andrey Vagin Committed by Cyrill Gorcunov

pipe: avoid intersection of pipe descriptors.

1. pipe() returns two descriptors with numbers (r: x, w: y).
We may want to restore it as (r: y, w: x).
2. Close a extra end, before try to restore a target end.
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Acked-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent 6840bcc4
...@@ -935,6 +935,30 @@ static int set_fd_flags(int fd, int flags) ...@@ -935,6 +935,30 @@ static int set_fd_flags(int fd, int flags)
return fcntl(fd, F_SETFL, flags); return fcntl(fd, F_SETFL, flags);
} }
static int reopen_pipe(int src, int *dst, int *other)
{
int tmp;
if (*dst != -1) {
if (*other == *dst) {
tmp = dup(*other);
if (tmp < 0) {
pr_perror("dup failed\n");
return -1;
}
close_safe(other);
*other = tmp;
}
tmp = reopen_fd_as(*dst, src);
if (tmp < 0)
return -1;
} else
*dst = src;
return 0;
}
static int create_pipe(int pid, struct pipe_entry *e, struct pipe_info *pi, int pipes_fd) static int create_pipe(int pid, struct pipe_entry *e, struct pipe_info *pi, int pipes_fd)
{ {
unsigned long time = 1000; unsigned long time = 1000;
...@@ -960,37 +984,15 @@ static int create_pipe(int pid, struct pipe_entry *e, struct pipe_info *pi, int ...@@ -960,37 +984,15 @@ static int create_pipe(int pid, struct pipe_entry *e, struct pipe_info *pi, int
} }
} }
if (pi->read_fd != -1) if (reopen_pipe(pfd[0], &pi->read_fd, &pfd[1]))
tmp = reopen_fd_as(pi->read_fd, pfd[0]); return -1;
else if (reopen_pipe(pfd[1], &pi->write_fd, &pi->read_fd))
pi->read_fd = pfd[0]; return -1;
if (tmp < 0)
return 1;
if (pi->write_fd != -1)
tmp = reopen_fd_as(pi->write_fd, pfd[1]);
else
pi->write_fd = pfd[1];
if (tmp < 0)
return 1;
pi->real_pid = getpid(); pi->real_pid = getpid();
pi->status |= PIPE_CREATED; pi->status |= PIPE_CREATED;
if (pi->write_fd != e->fd && pi->read_fd != e->fd) {
switch (e->flags & O_ACCMODE) {
case O_WRONLY:
tmp = dup2(pi->write_fd, e->fd);
break;
case O_RDONLY:
tmp = dup2(pi->read_fd, e->fd);
break;
}
}
if (tmp < 0)
return 1;
pr_info("\t%d: Done, waiting for others (users %d) on %d pid with r:%d w:%d\n", pr_info("\t%d: Done, waiting for others (users %d) on %d pid with r:%d w:%d\n",
pid, pi->users, pi->real_pid, pi->read_fd, pi->write_fd); pid, pi->users, pi->real_pid, pi->read_fd, pi->write_fd);
...@@ -1012,6 +1014,20 @@ static int create_pipe(int pid, struct pipe_entry *e, struct pipe_info *pi, int ...@@ -1012,6 +1014,20 @@ static int create_pipe(int pid, struct pipe_entry *e, struct pipe_info *pi, int
close_safe(&pi->write_fd); close_safe(&pi->write_fd);
} }
tmp = 0;
if (pi->write_fd != e->fd && pi->read_fd != e->fd) {
switch (e->flags & O_ACCMODE) {
case O_WRONLY:
tmp = dup2(pi->write_fd, e->fd);
break;
case O_RDONLY:
tmp = dup2(pi->read_fd, e->fd);
break;
}
}
if (tmp < 0)
return 1;
tmp = set_fd_flags(e->fd, e->flags); tmp = set_fd_flags(e->fd, e->flags);
if (tmp < 0) if (tmp < 0)
return 1; return 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment