Subject: bin/1288: ps has no way of specifying -t for no controlling terminal
To: None <gnats-bugs@NetBSD.ORG>
From: None <abs@mono.city.ac.uk>
List: netbsd-bugs
Date: 07/27/1995 17:10:40
>Number:         1288
>Category:       bin
>Synopsis:       ps has no way of specifying -t for no controlling terminal
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jul 27 16:35:06 1995
>Last-Modified:
>Originator:     David Brownlee
>Organization:
Monochrome
>Release:        Jun 9th 1995
>Environment:
sparc, 1.0A, current
System: NetBSD gluon.city.ac.uk 1.0A NetBSD 1.0A (GLUON) #1: monoadm@gluon.city.ac.uk:/mono/u1/NetBSD/src/sys/arch/sparc/compile/GLUON sparc

>Description:
	If you want all processes on the console you can specify 'ps tco', but
	if you want all processes without a controlling terminal you're a
	little stuffed :)

	Other systems allow 'ps t\?' for a controlling terminal of '?'.
	(Seems to make sense to me)

>How-To-Repeat:
	Hit ~ ^Z on your console at the wrong time - hang the shell so
	you cannot kill -9 it & then try hunting down any processes without
	a controlling terminal as you can't figure out anything else to do...
	(but that's a different story :)
>Fix:
	I tried patching ps to pass through KERN_PROC_TTY,NODEV to
	kvm_getprocs(), but of course kvm_getprocs() didn't buy that...

	So I tried patching kvm_getprocs() to accept it - and it works fine
	as long as kvm_getprocs() doesn't call sysctl() to get the information
	(arrg). I couldn't find where __sysctl() hangs out, but I figure my
	changes will have to be looked at by someone who knows all about this
	anyway, so as I've run outa time here I'll submit what I have :)

	Follows a patch for ps which will make it accept -t? or -t?? to mean
	all processes without a controlling terminal, which I'm happy enough
	with. Also patch for the manpage.

	After that is a patch for libkvm/kvm_proc.c - this only works for
	the case where ISALIVE(kd) is false - so I've forced this case just
	to prove my code - the ``if (ISALIVE(kd) && 0)'' is not proposed to go
	into the tree!! :) . I think all but the last makes sense - if anyone
	could tell me where I should have found __sysctl() & fixed this last
	bit I'd be greatful!

		Thanks
					abs

*** ps.c.old	Thu Jul 27 16:14:06 1995
--- ps.c	Thu Jul 27 17:16:32 1995
***************
*** 111,116 ****
--- 111,117 ----
  	struct kinfo_proc *kp;
  	struct varent *vent;
  	struct winsize ws;
+ 	int   check_tty;
  	dev_t ttydev;
  	pid_t pid;
  	uid_t uid;
***************
*** 132,138 ****
  	all = fmt = prtheader = wflag = xflg = 0;
  	pid = -1;
  	uid = (uid_t) -1;
! 	ttydev = NODEV;
  	memf = nlistf = swapf = NULL;
  	while ((ch = getopt(argc, argv,
  	    "acCeghjLlM:mN:O:o:p:rSTt:uvW:wx")) != EOF)
--- 133,139 ----
  	all = fmt = prtheader = wflag = xflg = 0;
  	pid = -1;
  	uid = (uid_t) -1;
! 	check_tty = 0;
  	memf = nlistf = swapf = NULL;
  	while ((ch = getopt(argc, argv,
  	    "acCeghjLlM:mN:O:o:p:rSTt:uvW:wx")) != EOF)
***************
*** 205,213 ****
  			struct stat sb;
  			char *ttypath, pathbuf[MAXPATHLEN];
  
  			if (strcmp(optarg, "co") == 0)
  				ttypath = _PATH_CONSOLE;
! 			else if (*optarg != '/')
  				(void)snprintf(ttypath = pathbuf,
  				    sizeof(pathbuf), "%s%s", _PATH_TTY, optarg);
  			else
--- 206,218 ----
  			struct stat sb;
  			char *ttypath, pathbuf[MAXPATHLEN];
  
+ 			check_tty = 1;
  			if (strcmp(optarg, "co") == 0)
  				ttypath = _PATH_CONSOLE;
! 			else if (strcmp(optarg, "?") == 0)
! 				ttydev = NODEV;
! 				break;
! 			} else if (*optarg != '/')
  				(void)snprintf(ttypath = pathbuf,
  				    sizeof(pathbuf), "%s%s", _PATH_TTY, optarg);
  			else
***************
*** 276,282 ****
  	if (!fmt)
  		parsefmt(dfmt);
  
! 	if (!all && ttydev == NODEV && pid == -1)  /* XXX - should be cleaner */
  		uid = getuid();
  
  	/*
--- 281,287 ----
  	if (!fmt)
  		parsefmt(dfmt);
  
! 	if (!all && check_tty == 0 && pid == -1)  /* XXX - should be cleaner */
  		uid = getuid();
  
  	/*
***************
*** 290,296 ****
  	if (uid != (uid_t) -1) {
  		what = KERN_PROC_UID;
  		flag = uid;
! 	} else if (ttydev != NODEV) {
  		what = KERN_PROC_TTY;
  		flag = ttydev;
  	} else if (pid != -1) {
--- 295,301 ----
  	if (uid != (uid_t) -1) {
  		what = KERN_PROC_UID;
  		flag = uid;
! 	} else if (check_tty) {
  		what = KERN_PROC_TTY;
  		flag = ttydev;
  	} else if (pid != -1) {
-------------------------------------------------------------------------------

*** ps.1.old	Thu Jul 27 17:15:33 1995
--- ps.1	Thu Jul 27 17:15:36 1995
***************
*** 137,143 ****
  with the standard input.
  .It Fl t
  Display information about processes attached to the specified terminal
! device.
  .It Fl u
  Display information associated with the following keywords:
  user, pid, %cpu, %mem, vsz, rss, tt, state, start, time and command.
--- 137,144 ----
  with the standard input.
  .It Fl t
  Display information about processes attached to the specified terminal
! device. 
! Specifying t? will display processes without a controlling terminal.
  .It Fl u
  Display information associated with the following keywords:
  user, pid, %cpu, %mem, vsz, rss, tt, state, start, time and command.
-------------------------------------------------------------------------------


*** kvm_proc.c.old	Thu Jul 27 16:30:51 1995
--- kvm_proc.c	Thu Jul 27 16:48:42 1995
***************
*** 422,429 ****
  			break;
  
  		case KERN_PROC_TTY:
! 			if ((proc.p_flag & P_CONTROLT) == 0 || 
! 			     eproc.e_tdev != (dev_t)arg)
  				continue;
  			break;
  		}
--- 422,430 ----
  			break;
  
  		case KERN_PROC_TTY:
! 			if (((proc.p_flag & P_CONTROLT) == 0 || 
! 			     eproc.e_tdev != (dev_t)arg) &&
! 			     (arg != NODEV || (proc.p_flag & P_CONTROLT)))
  				continue;
  			break;
  		}
***************
*** 487,493 ****
  		 */
  		kd->procbase = 0;
  	}
! 	if (ISALIVE(kd)) {
  		size = 0;
  		mib[0] = CTL_KERN;
  		mib[1] = KERN_PROC;
--- 488,494 ----
  		 */
  		kd->procbase = 0;
  	}
! 	if (ISALIVE(kd) && 0) {
  		size = 0;
  		mib[0] = CTL_KERN;
  		mib[1] = KERN_PROC;






>Audit-Trail:
>Unformatted: