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.