1 #include "ruby/config.h"
3 #include RUBY_EXTCONF_H
13 #ifdef HAVE_SYS_IOCTL_H
14 #include <sys/ioctl.h>
25 #ifdef HAVE_SYS_WAIT_H
28 #define WIFSTOPPED(status) (((status) & 0xff) == 0x7f)
37 #ifdef HAVE_SYS_STROPTS_H
38 #include <sys/stropts.h>
47 #if !defined(HAVE_OPENPTY)
53 "p0",
"p1",
"p2",
"p3",
"p4",
"p5",
"p6",
"p7",
54 "p8",
"p9",
"pa",
"pb",
"pc",
"pd",
"pe",
"pf",
55 "q0",
"q1",
"q2",
"q3",
"q4",
"q5",
"q6",
"q7",
56 "q8",
"q9",
"qa",
"qb",
"qc",
"qd",
"qe",
"qf",
57 "r0",
"r1",
"r2",
"r3",
"r4",
"r5",
"r6",
"r7",
58 "r8",
"r9",
"ra",
"rb",
"rc",
"rd",
"re",
"rf",
59 "s0",
"s1",
"s2",
"s3",
"s4",
"s5",
"s6",
"s7",
60 "s8",
"s9",
"sa",
"sb",
"sc",
"sd",
"se",
"sf",
61 "t0",
"t1",
"t2",
"t3",
"t4",
"t5",
"t6",
"t7",
62 "t8",
"t9",
"ta",
"tb",
"tc",
"td",
"te",
"tf",
63 "u0",
"u1",
"u2",
"u3",
"u4",
"u5",
"u6",
"u7",
64 "u8",
"u9",
"ua",
"ub",
"uc",
"ud",
"ue",
"uf",
65 "v0",
"v1",
"v2",
"v3",
"v4",
"v5",
"v6",
"v7",
66 "v8",
"v9",
"va",
"vb",
"vc",
"vd",
"ve",
"vf",
67 "w0",
"w1",
"w2",
"w3",
"w4",
"w5",
"w6",
"w7",
68 "w8",
"w9",
"wa",
"wb",
"wc",
"wd",
"we",
"wf",
71 #elif defined(_IBMESA)
76 "00",
"01",
"02",
"03",
"04",
"05",
"06",
"07",
"08",
"09",
"0a",
"0b",
"0c",
"0d",
"0e",
"0f",
77 "10",
"11",
"12",
"13",
"14",
"15",
"16",
"17",
"18",
"19",
"1a",
"1b",
"1c",
"1d",
"1e",
"1f",
78 "20",
"21",
"22",
"23",
"24",
"25",
"26",
"27",
"28",
"29",
"2a",
"2b",
"2c",
"2d",
"2e",
"2f",
79 "30",
"31",
"32",
"33",
"34",
"35",
"36",
"37",
"38",
"39",
"3a",
"3b",
"3c",
"3d",
"3e",
"3f",
80 "40",
"41",
"42",
"43",
"44",
"45",
"46",
"47",
"48",
"49",
"4a",
"4b",
"4c",
"4d",
"4e",
"4f",
81 "50",
"51",
"52",
"53",
"54",
"55",
"56",
"57",
"58",
"59",
"5a",
"5b",
"5c",
"5d",
"5e",
"5f",
82 "60",
"61",
"62",
"63",
"64",
"65",
"66",
"67",
"68",
"69",
"6a",
"6b",
"6c",
"6d",
"6e",
"6f",
83 "70",
"71",
"72",
"73",
"74",
"75",
"76",
"77",
"78",
"79",
"7a",
"7b",
"7c",
"7d",
"7e",
"7f",
84 "80",
"81",
"82",
"83",
"84",
"85",
"86",
"87",
"88",
"89",
"8a",
"8b",
"8c",
"8d",
"8e",
"8f",
85 "90",
"91",
"92",
"93",
"94",
"95",
"96",
"97",
"98",
"99",
"9a",
"9b",
"9c",
"9d",
"9e",
"9f",
86 "a0",
"a1",
"a2",
"a3",
"a4",
"a5",
"a6",
"a7",
"a8",
"a9",
"aa",
"ab",
"ac",
"ad",
"ae",
"af",
87 "b0",
"b1",
"b2",
"b3",
"b4",
"b5",
"b6",
"b7",
"b8",
"b9",
"ba",
"bb",
"bc",
"bd",
"be",
"bf",
88 "c0",
"c1",
"c2",
"c3",
"c4",
"c5",
"c6",
"c7",
"c8",
"c9",
"ca",
"cb",
"cc",
"cd",
"ce",
"cf",
89 "d0",
"d1",
"d2",
"d3",
"d4",
"d5",
"d6",
"d7",
"d8",
"d9",
"da",
"db",
"dc",
"dd",
"de",
"df",
90 "e0",
"e1",
"e2",
"e3",
"e4",
"e5",
"e6",
"e7",
"e8",
"e9",
"ea",
"eb",
"ec",
"ed",
"ee",
"ef",
91 "f0",
"f1",
"f2",
"f3",
"f4",
"f5",
"f6",
"f7",
"f8",
"f9",
"fa",
"fb",
"fc",
"fd",
"fe",
"ff",
93 #elif !defined(HAVE_PTSNAME)
98 "p0",
"p1",
"p2",
"p3",
"p4",
"p5",
"p6",
"p7",
99 "p8",
"p9",
"pa",
"pb",
"pc",
"pd",
"pe",
"pf",
100 "q0",
"q1",
"q2",
"q3",
"q4",
"q5",
"q6",
"q7",
101 "q8",
"q9",
"qa",
"qb",
"qc",
"qd",
"qe",
"qf",
102 "r0",
"r1",
"r2",
"r3",
"r4",
"r5",
"r6",
"r7",
103 "r8",
"r9",
"ra",
"rb",
"rc",
"rd",
"re",
"rf",
104 "s0",
"s1",
"s2",
"s3",
"s4",
"s5",
"s6",
"s7",
105 "s8",
"s9",
"sa",
"sb",
"sc",
"sd",
"se",
"sf",
112 # ifdef HAVE_SETREUID
113 # define seteuid(e) setreuid(-1, (e))
115 # ifdef HAVE_SETRESUID
116 # define seteuid(e) setresuid(-1, (e), -1)
149 chfunc(
void *data,
char *errbuf,
size_t errbuf_len)
157 #define ERROR_EXIT(str) do { \
158 strlcpy(errbuf, (str), errbuf_len); \
175 if (setpgrp(0, getpid()) == -1)
178 int i = open(
"/dev/tty", O_RDONLY);
181 if (
ioctl(i, TIOCNOTTY, (
char *)0))
192 #if defined(TIOCSCTTY)
194 (void)
ioctl(slave, TIOCSCTTY, (
char *)0);
209 #if defined(HAVE_SETEUID) || defined(HAVE_SETREUID) || defined(HAVE_SETRESUID)
225 struct passwd *pwent;
231 const char *shellname;
237 pwent = getpwuid(
getuid());
238 if (pwent && pwent->pw_shell)
239 shellname = pwent->pw_shell;
241 shellname =
"/bin/sh";
248 getDevice(&master, &slave, SlaveName, 0);
276 return chmod(slavedevice, 0600);
284 #if defined(HAVE_POSIX_OPENPT)
285 int masterfd = -1, slavefd = -1;
287 struct sigaction dfl, old;
289 dfl.sa_handler = SIG_DFL;
291 sigemptyset(&dfl.sa_mask);
293 if ((masterfd = posix_openpt(O_RDWR|O_NOCTTY)) == -1)
goto error;
295 if (sigaction(SIGCHLD, &dfl, &old) == -1)
goto error;
296 if (grantpt(masterfd) == -1)
goto grantpt_error;
297 if (sigaction(SIGCHLD, &old,
NULL) == -1)
goto error;
298 if (unlockpt(masterfd) == -1)
goto error;
299 if ((slavedevice = ptsname(masterfd)) ==
NULL)
goto error;
300 if (
no_mesg(slavedevice, nomesg) == -1)
goto error;
301 if ((slavefd = open(slavedevice, O_RDWR|O_NOCTTY, 0)) == -1)
goto error;
304 #if defined I_PUSH && !defined linux
305 if (
ioctl(slavefd, I_PUSH,
"ptem") == -1)
goto error;
306 if (
ioctl(slavefd, I_PUSH,
"ldterm") == -1)
goto error;
307 if (
ioctl(slavefd, I_PUSH,
"ttcompat") == -1)
goto error;
312 strlcpy(SlaveName, slavedevice, DEVICELEN);
316 sigaction(SIGCHLD, &old,
NULL);
318 if (slavefd != -1) close(slavefd);
319 if (masterfd != -1) close(masterfd);
324 #elif defined HAVE_OPENPTY
329 if (openpty(master, slave, SlaveName,
330 (
struct termios *)0, (
struct winsize *)0) == -1) {
331 if (!fail)
return -1;
336 if (
no_mesg(SlaveName, nomesg) == -1) {
337 if (!fail)
return -1;
343 #elif defined HAVE__GETPTY
345 mode_t mode = nomesg ? 0600 : 0622;
347 if (!(name = _getpty(master, O_RDWR, mode, 0))) {
348 if (!fail)
return -1;
353 *slave = open(name, O_RDWR);
356 strlcpy(SlaveName, name, DEVICELEN);
359 #elif defined(HAVE_PTSNAME)
360 int masterfd = -1, slavefd = -1;
364 extern char *ptsname(
int);
365 extern int unlockpt(
int);
366 extern int grantpt(
int);
368 if((masterfd = open(
"/dev/ptmx", O_RDWR, 0)) == -1)
goto error;
370 s =
signal(SIGCHLD, SIG_DFL);
371 if(grantpt(masterfd) == -1)
goto error;
373 if(unlockpt(masterfd) == -1)
goto error;
374 if((slavedevice = ptsname(masterfd)) ==
NULL)
goto error;
375 if (
no_mesg(slavedevice, nomesg) == -1)
goto error;
376 if((slavefd = open(slavedevice, O_RDWR, 0)) == -1)
goto error;
378 #if defined I_PUSH && !defined linux
379 if(
ioctl(slavefd, I_PUSH,
"ptem") == -1)
goto error;
380 if(
ioctl(slavefd, I_PUSH,
"ldterm") == -1)
goto error;
381 ioctl(slavefd, I_PUSH,
"ttcompat");
385 strlcpy(SlaveName, slavedevice, DEVICELEN);
389 if (slavefd != -1) close(slavefd);
390 if (masterfd != -1) close(masterfd);
394 int masterfd = -1, slavefd = -1;
395 const char *
const *
p;
400 if ((masterfd = open(MasterName,O_RDWR,0)) >= 0) {
404 if ((slavefd = open(SlaveName,O_RDWR,0)) >= 0) {
408 if (chmod(SlaveName, nomesg ? 0600 : 0622) != 0)
goto error;
415 if (slavefd != -1) close(slavefd);
416 if (masterfd != -1) close(masterfd);
437 for (i = 0; i < 2; i++) {
505 int master_fd, slave_fd;
507 VALUE master_io, slave_file;
508 rb_io_t *master_fptr, *slave_fptr;
511 getDevice(&master_fd, &slave_fd, slavename, 1);
516 master_fptr->
fd = master_fd;
522 slave_fptr->
fd = slave_fd;
590 wfptr->fd = dup(info.
fd);
594 wfptr->pathv = rfptr->pathv;
615 #if defined(WIFSTOPPED)
616 #elif defined(IF_STOPPED)
617 #define WIFSTOPPED(status) IF_STOPPED(status)
619 ---->> Either IF_STOPPED or
WIFSTOPPED is needed <<----
624 else if (
kill(pid, 0) == 0) {
630 snprintf(buf,
sizeof(buf),
"pty - %s: %ld", state, (
long)pid);
661 if (cpid == -1 || cpid == 0)
return Qnil;