mirror of
https://github.com/tmux/tmux.git
synced 2025-11-24 19:06:07 +00:00
compat
asprintf.c
base64.c
bitstring.h
cfmakeraw.c
closefrom.c
daemon.c
err.c
explicit_bzero.c
fgetln.c
forkpty-aix.c
forkpty-hpux.c
forkpty-sunos.c
fparseln.c
freezero.c
getdtablecount.c
getopt.c
getprogname.c
imsg-buffer.c
imsg.c
imsg.h
queue.h
reallocarray.c
recallocarray.c
setenv.c
setproctitle.c
strcasestr.c
strlcat.c
strlcpy.c
strndup.c
strnlen.c
strsep.c
strtonum.c
tree.h
unvis.c
utf8proc.c
vis.c
vis.h
logo
presentations
tools
.gitignore
.mailmap
.travis.yml
CHANGES
CONTRIBUTING
COPYING
FAQ
ISSUE_TEMPLATE
Makefile.am
README
SYNCING
TODO
alerts.c
arguments.c
attributes.c
autogen.sh
cfg.c
client.c
cmd-attach-session.c
cmd-bind-key.c
cmd-break-pane.c
cmd-capture-pane.c
cmd-choose-buffer.c
cmd-choose-client.c
cmd-choose-tree.c
cmd-command-prompt.c
cmd-confirm-before.c
cmd-copy-mode.c
cmd-detach-client.c
cmd-display-message.c
cmd-display-panes.c
cmd-find-window.c
cmd-find.c
cmd-if-shell.c
cmd-join-pane.c
cmd-kill-pane.c
cmd-kill-server.c
cmd-kill-session.c
cmd-kill-window.c
cmd-list-buffers.c
cmd-list-clients.c
cmd-list-keys.c
cmd-list-panes.c
cmd-list-sessions.c
cmd-list-windows.c
cmd-list.c
cmd-load-buffer.c
cmd-lock-server.c
cmd-move-window.c
cmd-new-session.c
cmd-new-window.c
cmd-paste-buffer.c
cmd-pipe-pane.c
cmd-queue.c
cmd-refresh-client.c
cmd-rename-session.c
cmd-rename-window.c
cmd-resize-pane.c
cmd-respawn-pane.c
cmd-respawn-window.c
cmd-rotate-window.c
cmd-run-shell.c
cmd-save-buffer.c
cmd-select-layout.c
cmd-select-pane.c
cmd-select-window.c
cmd-send-keys.c
cmd-set-buffer.c
cmd-set-environment.c
cmd-set-hook.c
cmd-set-option.c
cmd-show-environment.c
cmd-show-messages.c
cmd-show-options.c
cmd-source-file.c
cmd-split-window.c
cmd-string.c
cmd-swap-pane.c
cmd-swap-window.c
cmd-switch-client.c
cmd-unbind-key.c
cmd-wait-for.c
cmd.c
colour.c
compat.h
configure.ac
control-notify.c
control.c
environ.c
example_tmux.conf
format.c
grid-view.c
grid.c
hooks.c
input-keys.c
input.c
job.c
key-bindings.c
key-string.c
layout-custom.c
layout-set.c
layout.c
log.c
mdoc2man.awk
names.c
notify.c
options-table.c
options.c
osdep-aix.c
osdep-cygwin.c
osdep-darwin.c
osdep-dragonfly.c
osdep-freebsd.c
osdep-hpux.c
osdep-linux.c
osdep-netbsd.c
osdep-openbsd.c
osdep-sunos.c
osdep-unknown.c
paste.c
proc.c
pty.c
resize.c
screen-redraw.c
screen-write.c
screen.c
server-client.c
server-fn.c
server.c
session.c
signal.c
status.c
style.c
tmux.1
tmux.c
tmux.h
tty-acs.c
tty-keys.c
tty-term.c
tty.c
utf8.c
window-choose.c
window-clock.c
window-copy.c
window.c
xmalloc.c
xmalloc.h
xterm-keys.c
119 lines
2.5 KiB
C
119 lines
2.5 KiB
C
/*
|
|
* Copyright (c) 2009 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 <fcntl.h>
|
|
#include <stdlib.h>
|
|
#include <stropts.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
|
|
#include "compat.h"
|
|
|
|
void fatal(const char *, ...);
|
|
void fatalx(const char *, ...);
|
|
|
|
pid_t
|
|
forkpty(int *master, unused char *name, struct termios *tio, struct winsize *ws)
|
|
{
|
|
int slave = -1, fd, pipe_fd[2];
|
|
char *path, dummy;
|
|
pid_t pid;
|
|
|
|
if (pipe(pipe_fd) == -1)
|
|
return (-1);
|
|
|
|
if ((*master = open("/dev/ptc", O_RDWR|O_NOCTTY)) == -1)
|
|
goto out;
|
|
|
|
if ((path = ttyname(*master)) == NULL)
|
|
goto out;
|
|
|
|
if (name != NULL)
|
|
strlcpy(name, path, TTY_NAME_MAX);
|
|
|
|
if ((slave = open(path, O_RDWR|O_NOCTTY)) == -1)
|
|
goto out;
|
|
|
|
switch (pid = fork()) {
|
|
case -1:
|
|
goto out;
|
|
case 0:
|
|
close(*master);
|
|
|
|
close(pipe_fd[1]);
|
|
while (read(pipe_fd[0], &dummy, 1) == -1) {
|
|
if (errno != EINTR)
|
|
break;
|
|
}
|
|
close(pipe_fd[0]);
|
|
|
|
fd = open(_PATH_TTY, O_RDWR|O_NOCTTY);
|
|
if (fd >= 0) {
|
|
ioctl(fd, TIOCNOTTY, NULL);
|
|
close(fd);
|
|
}
|
|
|
|
if (setsid() < 0)
|
|
fatal("setsid");
|
|
|
|
fd = open(_PATH_TTY, O_RDWR|O_NOCTTY);
|
|
if (fd >= 0)
|
|
fatalx("open succeeded (failed to disconnect)");
|
|
|
|
fd = open(path, O_RDWR);
|
|
if (fd < 0)
|
|
fatal("open failed");
|
|
close(fd);
|
|
|
|
fd = open("/dev/tty", O_WRONLY);
|
|
if (fd < 0)
|
|
fatal("open failed");
|
|
close(fd);
|
|
|
|
if (tio != NULL && tcsetattr(slave, TCSAFLUSH, tio) == -1)
|
|
fatal("tcsetattr failed");
|
|
if (ioctl(slave, TIOCSWINSZ, ws) == -1)
|
|
fatal("ioctl failed");
|
|
|
|
dup2(slave, 0);
|
|
dup2(slave, 1);
|
|
dup2(slave, 2);
|
|
if (slave > 2)
|
|
close(slave);
|
|
|
|
return (0);
|
|
}
|
|
|
|
close(slave);
|
|
|
|
close(pipe_fd[0]);
|
|
close(pipe_fd[1]);
|
|
return (pid);
|
|
|
|
out:
|
|
if (*master != -1)
|
|
close(*master);
|
|
if (slave != -1)
|
|
close(slave);
|
|
|
|
close(pipe_fd[0]);
|
|
close(pipe_fd[1]);
|
|
return (-1);
|
|
}
|