2 * pty.c - pseudo-terminal handling
16 #include <sys/ioctl.h>
17 #include <sys/types.h>
23 static char ptyname[FILENAME_MAX];
26 void pty_preinit(void)
31 master = open("/dev/ptmx", O_RDWR);
33 perror("/dev/ptmx: open");
37 if (grantpt(master) < 0) {
42 if (unlockpt(master) < 0) {
48 void pty_resize(int w, int h)
56 sz.ws_xpixel = sz.ws_ypixel = 0;
57 ioctl(master, TIOCSWINSZ, &sz);
60 int run_program_in_pty(const struct shell_data *shdata,
61 char *directory, char **program_args)
64 char *fallback_args[2];
68 ptyname[FILENAME_MAX-1] = '\0';
69 strncpy(ptyname, ptsname(master), FILENAME_MAX-1);
77 * FIXME: think up some good defaults here
80 if (!ioctl(0, TIOCGWINSZ, &ws))
81 ioctl(master, TIOCSWINSZ, &ws);
82 if (!tcgetattr(0, &ts))
83 tcsetattr(master, TCSANOW, &ts);
87 slave = open(ptyname, O_RDWR | O_NOCTTY);
89 perror("slave pty: open");
94 * Fork and execute the command.
110 fcntl(slave, F_SETFD, 0); /* don't close on exec */
113 if (slave != 0 && slave != 1)
120 if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
121 ioctl(fd, TIOCNOTTY, &i);
126 ioctl(0, TIOCSCTTY, &i);
128 tcsetpgrp(0, getpgrp());
130 for (i = 0; i < shdata->nenvvars; i++)
131 putenv(shdata->envvars[i]);
132 if (shdata->termtype)
133 putenv(shdata->termtype);
139 * Use the provided shell program name, if the user gave
140 * one. Failing that, use $SHELL; failing that, look up
141 * the user's default shell in the password file; failing
142 * _that_, revert to the bog-standard /bin/sh.
147 shell = getenv("SHELL");
154 * For maximum generality in the face of multiple
155 * /etc/passwd entries with different login names and
156 * shells but a shared uid, we start by using
157 * getpwnam(getlogin()) if it's available - but we
158 * insist that its uid must match our real one, or we
159 * give up and fall back to getpwuid(getuid()).
163 if (login && (pwd = getpwnam(login)) && pwd->pw_uid == uid)
164 shell = pwd->pw_shell;
165 else if ((pwd = getpwuid(uid)))
166 shell = pwd->pw_shell;
171 fallback_args[0] = shell;
172 fallback_args[1] = NULL;
173 program_args = fallback_args;
176 execv(program_args[0], program_args);
179 * If we're here, exec has gone badly foom.