Skip to content

Commit f41c194

Browse files
committed
pty: Prefer FD-base operations if available
1 parent c6bee05 commit f41c194

2 files changed

Lines changed: 22 additions & 7 deletions

File tree

ext/pty/extconf.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
(util or have_func("openpty")) or
2222
have_func("_getpty") or
2323
have_func("ioctl")
24+
have_macro("HAVE_FCHMOD") or have_func("fchmod")
25+
have_macro("HAVE_FCHOWN") or have_func("fchown")
2426
create_makefile('pty')
2527
end
2628
end

ext/pty/pty.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -274,12 +274,23 @@ ptsname_r(int fd, char *buf, size_t buflen)
274274
# define HAVE_PTSNAME_R 1
275275
#endif
276276

277+
#ifdef HAVE_FCHMOD
278+
# define change_mode(name, fd, mode) fchmod(fd, mode)
279+
#else
280+
# define change_mode(name, fd, mode) chmod(name, mode)
281+
#endif
282+
#ifdef HAVE_FCHOWN
283+
# define change_owner(name, fd, uid, gid) fchown(fd, uid, gid)
284+
#else
285+
# define change_owner(name, fd, uid, gid) chown(name, uid, gid)
286+
#endif
287+
277288
#if defined(HAVE_POSIX_OPENPT) || defined(HAVE_OPENPTY) || defined(HAVE_PTSNAME_R)
278289
static int
279-
no_mesg(char *slavedevice, int nomesg)
290+
set_device_mode(const char *slavedevice, int fd, int nomesg)
280291
{
281292
if (nomesg)
282-
return chmod(slavedevice, 0600);
293+
return change_mode(slavedevice, fd, 0600);
283294
else
284295
return 0;
285296
}
@@ -340,8 +351,8 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
340351
if (unlockpt(masterfd) == -1) goto error;
341352
if (ptsname_r(masterfd, SlaveName, DEVICELEN) != 0) goto error;
342353
slavedevice = SlaveName;
343-
if (no_mesg(slavedevice, nomesg) == -1) goto error;
344354
if ((slavefd = rb_cloexec_open(slavedevice, O_RDWR|O_NOCTTY, 0)) == -1) goto error;
355+
if (set_device_mode(slavedevice, slavefd, nomesg) == -1) goto error;
345356
rb_update_max_fd(slavefd);
346357

347358
#if defined(I_PUSH) && !defined(__linux__) && !defined(_AIX)
@@ -375,7 +386,9 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
375386
}
376387
rb_fd_fix_cloexec(*master);
377388
rb_fd_fix_cloexec(*slave);
378-
if (no_mesg(SlaveName, nomesg) == -1) {
389+
if (set_device_mode(SlaveName, *slave, nomesg) == -1) {
390+
close(*master);
391+
close(*slave);
379392
if (!fail) return -1;
380393
rb_raise(rb_eRuntimeError, "can't chmod slave pty");
381394
}
@@ -424,8 +437,8 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
424437
if(unlockpt(masterfd) == -1) goto error;
425438
if (ptsname_r(masterfd, SlaveName, DEVICELEN) != 0) goto error;
426439
slavedevice = SlaveName;
427-
if (no_mesg(slavedevice, nomesg) == -1) goto error;
428440
if((slavefd = rb_cloexec_open(slavedevice, O_RDWR, 0)) == -1) goto error;
441+
if (set_device_mode(slavedevice, slavefd, nomesg) == -1) goto error;
429442
rb_update_max_fd(slavefd);
430443
#if defined(I_PUSH) && !defined(__linux__) && !defined(_AIX)
431444
if(ioctl_I_PUSH(slavefd, "ptem") == -1) goto error;
@@ -478,8 +491,8 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
478491
if ((slavefd = rb_cloexec_open(SlaveName,O_RDWR,0)) >= 0) {
479492
rb_update_max_fd(slavefd);
480493
*slave = slavefd;
481-
if (chown(SlaveName, getuid(), getgid()) != 0) goto error;
482-
if (chmod(SlaveName, nomesg ? 0600 : 0622) != 0) goto error;
494+
if (change_owner(slavefd, getuid(), getgid()) != 0) goto error;
495+
if (change_mode(slavefd, nomesg ? 0600 : 0622) != 0) goto error;
483496
return 0;
484497
}
485498
close(masterfd);

0 commit comments

Comments
 (0)