34
37
#include <signal.h>
40
#ifdef HAVE_WORKING_POLL
42
44
#include <sys/poll.h>
46
#ifdef HAVE_SYS_SELECT_H
47
# include <sys/select.h>
50
#if !(defined(_MINIX) || defined(__BEOS__))
51
#define HAVE_WORKING_SELECT 1
55
#ifdef HAVE_WORKING_SELECT
56
#if defined(HAVE_SYS_SELECT_H) && defined(HAVE_SYS_TIME_SELECT)
57
#include <sys/select.h>
54
65
#ifdef HAVE_STROPTS_H
58
#ifdef HAVE_SYS_PARAM_H
59
# include <sys/param.h>
70
#include <sys/param.h>
74
#if defined(HAVE_UTIL_H)
76
#elif defined(HAVE_LIBUTIL_H)
78
#elif defined(HAVE_PTY_H)
81
#endif /* HAVE_OPENPTY */
89
#if defined(HAVE_OPENPTY)
90
static int opened_tty = -1;
64
93
static int saved_tio_valid = 0;
65
94
static struct termios saved_tio;
70
97
waitForOutput(int fd)
101
#if defined(HAVE_WORKING_POLL)
72
102
struct pollfd pfd[1];
77
107
pfd[0].revents = 0;
79
109
rc = poll(pfd, 1, -1);
83
if(pfd[0].revents & POLLOUT)
112
else if (pfd[0].revents & (POLLOUT | POLLERR | POLLHUP))
115
#elif defined(HAVE_WORKING_SELECT)
121
rc = select(FD_SETSIZE, NULL, &fds, NULL, NULL);
124
else if (FD_ISSET(fd, &fds))
90
135
waitForInput(int fd1, int fd2)
139
#if defined(HAVE_WORKING_POLL)
92
140
struct pollfd pfd[2];
98
146
pfd[0].revents = pfd[1].revents = 0;
100
148
rc = poll(pfd, 2, -1);
105
if(pfd[0].revents & (POLLIN | POLLERR | POLLHUP))
107
if(pfd[1].revents & (POLLIN | POLLERR | POLLHUP))
115
waitForOutput(int fd)
152
if (pfd[0].revents & (POLLIN | POLLERR | POLLHUP))
154
if (pfd[1].revents & (POLLIN | POLLERR | POLLHUP))
158
#elif defined(HAVE_WORKING_SELECT)
122
rc = select(FD_SETSIZE, NULL, &fds, NULL, NULL);
126
if(FD_ISSET(fd, &fds))
133
waitForInput(int fd1, int fd2)
139
163
FD_SET(fd1, &fds);
140
164
FD_SET(fd2, &fds);
141
165
rc = select(FD_SETSIZE, &fds, NULL, NULL, NULL);
169
if (FD_ISSET(fd1, &fds))
171
if (FD_ISSET(fd2, &fds))
146
if(FD_ISSET(fd1, &fds))
148
if(FD_ISSET(fd2, &fds))
156
/* Busy looping implementation */
158
waitForOutput(int fd)
164
waitForInput(int fd1, int fd2)
173
182
setWindowSize(int sfd, int dfd)
175
184
#ifdef TIOCGWINSZ
177
186
struct winsize ws;
178
rc = ioctl(sfd, TIOCGWINSZ, (char*)&ws);
181
rc = ioctl(dfd, TIOCSWINSZ, (char*)&ws);
187
rc = ioctl(sfd, TIOCGWINSZ, (char *) &ws);
190
rc = ioctl(dfd, TIOCSWINSZ, (char *) &ws);
189
installHandler(int signum, void (*handler)(int))
198
installHandler(int signum, void (*handler) (int))
191
200
struct sigaction sa;
242
251
struct termios tio;
254
if (!saved_tio_valid)
247
256
rc = tcgetattr(0, &tio);
250
tio.c_lflag &= ~(ECHO|ICANON|ISIG);
251
tio.c_iflag &= ~(ICRNL|IXOFF|IXON|ISTRIP);
259
tio.c_lflag &= (unsigned) ~(ECHO | ICANON | ISIG);
260
tio.c_iflag &= (unsigned) ~(ICRNL | IXOFF | IXON | ISTRIP);
253
tio.c_oflag &= ~ONLCR;
262
tio.c_oflag &= (unsigned) ~ONLCR;
256
tio.c_oflag &= ~OCRNL;
265
tio.c_oflag &= (unsigned) ~OCRNL;
259
tio.c_oflag &= ~ONOCR;
268
tio.c_oflag &= (unsigned) ~ONOCR;
291
int uid = getuid(), gid = getgid();
293
300
rc = stat(line, &s);
296
if(s.st_uid != uid || s.st_gid != gid) {
297
rc = chown(line, getuid(), getgid());
300
"Warning: could not change ownership of tty -- "
301
"pty is insecure!\n");
303
if (s.st_uid != getuid() || s.st_gid != getgid()) {
304
rc = chown(line, getuid(), getgid());
307
"Warning: could not change ownership of tty -- "
308
"pty is insecure!\n");
305
if((s.st_mode & 0777) != (S_IRUSR | S_IWUSR | S_IWGRP)) {
306
rc = chmod(line, S_IRUSR | S_IWUSR | S_IWGRP);
309
"Warning: could not change permissions of tty -- "
310
"pty is insecure!\n");
312
if ((s.st_mode & 0777) != (S_IRUSR | S_IWUSR | S_IWGRP)) {
313
rc = chmod(line, S_IRUSR | S_IWUSR | S_IWGRP);
316
"Warning: could not change permissions of tty -- "
317
"pty is insecure!\n");
320
327
char name[12], *line = NULL;
322
char *name1 = "pqrstuvwxyzPQRST",
323
*name2 = "0123456789abcdefghijklmnopqrstuv";
329
const char *name1 = "pqrstuvwxyzPQRST";
331
char *name2 = strcpy(buffer, "0123456789abcdefghijklmnopqrstuv");
335
#if defined(HAVE_GRANTPT)
331
pty = posix_openpt(O_RDWR);
333
338
pty = open("/dev/ptmx", O_RDWR);
339
342
rc = grantpt(pty);
345
348
rc = unlockpt(pty);
351
temp_line = ptsname(pty);
356
line = strdup(temp_line);
369
#endif /* HAVE_GRANTPT */
354
line = strmalloc(ptsname(pty));
367
#elif defined(HAVE_OPENPTY)
369
char ttydev[80]; /* OpenBSD says at least 16 bytes */
371
rc = openpty(&pty, &opened_tty, ttydev, NULL, NULL);
376
line = strmalloc(ttydev);
389
#endif /* HAVE_GRANTPT, etc */
371
391
strcpy(name, "/dev/pty??");
372
for(p1 = name1; *p1; p1++) {
374
for(p2 = name2; *p2; p2++) {
376
pty = open(name, O_RDWR);
379
/* Systems derived from 4.4BSD differ in their pty names,
380
so ENOENT doesn't necessarily imply we're done. */
392
for (p1 = name1; *p1; p1++) {
394
for (p2 = name2; *p2; p2++) {
396
pty = open(name, O_RDWR);
399
/* Systems derived from 4.4BSD differ in their pty names,
400
so ENOENT doesn't necessarily imply we're done. */
408
if ((line = strmalloc(name)) != 0) {
411
#if !defined(O_NOCTTY) || !defined(TIOCSCTTY)
412
/* e.g. Cygwin has a working O_NOCTTY but no TIOCSCTTY, so the tty
413
must be opened as controlling */
414
tty = open(line, O_RDWR);
416
/* The TIOCSCTTY ioctl below will fail if the process already has a
417
controlling tty (even if the current controlling tty is the same
418
as the tty you want to make controlling). So we need to open
419
the tty with O_NOCTTY to make sure this doesn't happen. */
420
tty = open(line, O_RDWR | O_NOCTTY);
430
tty = open(line, O_RDWR
431
#if defined(TIOCSCTTY) && defined(O_NOCTTY)
433
* Do not make this our controlling terminal, yet just in case it fails
434
* in some intermediate state. But do not add this flag if we haven't
435
* the corresponding ioctl.
444
#if defined(HAVE_OPENPTY)
445
if (opened_tty >= 0) {
427
rc = ioctl(tty, TIOCSCTTY, (char *)0);
453
* Now that we've successfully opened the terminal, make it the controlling
454
* terminal. This call works only if the process does not already have a
455
* controlling terminal.
457
* Cygwin as of 2009/10/12 lacks this call, but has O_NOCTTY.
459
rc = ioctl(tty, TIOCSCTTY, (char *) 0);
433
#if defined(SVR4) || defined(__SVR4)
465
#if defined(I_PUSH) && (defined(SVR4) || defined(__SVR4))
434
466
rc = ioctl(tty, I_PUSH, "ptem");
438
470
rc = ioctl(tty, I_PUSH, "ldterm");
442
474
rc = ioctl(tty, I_PUSH, "ttcompat");
455
487
/* Post-4.4 BSD systems have POSIX semantics (_POSIX_SAVED_IDS
456
488
or not, depending on the version). 4.3BSD and Minix do not have
457
489
saved IDs at all, so there's no issue. */
458
494
#if (defined(BSD) && !defined(_POSIX_SAVED_IDS)) || defined(_MINIX)
463
495
rc = setuid(getuid());
466
return setgid(getgid());
497
rc = setgid(getgid());
468
499
#elif defined(_POSIX_SAVED_IDS)
473
int euid = geteuid();
475
int egid = getegid();
478
if((uid != euid || gid != egid) && euid != 0) {
492
int euid = geteuid();
494
int egid = getegid();
496
if(uid != euid || gid != egid) {
500
uid_t uid = getuid();
501
uid_t euid = geteuid();
502
gid_t gid = getgid();
503
gid_t egid = getegid();
505
if ((uid != euid || gid != egid) && euid != 0) {
514
uid_t uid = getuid();
515
uid_t euid = geteuid();
516
gid_t gid = getgid();
517
gid_t egid = getegid();
519
if (uid != euid || gid != egid) {
530
strmalloc(const char *value)
536
result = strdup(value);
538
result = malloc(strlen(value) + 1);
540
strcpy(result, value);
548
ExitProgram(int code)