diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | client.c | 2 | ||||
-rw-r--r-- | pty.c | 67 | ||||
-rw-r--r-- | tmux.c | 3 | ||||
-rw-r--r-- | tmux.h | 5 | ||||
-rw-r--r-- | window.c | 2 |
6 files changed, 79 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am index 0d95873c..cc165bea 100644 --- a/Makefile.am +++ b/Makefile.am @@ -165,6 +165,7 @@ dist_tmux_SOURCES = \ options.c \ paste.c \ proc.c \ + pty.c \ resize.c \ screen-redraw.c \ screen-write.c \ @@ -304,6 +304,8 @@ client_main(struct event_base *base, int argc, char **argv, int flags, #endif /* Free stuff that is not used in the client. */ + if (ptm_fd != -1) + close(ptm_fd); options_free(global_options); options_free(global_s_options); options_free(global_w_options); @@ -0,0 +1,67 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/tty.h> + +#include <fcntl.h> +#include <string.h> +#include <termios.h> +#include <unistd.h> +#include <util.h> + +int pty_open(int *); +pid_t pty_fork(int, int *, char *, size_t, struct winsize *); + +int +pty_open(int *fd) +{ + *fd = open(PATH_PTMDEV, O_RDWR|O_CLOEXEC); + if (*fd < 0) + return (-1); + return (0); +} + +pid_t +pty_fork(int ptmfd, int *fd, char *name, size_t namelen, struct winsize *ws) +{ + struct ptmget ptm; + pid_t pid; + + if ((ioctl(ptmfd, PTMGET, &ptm) == -1)) + return (-1); + + strlcpy(name, ptm.sn, namelen); + ioctl(ptm.sfd, TIOCSWINSZ, ws); + + switch (pid = fork()) { + case -1: + close(ptm.cfd); + close(ptm.sfd); + return (-1); + case 0: + close(ptm.cfd); + login_tty(ptm.sfd); + return (0); + } + *fd = ptm.cfd; + close(ptm.sfd); + return (pid); +} @@ -42,6 +42,7 @@ struct hooks *global_hooks; struct timeval start_time; const char *socket_path; +int ptm_fd = -1; static __dead void usage(void); static char *make_label(const char *); @@ -261,6 +262,8 @@ main(int argc, char **argv) usage(); #ifdef __OpenBSD__ + if (pty_open(&ptm_fd) != 0) + errx(1, "open(\"/dev/ptm\""); if (pledge("stdio rpath wpath cpath flock fattr unix getpw sendfd " "recvfd proc exec tty ps", NULL) != 0) err(1, "pledge"); @@ -1503,6 +1503,7 @@ extern struct options *global_w_options; extern struct environ *global_environ; extern struct timeval start_time; extern const char *socket_path; +extern int ptm_fd; int areshell(const char *); void setblocking(int, int); const char *find_home(void); @@ -2333,4 +2334,8 @@ void style_apply_update(struct grid_cell *, struct options *, int style_equal(const struct grid_cell *, const struct grid_cell *); +/* pty.c */ +int pty_open(int *); +pid_t pty_fork(int, int *, char *, size_t, struct winsize *); + #endif /* TMUX_H */ @@ -892,7 +892,7 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv, ws.ws_col = screen_size_x(&wp->base); ws.ws_row = screen_size_y(&wp->base); - switch (wp->pid = forkpty(&wp->fd, wp->tty, NULL, &ws)) { + switch (wp->pid = pty_fork(ptm_fd, &wp->fd, wp->tty, sizeof wp->tty, &ws)) { case -1: wp->fd = -1; xasprintf(cause, "%s: %s", cmd, strerror(errno)); |