mirror of
https://repo.or.cz/socat.git
synced 2025-07-10 22:13:00 +00:00
Procan: Try to identify controlling terminal
This commit is contained in:
parent
cd5673dbd0
commit
27877ea777
7 changed files with 314 additions and 36 deletions
183
procan.c
183
procan.c
|
@ -16,38 +16,168 @@
|
|||
#include "sched.h"
|
||||
#include "filan.h"
|
||||
|
||||
#include <sys/resource.h>
|
||||
#include <sys/resource.h> /* RLIMIT_CPU ... */
|
||||
#include <dirent.h> /* opendir() readdir() closedir() */
|
||||
|
||||
#include "procan.h"
|
||||
|
||||
|
||||
/* Search dir recursively for matching device file.
|
||||
Returns 0 on success;
|
||||
returns -1 when it failed to find the device file. */
|
||||
int find_devpath(
|
||||
char *dirname,
|
||||
unsigned int major,
|
||||
unsigned int minor,
|
||||
char *devname)
|
||||
{
|
||||
DIR *dirp;
|
||||
struct dirent *dirent;
|
||||
char devpath[PATH_MAX];
|
||||
int rc;
|
||||
|
||||
/* Pass 1: search dir flatly for this device entry */
|
||||
dirp = opendir(dirname);
|
||||
if (dirp == NULL) {
|
||||
Warn2("failed to open dir \"%s\": %s", dirname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
while ((errno = 0) || (dirent = readdir(dirp))) {
|
||||
struct stat statbuf;
|
||||
|
||||
#if HAVE_DIRENT_D_TYPE
|
||||
if (dirent->d_type != DT_CHR && dirent->d_type != DT_UNKNOWN)
|
||||
continue;
|
||||
#endif
|
||||
snprintf(devpath, PATH_MAX, "%s/%s", dirname, dirent->d_name);
|
||||
if (Stat(devpath, &statbuf) < 0) {
|
||||
Warn2("failed to stat entry \"%s\": %s", devpath, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
if ((statbuf.st_mode & S_IFMT) != S_IFCHR)
|
||||
continue;
|
||||
if ((statbuf.st_rdev >> 8) == major &&
|
||||
(statbuf.st_rdev & 0xff) == minor) {
|
||||
strcpy(devname, devpath);
|
||||
return 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
closedir(dirp);
|
||||
if (errno != 0) {
|
||||
Warn2("failed to read dir \"%s\": %s", dirname, strerror(errno));
|
||||
snprintf(devname, PATH_MAX, "device %u, %u", major, minor);
|
||||
}
|
||||
|
||||
/* Pass 2: search sub dirs */
|
||||
dirp = opendir(dirname);
|
||||
if (dirp == NULL) {
|
||||
Warn2("failed to open dir \"%s\": %s", dirname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
while ((errno = 0) || (dirent = readdir(dirp))) {
|
||||
char dirpath[PATH_MAX];
|
||||
#if HAVE_DIRENT_D_TYPE
|
||||
if (dirent->d_type != DT_DIR)
|
||||
continue;
|
||||
#else /* Solaris */
|
||||
{
|
||||
struct stat statbuf;
|
||||
if (Stat(dirent->d_name, &statbuf) < 0)
|
||||
continue;
|
||||
if ((statbuf.st_mode & S_IFMT) != S_IFDIR)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, ".."))
|
||||
continue;
|
||||
snprintf(dirpath, PATH_MAX, "%s/%s", dirname, dirent->d_name);
|
||||
rc = find_devpath(dirpath, major, minor, devname);
|
||||
if (rc == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
closedir(dirp);
|
||||
if (dirent == NULL) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Tries to determine the name of the controlling terminal.
|
||||
Returns 0 on success, the name in cttyname;
|
||||
returns 1 when only the device numbers are in cttyname;
|
||||
returns -1 when it failed to determine ctty. */
|
||||
static int controlling_term(
|
||||
FILE *outfile)
|
||||
{
|
||||
char cttypath[PATH_MAX+1];
|
||||
int rc;
|
||||
|
||||
{ /* On Linux this just gives "/dev/tty" */
|
||||
char s[L_ctermid+1];
|
||||
fprintf(outfile, "controlling terminal by ctermid(): \"%s\"\n", ctermid(s));
|
||||
}
|
||||
|
||||
{ /* Check if there is a controlling terminal */
|
||||
int fd;
|
||||
|
||||
if ((fd = Open("/dev/tty", O_NOCTTY, 0)) >= 0)
|
||||
/* On Linux this just gives "/dev/tty" */
|
||||
fprintf(outfile, "controlling terminal by /dev/tty, ttyname(): \"%s\"\n", Ttyname(fd));
|
||||
else
|
||||
fprintf(outfile, "controlling terminal by /dev/tty, ttyname(): (none)\n");
|
||||
}
|
||||
|
||||
#if HAVE_PROC_DIR
|
||||
do { /* Linux: derive ctty from info in /proc */
|
||||
const char procpath[] = "/proc/self/stat";
|
||||
FILE *procstat;
|
||||
unsigned int dev;
|
||||
int n = 0;
|
||||
unsigned int maj, min;
|
||||
|
||||
/* Linux: get device ids from /proc */
|
||||
if ((procstat = fopen(procpath, "r")) == NULL) {
|
||||
Warn1("failed to open \"%s\" for process info", procpath);
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
n = fscanf(procstat, "%*s %*s %*s %*s %*s %*s %u", &dev);
|
||||
if (n != 1) {
|
||||
Warn1("failed to read ctty info from \"%s\"", procpath);
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
maj = (dev>>8)&0xff;
|
||||
min = ((dev>>12)&0xfff00)|(dev&0xff);
|
||||
rc = find_devpath("/dev" /* _PATH_DEV has trailing "/" */, maj, min, cttypath);
|
||||
if (rc < 0) {
|
||||
snprintf(cttypath, PATH_MAX, "device %u, %u", maj, min);
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
rc = 0;
|
||||
} while (false);
|
||||
#else /* !HAVE_PROC_DIR */
|
||||
rc = -1;
|
||||
#endif /* !HAVE_PROC_DIR */
|
||||
if (rc >= 0)
|
||||
fprintf(outfile, "controlling terminal by /proc/<pid>/: \"%s\"\n", cttypath);
|
||||
else
|
||||
fprintf(outfile, "controlling terminal by /proc/<pid>/: (none)\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int procan(FILE *outfile) {
|
||||
|
||||
/*filan(0, outfile);*/
|
||||
|
||||
/* controlling terminal */
|
||||
fprintf(outfile, "process id = "F_pid"\n", Getpid());
|
||||
fprintf(outfile, "process parent id = "F_pid"\n", Getppid());
|
||||
{
|
||||
int fd;
|
||||
if ((fd = Open("/dev/tty", O_NOCTTY, 0)) < 0) {
|
||||
fprintf(outfile, "controlling terminal: -\n");
|
||||
} else {
|
||||
#if 1
|
||||
fprintf(outfile, "controlling terminal: \"%s\"\n", Ttyname(fd));
|
||||
#else
|
||||
char procpath[PATH_MAX], devpath[PATH_MAX+1];
|
||||
int devlen;
|
||||
sprintf(procpath, "/proc/"F_pid"/fd/%d", Getpid(), 0 /*! fd*/);
|
||||
if ((devlen = Readlink(procpath, devpath, sizeof(devpath))) < 0) {
|
||||
;
|
||||
} else {
|
||||
devpath[devlen] = '\0';
|
||||
fprintf(outfile, "controlling terminal: \"%s\"\n", devpath);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
controlling_term(outfile);
|
||||
fprintf(outfile, "process group id = "F_pid"\n", Getpgrp());
|
||||
#if HAVE_GETSID
|
||||
fprintf(outfile, "process session id = "F_pid"\n", Getsid(0));
|
||||
|
@ -55,15 +185,6 @@ int procan(FILE *outfile) {
|
|||
fprintf(outfile, "process group id if fg process / stdin = "F_pid"\n", Tcgetpgrp(0));
|
||||
fprintf(outfile, "process group id if fg process / stdout = "F_pid"\n", Tcgetpgrp(1));
|
||||
fprintf(outfile, "process group id if fg process / stderr = "F_pid"\n", Tcgetpgrp(2));
|
||||
{
|
||||
int fd;
|
||||
if ((fd = Open("/dev/tty", O_RDWR, 0600)) >= 0) {
|
||||
fprintf(outfile, "process has a controlling terminal\n");
|
||||
Close(fd);
|
||||
} else {
|
||||
fprintf(outfile, "process does not have a controlling terminal\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* process owner, groups */
|
||||
fprintf(outfile, "user id = "F_uid"\n", Getuid());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue