mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/pty/pty.c (getDevice): add nomesg argument.
(get_device_once): add nomesg argument. chmod slave tty to 0600 if nomesg. more error tests. (no_mesg): new function. (pty_open): make slave tty's mode 0600. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20795 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
3ea21e47c1
commit
e27fbfbc98
3 changed files with 90 additions and 80 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
Tue Dec 16 20:34:44 2008 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* ext/pty/pty.c (getDevice): add nomesg argument.
|
||||||
|
(get_device_once): add nomesg argument. chmod slave tty to 0600
|
||||||
|
if nomesg. more error tests.
|
||||||
|
(no_mesg): new function.
|
||||||
|
(pty_open): make slave tty's mode 0600.
|
||||||
|
|
||||||
Tue Dec 16 20:24:20 2008 Tadayoshi Funaba <tadf@dotrb.org>
|
Tue Dec 16 20:24:20 2008 Tadayoshi Funaba <tadf@dotrb.org>
|
||||||
|
|
||||||
* lib/date/format.rb (_parse): m17n compliant.
|
* lib/date/format.rb (_parse): m17n compliant.
|
||||||
|
|
148
ext/pty/pty.c
148
ext/pty/pty.c
|
@ -130,7 +130,7 @@ struct pty_info {
|
||||||
rb_pid_t child_pid;
|
rb_pid_t child_pid;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void getDevice(int*, int*, char [DEVICELEN]);
|
static void getDevice(int*, int*, char [DEVICELEN], int);
|
||||||
|
|
||||||
struct exec_info {
|
struct exec_info {
|
||||||
int argc;
|
int argc;
|
||||||
|
@ -248,7 +248,7 @@ establishShell(int argc, VALUE *argv, struct pty_info *info,
|
||||||
argv = &v;
|
argv = &v;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDevice(&master, &slave, SlaveName);
|
getDevice(&master, &slave, SlaveName, 0);
|
||||||
|
|
||||||
carg.master = master;
|
carg.master = master;
|
||||||
carg.slave = slave;
|
carg.slave = slave;
|
||||||
|
@ -271,10 +271,19 @@ establishShell(int argc, VALUE *argv, struct pty_info *info,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int fail)
|
no_mesg(char *slavedevice, int nomesg)
|
||||||
|
{
|
||||||
|
if (nomesg)
|
||||||
|
return chmod(slavedevice, 0600);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg, int fail)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_POSIX_OPENPT)
|
#if defined(HAVE_POSIX_OPENPT)
|
||||||
int masterfd,slavefd;
|
int masterfd = -1, slavefd = -1;
|
||||||
char *slavedevice;
|
char *slavedevice;
|
||||||
struct sigaction dfl, old;
|
struct sigaction dfl, old;
|
||||||
|
|
||||||
|
@ -282,33 +291,34 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int fail)
|
||||||
dfl.sa_flags = 0;
|
dfl.sa_flags = 0;
|
||||||
sigemptyset(&dfl.sa_mask);
|
sigemptyset(&dfl.sa_mask);
|
||||||
|
|
||||||
if((masterfd = posix_openpt(O_RDWR|O_NOCTTY)) != -1) {
|
if ((masterfd = posix_openpt(O_RDWR|O_NOCTTY)) == -1) goto error;
|
||||||
sigaction(SIGCHLD, &dfl, &old);
|
if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error;
|
||||||
if(grantpt(masterfd) != -1) {
|
if (grantpt(masterfd) == -1) goto grantpt_error;
|
||||||
sigaction(SIGCHLD, &old, NULL);
|
if (sigaction(SIGCHLD, &old, NULL) == -1) goto error;
|
||||||
if(unlockpt(masterfd) != -1) {
|
if (unlockpt(masterfd) == -1) goto error;
|
||||||
if((slavedevice = ptsname(masterfd)) != NULL) {
|
if ((slavedevice = ptsname(masterfd)) == NULL) goto error;
|
||||||
if((slavefd = open(slavedevice, O_RDWR|O_NOCTTY, 0)) != -1) {
|
if (no_mesg(slavedevice, nomesg) == -1) goto error;
|
||||||
|
if ((slavefd = open(slavedevice, O_RDWR|O_NOCTTY, 0)) == -1) goto error;
|
||||||
|
|
||||||
#if defined I_PUSH && !defined linux
|
#if defined I_PUSH && !defined linux
|
||||||
if(ioctl(slavefd, I_PUSH, "ptem") != -1) {
|
if (ioctl(slavefd, I_PUSH, "ptem") == -1) goto error;
|
||||||
if(ioctl(slavefd, I_PUSH, "ldterm") != -1) {
|
if (ioctl(slavefd, I_PUSH, "ldterm") == -1) goto error;
|
||||||
ioctl(slavefd, I_PUSH, "ttcompat");
|
if (ioctl(slavefd, I_PUSH, "ttcompat") == -1) goto error;
|
||||||
#endif
|
#endif
|
||||||
*master = masterfd;
|
|
||||||
*slave = slavefd;
|
*master = masterfd;
|
||||||
strlcpy(SlaveName, slavedevice, DEVICELEN);
|
*slave = slavefd;
|
||||||
return 0;
|
strlcpy(SlaveName, slavedevice, DEVICELEN);
|
||||||
#if defined I_PUSH && !defined linux
|
return 0;
|
||||||
}
|
|
||||||
}
|
grantpt_error:
|
||||||
#endif
|
sigaction(SIGCHLD, &old, NULL);
|
||||||
}
|
error:
|
||||||
}
|
if (slavefd != -1) close(slavefd);
|
||||||
}
|
if (masterfd != -1) close(masterfd);
|
||||||
}
|
if (!fail) {
|
||||||
close(masterfd);
|
rb_raise(rb_eRuntimeError, "can't get Master/Slave device");
|
||||||
}
|
}
|
||||||
if (!fail) rb_raise(rb_eRuntimeError, "can't get Master/Slave device");
|
|
||||||
return -1;
|
return -1;
|
||||||
#elif defined HAVE_OPENPTY
|
#elif defined HAVE_OPENPTY
|
||||||
/*
|
/*
|
||||||
|
@ -320,12 +330,18 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int fail)
|
||||||
if (!fail) return -1;
|
if (!fail) return -1;
|
||||||
rb_raise(rb_eRuntimeError, "openpty() failed");
|
rb_raise(rb_eRuntimeError, "openpty() failed");
|
||||||
}
|
}
|
||||||
|
if (no_mesg(slavedevice, nomesg) == -1) {
|
||||||
|
if (!fail) return -1;
|
||||||
|
rb_raise(rb_eRuntimeError, "can't chmod slave pty");
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#elif defined HAVE__GETPTY
|
#elif defined HAVE__GETPTY
|
||||||
char *name;
|
char *name;
|
||||||
|
mode_t mode = nomesg ? 0600 : 0622;
|
||||||
|
|
||||||
if (!(name = _getpty(master, O_RDWR, 0622, 0))) {
|
if (!(name = _getpty(master, O_RDWR, mode, 0))) {
|
||||||
if (!fail) return -1;
|
if (!fail) return -1;
|
||||||
rb_raise(rb_eRuntimeError, "_getpty() failed");
|
rb_raise(rb_eRuntimeError, "_getpty() failed");
|
||||||
}
|
}
|
||||||
|
@ -335,72 +351,70 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int fail)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
#elif defined(HAVE_PTSNAME)
|
#elif defined(HAVE_PTSNAME)
|
||||||
int i,j;
|
int masterfd = -1, slavefd = -1;
|
||||||
char *pn;
|
char *slavedevice;
|
||||||
void (*s)();
|
void (*s)();
|
||||||
|
|
||||||
extern char *ptsname(int);
|
extern char *ptsname(int);
|
||||||
extern int unlockpt(int);
|
extern int unlockpt(int);
|
||||||
extern int grantpt(int);
|
extern int grantpt(int);
|
||||||
|
|
||||||
if((i = open("/dev/ptmx", O_RDWR, 0)) != -1) {
|
if((masterfd = open("/dev/ptmx", O_RDWR, 0)) == -1) goto error;
|
||||||
s = signal(SIGCHLD, SIG_DFL);
|
s = signal(SIGCHLD, SIG_DFL);
|
||||||
if(grantpt(i) != -1) {
|
if(grantpt(masterfd) == -1) goto error;
|
||||||
signal(SIGCHLD, s);
|
signal(SIGCHLD, s);
|
||||||
if(unlockpt(i) != -1) {
|
if(unlockpt(masterfd) == -1) goto error;
|
||||||
if((pn = ptsname(i)) != NULL) {
|
if((slavedevice = ptsname(masterfd)) == NULL) goto error;
|
||||||
if((j = open(pn, O_RDWR, 0)) != -1) {
|
if (no_mesg(slavedevice, nomesg) == -1) goto error;
|
||||||
|
if((slavefd = open(slavedevice, O_RDWR, 0)) == -1) goto error;
|
||||||
#if defined I_PUSH && !defined linux
|
#if defined I_PUSH && !defined linux
|
||||||
if(ioctl(j, I_PUSH, "ptem") != -1) {
|
if(ioctl(slavefd, I_PUSH, "ptem") == -1) goto error;
|
||||||
if(ioctl(j, I_PUSH, "ldterm") != -1) {
|
if(ioctl(slavefd, I_PUSH, "ldterm") == -1) goto error;
|
||||||
ioctl(j, I_PUSH, "ttcompat");
|
ioctl(slavefd, I_PUSH, "ttcompat");
|
||||||
#endif
|
#endif
|
||||||
*master = i;
|
*master = masterfd;
|
||||||
*slave = j;
|
*slave = slavefd;
|
||||||
strlcpy(SlaveName, pn, DEVICELEN);
|
strlcpy(SlaveName, slavedevice, DEVICELEN);
|
||||||
return 0;
|
return 0;
|
||||||
#if defined I_PUSH && !defined linux
|
|
||||||
}
|
error:
|
||||||
}
|
if (slavefd != -1) close(slavefd);
|
||||||
#endif
|
if (masterfd != -1) close(masterfd);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(i);
|
|
||||||
}
|
|
||||||
if (!fail) rb_raise(rb_eRuntimeError, "can't get Master/Slave device");
|
if (!fail) rb_raise(rb_eRuntimeError, "can't get Master/Slave device");
|
||||||
return -1;
|
return -1;
|
||||||
#else
|
#else
|
||||||
int i,j;
|
int masterfd = -1, slavefd = -1;
|
||||||
const char *const *p;
|
const char *const *p;
|
||||||
char MasterName[DEVICELEN];
|
char MasterName[DEVICELEN];
|
||||||
|
|
||||||
for (p = deviceNo; *p != NULL; p++) {
|
for (p = deviceNo; *p != NULL; p++) {
|
||||||
snprintf(MasterName, sizeof MasterName, MasterDevice, *p);
|
snprintf(MasterName, sizeof MasterName, MasterDevice, *p);
|
||||||
if ((i = open(MasterName,O_RDWR,0)) >= 0) {
|
if ((masterfd = open(MasterName,O_RDWR,0)) >= 0) {
|
||||||
*master = i;
|
*master = masterfd;
|
||||||
snprintf(SlaveName, DEVICELEN, SlaveDevice, *p);
|
snprintf(SlaveName, DEVICELEN, SlaveDevice, *p);
|
||||||
if ((j = open(SlaveName,O_RDWR,0)) >= 0) {
|
if ((slavefd = open(SlaveName,O_RDWR,0)) >= 0) {
|
||||||
*slave = j;
|
*slave = slavefd;
|
||||||
chown(SlaveName, getuid(), getgid());
|
if (chown(SlaveName, getuid(), getgid()) != 0) goto error;
|
||||||
chmod(SlaveName, 0622);
|
if (chmod(SlaveName, nomesg ? 0600 : 0622) != 0) goto error;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
close(i);
|
close(masterfd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
error:
|
||||||
|
if (slavefd != -1) close(slavefd);
|
||||||
|
if (masterfd != -1) close(masterfd);
|
||||||
if (fail) rb_raise(rb_eRuntimeError, "can't get %s", SlaveName);
|
if (fail) rb_raise(rb_eRuntimeError, "can't get %s", SlaveName);
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
getDevice(int *master, int *slave, char SlaveName[DEVICELEN])
|
getDevice(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg)
|
||||||
{
|
{
|
||||||
if (get_device_once(master, slave, SlaveName, 0)) {
|
if (get_device_once(master, slave, SlaveName, nomesg, 0)) {
|
||||||
rb_gc();
|
rb_gc();
|
||||||
get_device_once(master, slave, SlaveName, 1);
|
get_device_once(master, slave, SlaveName, nomesg, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +458,7 @@ pty_open(VALUE klass)
|
||||||
rb_io_t *master_fptr, *slave_fptr;
|
rb_io_t *master_fptr, *slave_fptr;
|
||||||
VALUE assoc;
|
VALUE assoc;
|
||||||
|
|
||||||
getDevice(&master_fd, &slave_fd, slavename);
|
getDevice(&master_fd, &slave_fd, slavename, 1);
|
||||||
|
|
||||||
master_io = rb_obj_alloc(rb_cIO);
|
master_io = rb_obj_alloc(rb_cIO);
|
||||||
MakeOpenFile(master_io, master_fptr);
|
MakeOpenFile(master_io, master_fptr);
|
||||||
|
|
|
@ -99,23 +99,11 @@ class TestPTY < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_stat_slave
|
def test_stat_slave
|
||||||
# If grantpt is used, the slave device is changed as follows.
|
|
||||||
# owner: real UID
|
|
||||||
# group: an unspecified value (e.g. tty)
|
|
||||||
# mode: 0620 (rw--w----)
|
|
||||||
#
|
|
||||||
# The group is not testable because unspecified.
|
|
||||||
#
|
|
||||||
# The mode is testable but the condition is relaxed because other
|
|
||||||
# pty functions (openpty, _getpty, etc.) may not use 0620.
|
|
||||||
# But no one can read from the tty, I hope (for security reason).
|
|
||||||
#
|
|
||||||
PTY.open {|master, slave|
|
PTY.open {|master, slave|
|
||||||
s = File.stat(slave.path)
|
s = File.stat(slave.path)
|
||||||
assert_equal(Process.uid, s.uid)
|
assert_equal(Process.uid, s.uid)
|
||||||
assert_equal(0600, s.mode & 0755)
|
assert_equal(0600, s.mode & 0777)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
end if defined? PTY
|
end if defined? PTY
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue