psacct/acct-6.3.2-pts.patch
cvsdist f55e500b0c auto-import changelog data from psacct-6.3.2-31.src.rpm
Wed Sep 01 2004 root <ccb@redhat.com> - 6.3.2-31
- integrate JFenlason's hz patch, improve pts device reporting
2004-09-09 10:50:13 +00:00

151 lines
3.4 KiB
Diff

--- acct-6.3.2/dev_hash.c.pts Thu Apr 18 19:18:15 1996
+++ acct-6.3.2/dev_hash.c Tue Aug 31 17:20:56 2004
@@ -29,6 +29,7 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/utsname.h>
#include <pwd.h>
#include "common.h"
@@ -52,6 +53,11 @@
# endif
#endif
+#ifdef __linux__
+#define NULLDEV 0
+#else
+#define NULLDEV -1
+#endif
/* globals */
@@ -62,6 +68,55 @@
};
+/* hash all possible /dev/pts devices as they only appear
+ * in the filesystem when the device is active.
+ */
+
+static void
+setup_pts_devices () {
+
+ struct utsname uts;
+ struct dev_data dd;
+ int i;
+ struct pts_params {
+ char *utsname; /* os name */
+ int base; /* base major number */
+ int max; /* max # of devices */
+ int mod; /* number of minors per major */
+ } *pts_ent, pts_table[] = {
+ {"Linux", 136, 2048, 256},
+ { }
+ };
+
+ if( uname (&uts) ) {
+ /* silent error */
+ return;
+ }
+
+ for (pts_ent = &(pts_table[0]); pts_ent != NULL; ++pts_ent) {
+ if (!strcmp (uts.sysname, pts_ent->utsname))
+ break;
+ }
+ if (pts_ent == NULL) return; /* unsupported OS */
+
+ for (i = 0; i < pts_ent->max; ++i) {
+ long dev_num;
+ struct hashtab_elem *he;
+ int major, minor;
+
+ major = pts_ent->base + (i/pts_ent->mod);
+ minor = i % pts_ent->mod;
+ dev_num = ((major << 8) + minor);
+
+ dd.name = xmalloc (sizeof(char) * (strlen("pts/xxxx") + 1));
+ sprintf (dd.name, "pts/%d", i);
+
+ he = hashtab_create (dev_table, (void *) & dev_num, sizeof(dev_num));
+ hashtab_set_value (he, &dd, sizeof (dd));
+ }
+}
+
+
/* Read the DIRNAME directory entries and make a linked list of ttys
(so we can search through it later) */
@@ -79,7 +134,14 @@
if ((dirp = opendir (dirname)) == NULL)
return; /* skip it silently */
-
+
+ if (!strcmp (dirname, "/dev/pts")) {
+ /* assuming SysV, these are dynamically allocated */
+ closedir (dirp);
+ setup_pts_devices ();
+ return;
+ }
+
for (dp = readdir (dirp); dp != NULL; dp = readdir (dirp))
{
char *fullname = (char *) alloca ((strlen (dirname)
@@ -105,7 +167,7 @@
dev_num = sp.st_rdev;
dd.name = (char *) xmalloc (sizeof (char) * (NAMLEN (dp) + 1));
strcpy (dd.name, dp->d_name);
-
+
he = hashtab_create (dev_table, (void *) &dev_num, sizeof (dev_num));
hashtab_set_value (he, &dd, sizeof (dd));
}
@@ -114,6 +176,8 @@
}
+
+
/* Return the name of the device associated with DEV_NUM. The
argument passed was originally a dev_t, but that data type is too
limited on some systems (won't let us pass -1 because it's an
@@ -123,10 +187,11 @@
devname (long dev_num)
{
struct hashtab_elem *he;
+ static char devstr [20];
/* special case */
- if (dev_num == -1)
+ if (dev_num == NULLDEV)
return "__";
if (dev_table == NULL)
@@ -135,6 +200,7 @@
setup_devices ("/dev"); /* most certainly */
setup_devices ("/dev/pty"); /* perhaps */
setup_devices ("/dev/ptym"); /* perhaps */
+ setup_devices ("/dev/pts"); /* perhaps */
}
he = hashtab_find (dev_table, (void *) &dev_num, sizeof (dev_num));
@@ -144,9 +210,12 @@
struct dev_data *dd = hashtab_get_value (he);
return dd->name;
}
-
- /* didn't find it */
-
- return "??";
+
+ /* didn't find it, return it as [maj,min] */
+
+ sprintf (devstr, "[%d,%d]", /* is this portable? */
+ (int) ((dev_num & 0xFF00) >> 8), (int) (dev_num & 0x00FF));
+
+ return devstr;
}