#define SEL_SESS 12
#define SEL_COMM 13
#define SEL_PPID 14
+#define SEL_PID_QUICK 15
/* Since an enum could be smashed by a #define, it would be bad. */
#define U98 0 /* Unix98 standard */ /* This must be 0 */
case SEL_FGID: show_gid("FGID", walk->n, walk->u); break;
case SEL_PGRP: show_pid("PGRP", walk->n, walk->u); break;
case SEL_PID : show_pid("PID ", walk->n, walk->u); break;
+ case SEL_PID_QUICK : show_pid("PID_QUICK ", walk->n, walk->u); break;
case SEL_PPID: show_pid("PPID", walk->n, walk->u); break;
case SEL_TTY : show_tty("TTY ", walk->n, walk->u); break;
case SEL_SESS: show_pid("SESS", walk->n, walk->u); break;
static void simple_spew(void){
static proc_t buf, buf2; // static avoids memset
PROCTAB* ptp;
+ pid_t* pidlist;
+ int flags;
+ int i;
- ptp = openproc(needs_for_format | needs_for_sort | needs_for_select | needs_for_threads);
+ pidlist = NULL;
+ flags = needs_for_format | needs_for_sort | needs_for_select | needs_for_threads;
+
+ // -q option (only single SEL_PID_QUICK typecode entry expected in the list, if present)
+ if (selection_list && selection_list->typecode == SEL_PID_QUICK) {
+ flags |= PROC_PID;
+
+ pidlist = (pid_t*) malloc(selection_list->n * sizeof(pid_t));
+ if (!pidlist) {
+ fprintf(stderr, _("error: not enough memory\n"));
+ exit(1);
+ }
+
+ for (i = 0; i < selection_list->n; i++) {
+ pidlist[i] = selection_list->u[selection_list->n-i-1].pid;
+ }
+ }
+
+ ptp = openproc(flags, pidlist);
if(!ptp) {
fprintf(stderr, _("error: can not access /proc\n"));
exit(1);
break;
}
closeproc(ptp);
+
+ if (pidlist) free(pidlist);
}
/***** forest output requires sorting by ppid; add start_time by default */
closeproc(ptp);
}
+static void arg_check_conflicts(void)
+{
+ int selection_list_len;
+ int has_quick_pid;
+
+ selection_node *walk = selection_list;
+ has_quick_pid = 0;
+ selection_list_len = 0;
+
+ while (walk) {
+ if (walk->typecode == SEL_PID_QUICK) has_quick_pid++;
+ walk = walk->next;
+ selection_list_len++;
+ }
+
+ /* -q doesn't allow multiple occurences */
+ if (has_quick_pid > 1) {
+ fprintf(stderr, "q/-q/--quick-pid can only be used once.\n");
+ exit(1);
+ }
+
+ /* -q doesn't allow combinations with other selection switches */
+ if (has_quick_pid && selection_list_len > has_quick_pid) {
+ fprintf(stderr, "q/-q/--quick-pid cannot be combined with other selection options.\n");
+ exit(1);
+ }
+
+ /* -q cannot be used with forest type listings */
+ if (has_quick_pid && forest_type) {
+ fprintf(stderr, "q/-q/--quick-pid cannot be used together with forest type listings.\n");
+ exit(1);
+ }
+
+ /* -q cannot be used with sort */
+ if (has_quick_pid && sort_list) {
+ fprintf(stderr, "q/-q,--quick-pid cannot be used together with sort options.\n");
+ exit(1);
+ }
+
+ /* -q cannot be used with -N */
+ if (has_quick_pid && negate_selection) {
+ fprintf(stderr, "q/-q/--quick-pid cannot be used together with negation switches.\n");
+ exit(1);
+ }
+
+}
/***** no comment */
int main(int argc, char *argv[]){
reset_global(); /* must be before parser */
arg_parse(argc,argv);
+ /* check for invalid combination of arguments */
+ arg_check_conflicts();
+
/* arg_show(); */
trace("screen is %ux%u\n",screen_cols,screen_rows);
/* printf("sizeof(proc_t) is %d.\n", sizeof(proc_t)); */
fputs(_(" -C <command> command name\n"), out);
fputs(_(" -G, --Group <GID> real group id or name\n"), out);
fputs(_(" -g, --group <group> session or effective group name\n"), out);
- fputs(_(" -p, --pid <PID> process id\n"), out);
- fputs(_(" --ppid <PID> select by parent process id\n"), out);
+ fputs(_(" -p, p, --pid <PID> process id\n"), out);
+ fputs(_(" --ppid <PID> parent process id\n"), out);
+ fputs(_(" -q, q, --quick-pid <PID>\n"
+ " process id (quick mode)\n"), out);
fputs(_(" -s, --sid <session> session id\n"), out);
fputs(_(" -t, t, --tty <tty> terminal\n"), out);
fputs(_(" -u, U, --user <UID> effective user id or name\n"), out);
if(err) return err;
selection_list->typecode = SEL_PID;
return NULL; /* can't have any more options */
+ case 'q': /* end */
+ trace("-q quick select by PID.\n");
+ arg=get_opt_arg();
+ if(!arg) return "List of process IDs must follow -q.";
+ err=parse_list(arg, parse_pid);
+ if(err) return err;
+ selection_list->typecode = SEL_PID_QUICK;
+ return NULL; /* can't have any more options */
#if 0
case 'r':
trace("-r some Digital Unix thing about warnings...\n");
if(err) return err;
selection_list->typecode = SEL_PID;
return NULL; /* can't have any more options */
+ case 'q': /* end */
+ trace("q Quick select by process ID\n");
+ arg=get_opt_arg();
+ if(!arg) return "List of process IDs must follow q.";
+ err=parse_list(arg, parse_pid);
+ if(err) return err;
+ selection_list->typecode = SEL_PID_QUICK;
+ return NULL; /* can't have any more options */
case 'r':
trace("r select running processes\n");
running_only = 1;
{"noheadings", &&case_noheadings},
{"pid", &&case_pid},
{"ppid", &&case_ppid},
+ {"quick-pid", &&case_pid_quick},
{"rows", &&case_rows},
{"sid", &&case_sid},
{"sort", &&case_sort},
if(err) return err;
selection_list->typecode = SEL_PID;
return NULL;
+ case_pid_quick:
+ trace("--quick-pid\n");
+ arg = grab_gnu_arg();
+ if(!arg) return "List of process IDs must follow --quick-pid.";
+ err=parse_list(arg, parse_pid);
+ if(err) return err;
+ selection_list->typecode = SEL_PID_QUICK;
+ return NULL;
case_ppid:
trace("--ppid\n");
arg = grab_gnu_arg();
.B ps\ \-C\ syslogd\ \-o\ pid=
.TP
Print only the name of PID 42:
-.B ps\ \-p\ 42\ \-o\ comm=
+.B ps\ \-q\ 42\ \-o\ comm=
.PP
.PP
.\" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
That is, it selects processes that are children of those listed in
.IR pidlist .
.TP
+.BI q \ pidlist
+Select by process ID (quick mode). Identical to
+.B \-q
+and
+.BR \-\-quick\-pid .
+.TP
+.BI \-q \ pidlist
+Select by PID (quick mode). This selects the processes whose process ID numbers appear in
+.IR pidlist .
+With this option \fBps\fR reads the necessary info only
+for the pids listed in the \fIpidlist\fR and doesn't apply
+additional filtering rules. The order of pids is unsorted
+and preserved. No additional selection options, sorting
+and forest type listings are allowed in this mode.
+Identical to
+.B q
+and
+.BR \-\-quick\-pid .
+.TP
+.BI \-\-quick\-pid \ pidlist
+Select by process\ ID (quick mode). Identical to
+.B \-q
+and
+.BR q .
+.TP
.BI \-s \ sesslist
Select by session ID. This selects the processes with a session ID specified
in
break; case SEL_PGRP: return_if_match(pgrp,pid);
break; case SEL_PID : return_if_match(tgid,pid);
+ break; case SEL_PID_QUICK : return_if_match(tgid,pid);
break; case SEL_PPID: return_if_match(ppid,ppid);
break; case SEL_TTY : return_if_match(tty,tty);
break; case SEL_SESS: return_if_match(session,pid);