- djm@cvs.openbsd.org 2010/04/23 22:42:05
[session.c] set stderr to /dev/null for subsystems rather than just closing it. avoids hangs if a subsystem or shell initialisation writes to stderr. bz#1750; ok markus@
This commit is contained in:
parent
85c50d7858
commit
22a29880bb
|
@ -10,6 +10,11 @@
|
||||||
set "detach_close" flag when registering channel cleanup callbacks.
|
set "detach_close" flag when registering channel cleanup callbacks.
|
||||||
This causes the channel to close normally when its fds close and
|
This causes the channel to close normally when its fds close and
|
||||||
hangs when terminating a mux slave using ~. bz#1758; ok markus@
|
hangs when terminating a mux slave using ~. bz#1758; ok markus@
|
||||||
|
- djm@cvs.openbsd.org 2010/04/23 22:42:05
|
||||||
|
[session.c]
|
||||||
|
set stderr to /dev/null for subsystems rather than just closing it.
|
||||||
|
avoids hangs if a subsystem or shell initialisation writes to stderr.
|
||||||
|
bz#1750; ok markus@
|
||||||
|
|
||||||
20100423
|
20100423
|
||||||
- (dtucker) [configure.ac] Bug #1756: Check for the existence of a lib64 dir
|
- (dtucker) [configure.ac] Bug #1756: Check for the existence of a lib64 dir
|
||||||
|
|
59
session.c
59
session.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: session.c,v 1.252 2010/03/07 11:57:13 dtucker Exp $ */
|
/* $OpenBSD: session.c,v 1.253 2010/04/23 22:42:05 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
|
@ -47,6 +47,7 @@
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#ifdef HAVE_PATHS_H
|
#ifdef HAVE_PATHS_H
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
|
@ -447,6 +448,9 @@ do_exec_no_pty(Session *s, const char *command)
|
||||||
#ifdef USE_PIPES
|
#ifdef USE_PIPES
|
||||||
int pin[2], pout[2], perr[2];
|
int pin[2], pout[2], perr[2];
|
||||||
|
|
||||||
|
if (s == NULL)
|
||||||
|
fatal("do_exec_no_pty: no session");
|
||||||
|
|
||||||
/* Allocate pipes for communicating with the program. */
|
/* Allocate pipes for communicating with the program. */
|
||||||
if (pipe(pin) < 0) {
|
if (pipe(pin) < 0) {
|
||||||
error("%s: pipe in: %.100s", __func__, strerror(errno));
|
error("%s: pipe in: %.100s", __func__, strerror(errno));
|
||||||
|
@ -458,33 +462,59 @@ do_exec_no_pty(Session *s, const char *command)
|
||||||
close(pin[1]);
|
close(pin[1]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (pipe(perr) < 0) {
|
if (s->is_subsystem) {
|
||||||
error("%s: pipe err: %.100s", __func__, strerror(errno));
|
if ((perr[1] = open(_PATH_DEVNULL, O_WRONLY)) == -1) {
|
||||||
|
error("%s: open(%s): %s", __func__, _PATH_DEVNULL,
|
||||||
|
strerror(errno));
|
||||||
close(pin[0]);
|
close(pin[0]);
|
||||||
close(pin[1]);
|
close(pin[1]);
|
||||||
close(pout[0]);
|
close(pout[0]);
|
||||||
close(pout[1]);
|
close(pout[1]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
perr[0] = -1;
|
||||||
|
} else {
|
||||||
|
if (pipe(perr) < 0) {
|
||||||
|
error("%s: pipe err: %.100s", __func__,
|
||||||
|
strerror(errno));
|
||||||
|
close(pin[0]);
|
||||||
|
close(pin[1]);
|
||||||
|
close(pout[0]);
|
||||||
|
close(pout[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
int inout[2], err[2];
|
int inout[2], err[2];
|
||||||
|
|
||||||
|
if (s == NULL)
|
||||||
|
fatal("do_exec_no_pty: no session");
|
||||||
|
|
||||||
/* Uses socket pairs to communicate with the program. */
|
/* Uses socket pairs to communicate with the program. */
|
||||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0) {
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0) {
|
||||||
error("%s: socketpair #1: %.100s", __func__, strerror(errno));
|
error("%s: socketpair #1: %.100s", __func__, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) {
|
if (s->is_subsystem) {
|
||||||
error("%s: socketpair #2: %.100s", __func__, strerror(errno));
|
if ((err[0] = open(_PATH_DEVNULL, O_WRONLY)) == -1) {
|
||||||
|
error("%s: open(%s): %s", __func__, _PATH_DEVNULL,
|
||||||
|
strerror(errno));
|
||||||
close(inout[0]);
|
close(inout[0]);
|
||||||
close(inout[1]);
|
close(inout[1]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
err[1] = -1;
|
||||||
|
} else {
|
||||||
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) {
|
||||||
|
error("%s: socketpair #2: %.100s", __func__,
|
||||||
|
strerror(errno));
|
||||||
|
close(inout[0]);
|
||||||
|
close(inout[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (s == NULL)
|
|
||||||
fatal("do_exec_no_pty: no session");
|
|
||||||
|
|
||||||
session_proctitle(s);
|
session_proctitle(s);
|
||||||
|
|
||||||
/* Fork the child. */
|
/* Fork the child. */
|
||||||
|
@ -496,12 +526,14 @@ do_exec_no_pty(Session *s, const char *command)
|
||||||
close(pin[1]);
|
close(pin[1]);
|
||||||
close(pout[0]);
|
close(pout[0]);
|
||||||
close(pout[1]);
|
close(pout[1]);
|
||||||
|
if (perr[0] != -1)
|
||||||
close(perr[0]);
|
close(perr[0]);
|
||||||
close(perr[1]);
|
close(perr[1]);
|
||||||
#else
|
#else
|
||||||
close(inout[0]);
|
close(inout[0]);
|
||||||
close(inout[1]);
|
close(inout[1]);
|
||||||
close(err[0]);
|
close(err[0]);
|
||||||
|
if (err[1] != -1)
|
||||||
close(err[1]);
|
close(err[1]);
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -536,6 +568,7 @@ do_exec_no_pty(Session *s, const char *command)
|
||||||
close(pout[1]);
|
close(pout[1]);
|
||||||
|
|
||||||
/* Redirect stderr. */
|
/* Redirect stderr. */
|
||||||
|
if (perr[0] != -1)
|
||||||
close(perr[0]);
|
close(perr[0]);
|
||||||
if (dup2(perr[1], 2) < 0)
|
if (dup2(perr[1], 2) < 0)
|
||||||
perror("dup2 stderr");
|
perror("dup2 stderr");
|
||||||
|
@ -547,6 +580,7 @@ do_exec_no_pty(Session *s, const char *command)
|
||||||
* seem to depend on it.
|
* seem to depend on it.
|
||||||
*/
|
*/
|
||||||
close(inout[1]);
|
close(inout[1]);
|
||||||
|
if (err[1] != -1)
|
||||||
close(err[1]);
|
close(err[1]);
|
||||||
if (dup2(inout[0], 0) < 0) /* stdin */
|
if (dup2(inout[0], 0) < 0) /* stdin */
|
||||||
perror("dup2 stdin");
|
perror("dup2 stdin");
|
||||||
|
@ -595,10 +629,6 @@ do_exec_no_pty(Session *s, const char *command)
|
||||||
close(perr[1]);
|
close(perr[1]);
|
||||||
|
|
||||||
if (compat20) {
|
if (compat20) {
|
||||||
if (s->is_subsystem) {
|
|
||||||
close(perr[0]);
|
|
||||||
perr[0] = -1;
|
|
||||||
}
|
|
||||||
session_set_fds(s, pin[1], pout[0], perr[0], 0);
|
session_set_fds(s, pin[1], pout[0], perr[0], 0);
|
||||||
} else {
|
} else {
|
||||||
/* Enter the interactive session. */
|
/* Enter the interactive session. */
|
||||||
|
@ -615,10 +645,7 @@ do_exec_no_pty(Session *s, const char *command)
|
||||||
* handle the case that fdin and fdout are the same.
|
* handle the case that fdin and fdout are the same.
|
||||||
*/
|
*/
|
||||||
if (compat20) {
|
if (compat20) {
|
||||||
session_set_fds(s, inout[1], inout[1],
|
session_set_fds(s, inout[1], inout[1], err[1], 0);
|
||||||
s->is_subsystem ? -1 : err[1], 0);
|
|
||||||
if (s->is_subsystem)
|
|
||||||
close(err[1]);
|
|
||||||
} else {
|
} else {
|
||||||
server_loop(pid, inout[1], inout[1], err[1]);
|
server_loop(pid, inout[1], inout[1], err[1]);
|
||||||
/* server_loop has closed inout[1] and err[1]. */
|
/* server_loop has closed inout[1] and err[1]. */
|
||||||
|
|
Loading…
Reference in New Issue