/* Store at most BUFLEN characters of the pathname of the slave pseudo terminal associated with the master FD is open on in BUF. Return 0 on success, otherwise an error number. */ int __ptsname_r (int fd, char *buf, size_t buflen) { int save_errno = errno; struct stat st; if (buf == NULL) { __set_errno (EINVAL); return EINVAL; } if (!__isatty (fd)) /* We rely on isatty to set errno properly (i.e. EBADF or ENOTTY). */ return errno; if (buflen < sizeof (_PATH_PTY) + 4) { __set_errno (ERANGE); return ERANGE; } if (__ttyname_r (fd, buf, buflen) != 0) return errno; buf[ 9] = 's'; buf[10] = 'l'; buf[11] = 'v'; if (__stat (buf, &st) < 0) return errno; __set_errno (save_errno); return 0; }
int ttyslot() { register struct ttyent *ttyp; register int slot; register char *p; int cnt; size_t buflen = __sysconf (_SC_TTY_NAME_MAX) + 1; char *name; if (buflen == 0) /* This should be enough if no fixed value is given. */ buflen = 32; name = __alloca (buflen); setttyent(); for (cnt = 0; cnt < 3; ++cnt) if (__ttyname_r (cnt, name, buflen) == 0) { if ((p = rindex(name, '/'))) ++p; else p = name; for (slot = 1; (ttyp = getttyent()); ++slot) if (!strcmp(ttyp->ty_name, p)) { endttyent(); return(slot); } break; } endttyent(); return(0); }
int __ttyname_r_chk (int fd, char *buf, size_t buflen, size_t nreal) { if (buflen > nreal) __chk_fail (); return __ttyname_r (fd, buf, buflen); }
STATIC #endif char * getlogin (void) { char tty_pathname[2 + 2 * NAME_MAX]; char *real_tty_path = tty_pathname; int err; char *result = NULL; struct utmp *ut, line, buffer; /* Get name of tty connected to fd 0. Return NULL if not a tty or if fd 0 isn't open. Note that a lot of documentation says that getlogin() is based on the controlling terminal---what they really mean is "the terminal connected to standard input". The getlogin() implementation of DEC Unix, SunOS, Solaris, HP-UX all return NULL if fd 0 has been closed, so this is the compatible thing to do. Note that ttyname(open("/dev/tty")) on those systems returns /dev/tty, so that is not a possible solution for getlogin(). */ err = __ttyname_r (0, real_tty_path, sizeof (tty_pathname)); if (err != 0) { __set_errno (err); return NULL; } real_tty_path += 5; /* Remove "/dev/". */ __setutent (); strncpy (line.ut_line, real_tty_path, sizeof line.ut_line); if (__getutline_r (&line, &buffer, &ut) < 0) { if (errno == ESRCH) /* The caller expects ENOENT if nothing is found. */ __set_errno (ENOENT); result = NULL; } else { strncpy (name, ut->ut_user, UT_NAMESIZE); name[UT_NAMESIZE] = '\0'; result = name; } __endutent (); return result; }
/* Store at most BUFLEN characters of the pathname of the slave pseudo terminal associated with the master FD is open on in BUF. Return 0 on success, otherwise an error number. */ int __ptsname_r (int fd, char *buf, size_t buflen) { int save_errno = errno; int err; struct stat st; if (buf == NULL) { __set_errno (EINVAL); return EINVAL; } if (!__isatty (fd)) /* We rely on isatty to set errno properly (i.e. EBADF or ENOTTY). */ return errno; if (buflen < strlen (_PATH_TTY) + 3) { __set_errno (ERANGE); return ERANGE; } err = __ttyname_r (fd, buf, buflen); if (err != 0) { __set_errno (err); return errno; } buf[sizeof (_PATH_DEV) - 1] = 't'; if (__stat (buf, &st) < 0) return errno; __set_errno (save_errno); return 0; }
/* Store at most BUFLEN characters of the pathname of the slave pseudo terminal associated with the master FD is open on in BUF. Return 0 on success, otherwise an error number. */ int __ptsname_r (int fd, char *buf, size_t buflen) { int save_errno = errno; int err; struct stat st; if (buf == NULL) { __set_errno (EINVAL); return EINVAL; } #if defined __sun /* Solaris */ if (fstat (fd, &st) < 0) return errno; if (!(S_ISCHR (st.st_mode) && major (st.st_rdev) == 0)) { errno = ENOTTY; return errno; } { /* Master ptys can be recognized through a STREAMS ioctl. See "STREAMS-based Pseudo-Terminal Subsystem" <http://docs.oracle.com/cd/E18752_01/html/816-4855/termsub15-44781.html> and "STREAMS ioctl commands" <http://docs.oracle.com/cd/E18752_01/html/816-5177/streamio-7i.html> */ struct strioctl ioctl_arg; ioctl_arg.ic_cmd = ISPTM; ioctl_arg.ic_timout = 0; ioctl_arg.ic_len = 0; ioctl_arg.ic_dp = NULL; if (ioctl (fd, I_STR, &ioctl_arg) < 0) { errno = ENOTTY; return errno; } } { char tmpbuf[9 + 10 + 1]; int n = sprintf (tmpbuf, "/dev/pts/%u", minor (st.st_rdev)); if (n >= buflen) { errno = ERANGE; return errno; } memcpy (buf, tmpbuf, n + 1); } #elif defined _AIX || defined __osf__ /* AIX, OSF/1 */ /* This implementation returns /dev/pts/N, like ptsname() does. Whereas the generic implementation below returns /dev/ttypN. Both are correct, but let's be consistent with ptsname(). */ if (fstat (fd, &st) < 0) return errno; if (!S_ISCHR (st.st_mode)) { errno = ENOTTY; return errno; } { int ret; int dev; char tmpbuf[9 + 10 + 1]; int n; # ifdef _AIX ret = ioctl (fd, ISPTM, &dev); # endif # ifdef __osf__ ret = ioctl (fd, ISPTM, NULL); dev = ret; # endif if (ret < 0) { errno = ENOTTY; return errno; } n = sprintf (tmpbuf, "/dev/pts/%u", minor (dev)); if (n >= buflen) { errno = ERANGE; return errno; } memcpy (buf, tmpbuf, n + 1); } #else if (!__isatty (fd)) { #if ISATTY_FAILS_WITHOUT_SETTING_ERRNO && defined F_GETFL /* IRIX, Solaris */ /* Set errno. */ if (fcntl (fd, F_GETFL) != -1) errno = ENOTTY; #else /* We rely on isatty to set errno properly (i.e. EBADF or ENOTTY). */ #endif return errno; } if (buflen < strlen (_PATH_TTY) + 3) { __set_errno (ERANGE); return ERANGE; } err = __ttyname_r (fd, buf, buflen); if (err != 0) { __set_errno (err); return errno; } if (strncmp(buf, "/dev/pts/", strlen("/dev/pts/")) != 0) buf[sizeof (_PATH_DEV) - 1] = 't'; #endif if (__stat (buf, &st) < 0) return errno; __set_errno (save_errno); return 0; }