/*
- * Copyright (c) 2012 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2012-2013 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
/*
* Do a breadth-first scan of dir looking for the specified device.
*/
-static
-char *sudo_ttyname_scan(const char *dir, dev_t rdev, bool builtin)
+static char *
+sudo_ttyname_scan(const char *dir, dev_t rdev, bool builtin)
{
- DIR *d;
+ DIR *d = NULL;
char pathbuf[PATH_MAX], **subdirs = NULL, *devname = NULL;
size_t sdlen, d_len, len, num_subdirs = 0, max_subdirs = 0;
struct dirent *dp;
}
if (S_ISCHR(sb.st_mode) && sb.st_rdev == rdev) {
devname = estrdup(pathbuf);
- break;
+ goto done;
}
}
- closedir(d);
/* Search subdirs if we didn't find it in the root level. */
for (i = 0; devname == NULL && i < num_subdirs; i++)
devname = sudo_ttyname_scan(subdirs[i], rdev, false);
done:
+ if (d != NULL)
+ closedir(d);
for (i = 0; i < num_subdirs; i++)
efree(subdirs[i]);
efree(subdirs);
debug_decl(sudo_ttyname_dev, SUDO_DEBUG_UTIL)
/*
- * First check search_devs.
+ * First check search_devs for common tty devices.
*/
- for (sd = search_devs; (devname = *sd) != NULL; sd++) {
+ for (sd = search_devs; tty == NULL && (devname = *sd) != NULL; sd++) {
len = strlen(devname);
if (devname[len - 1] == '/') {
- /* Special case /dev/pts */
if (strcmp(devname, "/dev/pts/") == 0) {
+ /* Special case /dev/pts */
(void)snprintf(buf, sizeof(buf), "%spts/%u", _PATH_DEV,
(unsigned int)minor(rdev));
if (stat(buf, &sb) == 0) {
- if (S_ISCHR(sb.st_mode) && sb.st_rdev == rdev) {
+ if (S_ISCHR(sb.st_mode) && sb.st_rdev == rdev)
tty = estrdup(buf);
- break;
- }
}
- continue;
+ } else {
+ /* Traverse directory */
+ tty = sudo_ttyname_scan(devname, rdev, true);
}
- /* Traverse directory */
- tty = sudo_ttyname_scan(devname, rdev, true);
} else {
if (stat(devname, &sb) == 0) {
- if (S_ISCHR(sb.st_mode) && sb.st_rdev == rdev) {
+ if (S_ISCHR(sb.st_mode) && sb.st_rdev == rdev)
tty = estrdup(devname);
- break;
- }
}
}
}
}
efree(ki_proc);
- /* If all else fails, fall back on ttyname(). */
- if (tty == NULL) {
- if ((tty = ttyname(STDIN_FILENO)) != NULL ||
- (tty = ttyname(STDOUT_FILENO)) != NULL ||
- (tty = ttyname(STDERR_FILENO)) != NULL)
- tty = estrdup(tty);
- }
-
debug_return_str(tty);
}
#elif defined(HAVE_STRUCT_PSINFO_PR_TTYDEV)
get_process_ttyname(void)
{
char path[PATH_MAX], *tty = NULL;
- struct stat sb;
struct psinfo psinfo;
ssize_t nread;
int i, fd;
continue;
nread = read(fd, &psinfo, sizeof(psinfo));
close(fd);
- if (nread == (ssize_t)sizeof(psinfo) && psinfo.pr_ttydev != (dev_t)-1) {
- tty = sudo_ttyname_dev(psinfo.pr_ttydev);
+ if (nread == (ssize_t)sizeof(psinfo)) {
+ dev_t rdev = (dev_t)psinfo.pr_ttydev;
+#ifdef DEVNO64
+ if (psinfo.pr_ttydev & DEVNO64)
+ rdev = makedev(major64(psinfo.pr_ttydev), minor64(psinfo.pr_ttydev));
+#endif
+ if (rdev != (dev_t)-1)
+ tty = sudo_ttyname_dev(rdev);
}
}
- /* If all else fails, fall back on ttyname(). */
- if (tty == NULL) {
- if ((tty = ttyname(STDIN_FILENO)) != NULL ||
- (tty = ttyname(STDOUT_FILENO)) != NULL ||
- (tty = ttyname(STDERR_FILENO)) != NULL)
- tty = estrdup(tty);
- }
-
debug_return_str(tty);
}
#elif defined(__linux__)
int i;
debug_decl(get_process_ttyname, SUDO_DEBUG_UTIL)
- /* Try to determine the tty from pr_ttydev in /proc/pid/psinfo. */
+ /* Try to determine the tty from tty_nr in /proc/pid/stat. */
for (i = 0; tty == NULL && i < 2; i++) {
FILE *fp;
char path[PATH_MAX];
}
efree(line);
- /* If all else fails, fall back on ttyname(). */
- if (tty == NULL) {
- if ((tty = ttyname(STDIN_FILENO)) != NULL ||
- (tty = ttyname(STDOUT_FILENO)) != NULL ||
- (tty = ttyname(STDERR_FILENO)) != NULL)
- tty = estrdup(tty);
- }
-
debug_return_str(tty);
}
#else