summaryrefslogtreecommitdiff
path: root/sysdeps/unix/grantpt.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/grantpt.c')
-rw-r--r--sysdeps/unix/grantpt.c59
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);
}