int master_fd, slave_fd;
void *frontend;
char name[FILENAME_MAX];
- int child_pid;
+ pid_t child_pid;
int term_width, term_height;
int child_dead, finished;
int exit_code;
static int pty_find_by_pid(void *av, void *bv)
{
- int a = *(int *)av;
+ pid_t a = *(pid_t *)av;
Pty b = (Pty)bv;
if (a < b->child_pid)
static Pty single_pty = NULL;
#ifndef OMIT_UTMP
-static int pty_utmp_helper_pid, pty_utmp_helper_pipe;
+static pid_t pty_utmp_helper_pid;
+static int pty_utmp_helper_pipe;
static int pty_stamped_utmp;
static struct utmpx utmp_entry;
#endif
static void sigchld_handler(int signum)
{
- write(pty_signal_pipe[1], "x", 1);
+ if (write(pty_signal_pipe[1], "x", 1) <= 0)
+ /* not much we can do about it */;
}
#ifndef OMIT_UTMP
{
if (pty->slave_fd < 0) {
pty->slave_fd = open(pty->name, O_RDWR);
- fcntl(pty->slave_fd, F_SETFD, FD_CLOEXEC);
+ cloexec(pty->slave_fd);
}
return pty->slave_fd;
strcpy(pty->name, master_name);
pty->name[5] = 't'; /* /dev/ptyXX -> /dev/ttyXX */
- fcntl(pty->master_fd, F_SETFD, FD_CLOEXEC);
+ cloexec(pty->master_fd);
if (pty_open_slave(pty) >= 0 &&
access(pty->name, R_OK | W_OK) == 0)
exit(1);
}
- fcntl(pty->master_fd, F_SETFD, FD_CLOEXEC);
+ cloexec(pty->master_fd);
pty->name[FILENAME_MAX-1] = '\0';
strncpy(pty->name, ptsname(pty->master_fd), FILENAME_MAX-1);
/*
* Set the pty master into non-blocking mode.
*/
- int i = 1;
- ioctl(pty->master_fd, FIONBIO, &i);
+ int fl;
+ fl = fcntl(pty->master_fd, F_GETFL);
+ if (fl != -1 && !(fl & O_NONBLOCK))
+ fcntl(pty->master_fd, F_SETFL, fl | O_NONBLOCK);
}
if (!ptys_by_fd)
perror("pterm: pipe");
exit(1);
}
+ cloexec(pipefd[0]);
+ cloexec(pipefd[1]);
pid = fork();
if (pid < 0) {
perror("pterm: fork");
if (fd == pty_signal_pipe[0]) {
pid_t pid;
- int ipid;
int status;
char c[1];
- read(pty_signal_pipe[0], c, 1); /* ignore its value; it'll be `x' */
+ if (read(pty_signal_pipe[0], c, 1) <= 0)
+ /* ignore error */;
+ /* ignore its value; it'll be `x' */
do {
pid = waitpid(-1, &status, WNOHANG);
- ipid = pid;
pty = find234(ptys_by_pid, &pid, pty_find_by_pid);
if (pty)
}
if (pid == 0) {
- int i;
/*
* We are the child.
*/
dup2(slavefd, 0);
dup2(slavefd, 1);
dup2(slavefd, 2);
+ close(slavefd);
setsid();
#ifdef TIOCSCTTY
- ioctl(slavefd, TIOCSCTTY, 1);
+ ioctl(0, TIOCSCTTY, 1);
#endif
pgrp = getpid();
- tcsetpgrp(slavefd, pgrp);
+ tcsetpgrp(0, pgrp);
setpgid(pgrp, pgrp);
close(open(pty->name, O_WRONLY, 0));
setpgid(pgrp, pgrp);
- /* Close everything _else_, for tidiness. */
- for (i = 3; i < 1024; i++)
- close(i);
{
char *term_env_var = dupprintf("TERM=%s", cfg->termtype);
putenv(term_env_var);
}
/*
- * SIGINT and SIGQUIT may have been set to ignored by our
- * parent, particularly by things like sh -c 'pterm &' and
- * some window managers. SIGCHLD, meanwhile, was blocked
- * during pt_main() startup. Reverse all this for our child
- * process.
+ * SIGINT, SIGQUIT and SIGPIPE may have been set to ignored by
+ * our parent, particularly by things like sh -c 'pterm &' and
+ * some window or session managers. SIGCHLD, meanwhile, was
+ * blocked during pt_main() startup. Reverse all this for our
+ * child process.
*/
putty_signal(SIGINT, SIG_DFL);
putty_signal(SIGQUIT, SIG_DFL);
+ putty_signal(SIGPIPE, SIG_DFL);
block_signal(SIGCHLD, 0);
if (pty_argv)
execvp(pty_argv[0], pty_argv);
add234(ptys_by_pid, pty);
}
- if (pty_signal_pipe[0] < 0 && pipe(pty_signal_pipe) < 0) {
- perror("pipe");
- exit(1);
+ if (pty_signal_pipe[0] < 0) {
+ if (pipe(pty_signal_pipe) < 0) {
+ perror("pipe");
+ exit(1);
+ }
+ cloexec(pty_signal_pipe[0]);
+ cloexec(pty_signal_pipe[1]);
}
pty_uxsel_setup(pty);
pty_provide_logctx,
pty_unthrottle,
pty_cfg_info,
- 1
+ "pty",
+ -1,
+ 0
};