diff options
Diffstat (limited to 'sysdeps/unix/grantpt.c')
-rw-r--r-- | sysdeps/unix/grantpt.c | 59 |
1 files changed, 32 insertions, 27 deletions
diff --git a/sysdeps/unix/grantpt.c b/sysdeps/unix/grantpt.c index 8c299e9147..260e8273f8 100644 --- a/sysdeps/unix/grantpt.c +++ b/sysdeps/unix/grantpt.c @@ -38,7 +38,7 @@ this buffer, a sufficiently long buffer is allocated using malloc, and returned in PTS. 0 is returned upon success, -1 otherwise. */ static int -pts_name (int fd, char **pts, size_t buf_len) +pts_name (int fd, char **pts, size_t buf_len, struct stat64 *stp) { int rv; char *buf = *pts; @@ -49,7 +49,7 @@ pts_name (int fd, char **pts, size_t buf_len) if (buf_len) { - rv = __ptsname_r (fd, buf, buf_len); + rv = __ptsname_internal (fd, buf, buf_len, stp); if (rv != 0) { if (rv == ENOTTY) @@ -108,15 +108,8 @@ grantpt (int fd) #endif char *buf = _buf; struct stat64 st; - char *grtmpbuf; - struct group grbuf; - size_t grbuflen = __sysconf (_SC_GETGR_R_SIZE_MAX); - struct group *p; - uid_t uid; - gid_t gid; - pid_t pid; - - if (__builtin_expect (pts_name (fd, &buf, sizeof (_buf)), 0)) + + if (__builtin_expect (pts_name (fd, &buf, sizeof (_buf), &st), 0)) { int save_errno = errno; @@ -126,34 +119,42 @@ grantpt (int fd) return -1; /* If the filedescriptor is no TTY, grantpt has to set errno - to EINVAL. */ + to EINVAL. */ if (save_errno == ENOTTY) - __set_errno (EINVAL); + __set_errno (EINVAL); else __set_errno (save_errno); return -1; } - if (__xstat64 (_STAT_VER, buf, &st) < 0) - goto cleanup; - /* Make sure that we own the device. */ - uid = __getuid (); + uid_t uid = __getuid (); if (st.st_uid != uid) { if (__chown (buf, uid, st.st_gid) < 0) goto helper; } - /* Get the group ID of the special `tty' group. */ - if (grbuflen == (size_t) -1L) - /* `sysconf' does not support _SC_GETGR_R_SIZE_MAX. - Try a moderate value. */ - grbuflen = 1024; - grtmpbuf = (char *) __alloca (grbuflen); - __getgrnam_r (TTY_GROUP, &grbuf, grtmpbuf, grbuflen, &p); - gid = p ? p->gr_gid : __getgid (); + static int tty_gid = -1; + if (__builtin_expect (tty_gid == -1, 0)) + { + char *grtmpbuf; + struct group grbuf; + size_t grbuflen = __sysconf (_SC_GETGR_R_SIZE_MAX); + struct group *p; + + /* Get the group ID of the special `tty' group. */ + if (grbuflen == (size_t) -1L) + /* `sysconf' does not support _SC_GETGR_R_SIZE_MAX. + Try a moderate value. */ + grbuflen = 1024; + grtmpbuf = (char *) __alloca (grbuflen); + __getgrnam_r (TTY_GROUP, &grbuf, grtmpbuf, grbuflen, &p); + if (p != NULL) + tty_gid = p->gr_gid; + } + gid_t gid = tty_gid == -1 ? __getgid () : tty_gid; /* Make sure the group of the device is that special group. */ if (st.st_gid != gid) @@ -174,9 +175,9 @@ grantpt (int fd) goto cleanup; /* We have to use the helper program. */ - helper: + helper:; - pid = __fork (); + pid_t pid = __fork (); if (pid == -1) goto cleanup; else if (pid == 0) @@ -190,6 +191,10 @@ grantpt (int fd) if (__dup2 (fd, PTY_FILENO) < 0) _exit (FAIL_EBADF); +#ifdef CLOSE_ALL_FDS + CLOSE_ALL_FDS (); +#endif + execle (_PATH_PT_CHOWN, basename (_PATH_PT_CHOWN), NULL, NULL); _exit (FAIL_EXEC); } |