Subject: mods to ps for no and revoked ttys
To: None <tech-kern@netbsd.org>
From: Simon Burge <simonb@netbsd.org>
List: tech-kern
Date: 04/11/2000 18:13:09
A while ago, Alexis Rosen asked about ps(1) support for showing only
processes with no ttys with -t? and processes with revoked ttys with
-t-, ala either sunos or solaris.

The following diffs add this.  Before I commit this, is there ever any
case where (p->p_flag & P_CONTROLT != 0) and (p->p_session == NULL)?
Looking at other uses of p_session in the kernel there doesn't seem
to be (for example kern_acct.c:acct_process(), subr_prf.c:uprintf()
and tty.c:ttioctl()), but I'd hate to add a possible null pointer
dereference...

The only bit I'm not happy with is using the magic number "-2" to denote
"check for revoked terminals".  Any suggestions on how to better handle
this?

Simon.
--
Index: bin/ps/ps.1
===================================================================
RCS file: /cvsroot/basesrc/bin/ps/ps.1,v
retrieving revision 1.35
diff -p -u -r1.35 ps.1
--- ps.1	2000/04/10 06:37:37	1.35
+++ ps.1	2000/04/11 08:04:43
@@ -165,7 +165,9 @@ Display information about processes atta
 with the standard input.
 .It Fl t
 Display information about processes attached to the specified terminal
-device.
+device.  Use an question mark (``?'') for processes not attached to a
+terminal device and a minus sign (``-'') for processes that have
+been revoked from their terminal device.
 .It Fl U
 Displays processes belonging to the user whose username or uid has 
 been given to the
Index: bin/ps/ps.c
===================================================================
RCS file: /cvsroot/basesrc/bin/ps/ps.c,v
retrieving revision 1.35
diff -p -u -r1.35 ps.c
--- ps.c	2000/04/10 06:37:37	1.35
+++ ps.c	2000/04/11 08:04:43
@@ -218,19 +218,26 @@ main(argc, argv)
 			struct stat sb;
 			char *ttypath, pathbuf[MAXPATHLEN];
 
-			if (strcmp(ttname, "co") == 0)
+			flag = 0;
+			if (strcmp(ttname, "?") == 0)
+				flag = NODEV;
+			else if (strcmp(ttname, "-") == 0)
+				flag = -2;
+			else if (strcmp(ttname, "co") == 0)
 				ttypath = _PATH_CONSOLE;
 			else if (*ttname != '/')
 				(void)snprintf(ttypath = pathbuf,
 				    sizeof(pathbuf), "%s%s", _PATH_TTY, ttname);
 			else
 				ttypath = ttname;
-			if (stat(ttypath, &sb) == -1)
-				err(1, "%s", ttypath);
-			if (!S_ISCHR(sb.st_mode))
-				errx(1, "%s: not a terminal", ttypath);
 			what = KERN_PROC_TTY;
-			flag = sb.st_rdev;
+			if (flag == 0) {
+				if (stat(ttypath, &sb) == -1)
+					err(1, "%s", ttypath);
+				if (!S_ISCHR(sb.st_mode))
+					errx(1, "%s: not a terminal", ttypath);
+				flag = sb.st_rdev;
+			}
 			break;
 		}
 		case 'U':
Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_sysctl.c,v
retrieving revision 1.60
diff -p -u -r1.60 kern_sysctl.c
--- kern_sysctl.c	2000/03/30 09:27:12	1.60
+++ kern_sysctl.c	2000/04/11 08:04:43
@@ -995,9 +995,17 @@ again:
 			break;
 
 		case KERN_PROC_TTY:
-			if ((p->p_flag & P_CONTROLT) == 0 ||
-			    p->p_session->s_ttyp == NULL ||
-			    p->p_session->s_ttyp->t_dev != (dev_t)name[1])
+			if (name[1] == -2) {	/* XXX revoked tty */
+				if ((p->p_flag & P_CONTROLT) == 0 ||
+				    p->p_session->s_ttyp == NULL ||
+				    p->p_session->s_ttyvp != NULL)
+					continue;
+			} else if ((p->p_flag & P_CONTROLT) == 0 ||
+			    p->p_session->s_ttyp == NULL) {
+				if ((dev_t)name[1] != NODEV)
+					continue;
+			} else if (p->p_session->s_ttyp->t_dev !=
+			    (dev_t)name[1])
 				continue;
 			break;
 
@@ -1056,7 +1064,7 @@ fill_eproc(p, ep)
 	struct tty *tp;
 
 	ep->e_paddr = p;
-	ep->e_sess = p->p_pgrp->pg_session;
+	ep->e_sess = p->p_session;
 	ep->e_pcred = *p->p_cred;
 	ep->e_ucred = *p->p_ucred;
 	if (p->p_stat == SIDL || P_ZOMBIE(p)) {