Commit 839078f8 authored by Kirill Tkhai's avatar Kirill Tkhai Committed by Pavel Emelyanov

files: Make recv_fd_from_peer() non-block

This breaks everything, because files.c can't have
a deal with this yet. But next patch will teach it.

v5: Use hard-coded 0, -1 and 1 for successful return,
error and "again" request.

v4: tty: merge new_fd assignment to receive_tty()
    and return this function result directly.
Signed-off-by: 's avatarKirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 96946ee9
......@@ -925,13 +925,19 @@ static int keep_fd_for_future(struct fdinfo_list_entry *fle, int fd)
int recv_fd_from_peer(struct fdinfo_list_entry *fle)
{
struct fdinfo_list_entry *tmp;
int fd, ret, tsock;
int fd, ret, tsock, count;
if (fle->received)
return fle->fe->fd;
return 0;
tsock = get_service_fd(TRANSPORT_FD_OFF);
again:
if (ioctl(tsock, FIONREAD, &count) < 0) {
pr_perror("Can't do ioctl on transport sock: pid=%d\n", fle->pid);
return -1;
} else if (count == 0)
return 1;
ret = recv_fds(tsock, &fd, 1, (void *)&tmp, sizeof(struct fdinfo_list_entry *));
if (ret)
return -1;
......@@ -951,7 +957,7 @@ again:
if (reopen_fd_as(fle->fe->fd, fd) < 0)
return -1;
return fle->fe->fd;
return 0;
}
int send_fd_to_peer(int fd, struct fdinfo_list_entry *fle)
......@@ -1003,7 +1009,7 @@ static int post_open_fd(int pid, struct fdinfo_list_entry *fle)
struct file_desc *d = fle->desc;
if (fle != file_master(d)) {
if (receive_fd(pid, fle) < 0) {
if (receive_fd(pid, fle) != 0) {
pr_err("Can't receive\n");
return -1;
}
......@@ -1072,18 +1078,17 @@ static int open_fd(int pid, struct fdinfo_list_entry *fle)
static int receive_fd(int pid, struct fdinfo_list_entry *fle)
{
int fd;
int ret;
pr_info("\tReceive fd for %d\n", fle->fe->fd);
fd = recv_fd_from_peer(fle);
if (fd < 0) {
pr_err("Can't get fd=%d, pid=%d\n", fle->fe->fd, fle->pid);
return -1;
ret = recv_fd_from_peer(fle);
if (ret != 0) {
if (ret != 1)
pr_err("Can't get fd=%d, pid=%d\n", fle->fe->fd, fle->pid);
return ret;
}
BUG_ON(fd != fle->fe->fd);
if (fcntl(fle->fe->fd, F_SETFD, fle->fe->flags) == -1) {
pr_perror("Unable to set file descriptor flags");
return -1;
......
......@@ -230,18 +230,20 @@ static int reopen_pipe(int fd, int flags)
static int recv_pipe_fd(struct pipe_info *pi, int *new_fd)
{
struct fdinfo_list_entry *fle;
int tmp, fd;
int tmp, fd, ret;
fle = file_master(&pi->d);
fd = fle->fe->fd;
pr_info("\tWaiting fd for %d\n", fd);
tmp = recv_fd_from_peer(fle);
if (tmp < 0) {
pr_err("Can't get fd %d\n", tmp);
return -1;
ret = recv_fd_from_peer(fle);
if (ret != 0) {
if (ret != 1)
pr_err("Can't get fd %d\n", fd);
return ret;
}
tmp = fd;
if (pi->reopen)
fd = reopen_pipe(tmp, pi->pe->flags);
......
......@@ -1100,18 +1100,20 @@ static int open_unixsk_pair_master(struct unix_sk_info *ui, int *new_fd)
static int open_unixsk_pair_slave(struct unix_sk_info *ui, int *new_fd)
{
struct fdinfo_list_entry *fle;
int sk;
int sk, ret;
fle = file_master(&ui->d);
pr_info("Opening pair slave (id %#x ino %#x peer %#x) on %d\n",
ui->ue->id, ui->ue->ino, ui->ue->peer, fle->fe->fd);
sk = recv_fd_from_peer(fle);
if (sk < 0) {
pr_err("Can't recv pair slave\n");
return -1;
ret = recv_fd_from_peer(fle);
if (ret != 0) {
if (ret != 1)
pr_err("Can't recv pair slave\n");
return ret;
}
sk = fle->fe->fd;
if (bind_unix_sk(sk, ui))
return -1;
......
......@@ -913,24 +913,29 @@ err:
return ret;
}
static int receive_tty(struct tty_info *info)
static int receive_tty(struct tty_info *info, int *new_fd)
{
struct fdinfo_list_entry *fle;
int fd;
int fd, ret;
fle = file_master(&info->d);
pr_info("\tWaiting tty fd %d (pid %d)\n", fle->fe->fd, fle->pid);
fd = recv_fd_from_peer(fle);
if (fd < 0) {
pr_err("Can't get fd %d\n", fd);
return -1;
fd = fle->fe->fd;
ret = recv_fd_from_peer(fle);
if (ret != 0) {
if (ret != 1)
pr_err("Can't get fd %d\n", fd);
return ret;
}
if (rst_file_params(fd, info->tfe->fown, info->tfe->flags))
if (rst_file_params(fd, info->tfe->fown, info->tfe->flags) < 0) {
close_safe(&fd);
return -1;
}
return fd;
*new_fd = fd;
return 0;
}
static int pty_open_unpaired_slave(struct file_desc *d, struct tty_info *slave)
......@@ -1101,7 +1106,7 @@ static int tty_open(struct file_desc *d, int *new_fd)
tty_show_pty_info("open", info);
if (!info->create)
ret = receive_tty(info);
return receive_tty(info, new_fd);
else if (is_pty(info->driver) && !tty_is_master(info))
ret = pty_open_unpaired_slave(d, info);
else
......
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