2 * proc.c - common process and file structure functions for lsof
7 * Copyright 1994 Purdue Research Foundation, West Lafayette, Indiana
8 * 47907. All rights reserved.
10 * Written by Victor A. Abell
12 * This software is not subject to any license of the American Telephone
13 * and Telegraph Company or the Regents of the University of California.
15 * Permission is granted to anyone to use this software for any purpose on
16 * any computer system, and to alter it and redistribute it freely, subject
17 * to the following restrictions:
19 * 1. Neither the authors nor Purdue University are responsible for any
20 * consequences of the use of this software.
22 * 2. The origin of this software must not be misrepresented, either by
23 * explicit claim or by omission. Credit to the authors and Purdue
24 * University must appear in documentation and sources.
26 * 3. Altered versions must be plainly marked as such, and must not be
27 * misrepresented as being the original software.
29 * 4. This notice may not be removed or altered.
33 static char copyright[] =
34 "@(#) Copyright 1994 Purdue Research Foundation.\nAll rights reserved.\n";
35 static char *rcsid = "$Id: proc.c,v 1.48 2014/10/13 22:36:20 abe Exp $";
43 * Local function prototypes
46 _PROTOTYPE(static int is_file_sel,(struct lproc *lp, struct lfile *lf));
50 * add_nma() - add to NAME column addition
55 char *cp; /* string to add */
56 int len; /* string length */
63 nl = (int)strlen(Lf->nma);
64 Lf->nma = (char *)realloc((MALLOC_P *)Lf->nma,
65 (MALLOC_S)(len + nl + 2));
68 Lf->nma = (char *)malloc((MALLOC_S)(len + 1));
71 (void) fprintf(stderr, "%s: no name addition space: PID %ld, FD %s",
72 Pn, (long)Lp->pid, Lf->fd);
77 (void) strncpy(&Lf->nma[nl + 1], cp, len);
78 Lf->nma[nl + 1 + len] = '\0';
80 (void) strncpy(Lf->nma, cp, len);
86 #if defined(HASFSTRUCT)
87 _PROTOTYPE(static char *alloc_fflbuf,(char **bp, int *al, int lr));
91 * alloc_fflbuf() - allocate file flags print buffer
95 alloc_fflbuf(bp, al, lr)
96 char **bp; /* current buffer pointer */
97 int *al; /* current allocated length */
98 int lr; /* length required */
102 sz = (int)(lr + 1); /* allocate '\0' space */
103 if (*bp && (sz <= *al))
106 *bp = (char *)realloc((MALLOC_P *)*bp, (MALLOC_S)sz);
108 *bp = (char *)malloc((MALLOC_S)sz);
110 (void) fprintf(stderr, "%s: no space (%d) for print flags\n",
117 #endif /* defined(HASFSTRUCT) */
121 * alloc_lfile() - allocate local file structure space
126 char *nm; /* file descriptor name (may be NULL) */
127 int num; /* file descriptor number -- -1 if
134 * If reusing a previously allocated structure, release any allocated
135 * space it was using.
138 (void) free((FREE_P *)Lf->dev_ch);
140 (void) free((FREE_P *)Lf->nm);
142 (void) free((FREE_P *)Lf->nma);
144 #if defined(HASLFILEADD) && defined(CLRLFILEADD)
146 #endif /* defined(HASLFILEADD) && defined(CLRLFILEADD) */
149 * Othwerise, allocate a new structure.
151 } else if (!(Lf = (struct lfile *)malloc(sizeof(struct lfile)))) {
152 (void) fprintf(stderr, "%s: no local file space at PID %d\n",
157 * Initialize the structure.
159 Lf->access = Lf->lock = ' ';
160 Lf->dev_def = Lf->inp_ty = Lf->is_com = Lf->is_nfs = Lf->is_stream
161 = Lf->lmi_srch = Lf->nlink_def = Lf->off_def = Lf->sz_def
164 Lf->li[0].af = Lf->li[1].af = 0;
168 #if defined(HASMNTSTAT)
169 Lf->mnt_stat = (unsigned char)0;
170 #endif /* defined(HASMNTSTAT) */
172 #if defined(HASEPTOPTS)
174 #endif /* defined(HASEPTOPTS) */
176 #if defined(HASSOOPT)
177 Lf->lts.kai = Lf->lts.ltm = 0;
178 Lf->lts.opt = Lf->lts.qlen = Lf->lts.qlim = Lf->lts.pqlen
180 Lf->lts.rbsz = Lf->lts.sbsz = (unsigned long)0;
181 Lf->lts.qlens = Lf->lts.qlims = Lf->lts.pqlens = Lf->lts.rbszs
182 = Lf->lts.sbszs = (unsigned char)0;
183 #endif /* defined(HASSOOPT) */
185 #if defined(HASSOSTATE)
187 #endif /* defined(HASSOSTATE) */
189 #if defined(HASTCPOPT)
190 Lf->lts.mss = (unsigned long)0;
191 Lf->lts.msss = (unsigned char)0;
192 Lf->lts.topt = (unsigned int)0;
193 #endif /* defined(HASTCPOPT) */
195 #if defined(HASTCPTPIQ)
196 Lf->lts.rqs = Lf->lts.sqs = (unsigned char)0;
197 #endif /* defined(HASTCPTPIQ) */
199 #if defined(HASTCPTPIW)
200 Lf->lts.rws = Lf->lts.wws = (unsigned char)0;
201 #endif /* defined(HASTCPTPIW) */
203 #if defined(HASFSINO)
205 #endif /* defined(HASFSINO) */
207 #if defined(HASVXFS) && defined(HASVXFSDNLC)
209 #endif /* defined(HASVXFS) && defined(HASVXFSDNLC) */
211 Lf->inode = (INODETYPE)0;
212 Lf->off = (SZOFFTYPE)0;
213 if (Lp->pss & PS_PRI)
217 Lf->iproto[0] = Lf->type[0] = '\0';
219 (void) strncpy(Lf->fd, nm, FDLEN - 1);
220 Lf->fd[FDLEN - 1] = '\0';
221 } else if (num >= 0) {
223 (void) snpf(Lf->fd, sizeof(Lf->fd), "%4d", num);
225 (void) snpf(Lf->fd, sizeof(Lf->fd), "*%03d", num % 1000);
228 Lf->dev_ch = Lf->fsdir = Lf->fsdev = Lf->nm = Lf->nma = (char *)NULL;
231 #if defined(HASNCACHE) && HASNCACHE<2
233 #endif /* defined(HASNCACHE) && HASNCACHE<2 */
235 Lf->next = (struct lfile *)NULL;
236 Lf->ntype = Ntype = N_REGLR;
239 #if defined(HASFSTRUCT)
240 Lf->fct = Lf->ffg = Lf->pof = (long)0;
241 Lf->fna = (KA_T)NULL;
242 Lf->fsv = (unsigned char)0;
243 #endif /* defined(HASFSTRUCT) */
245 #if defined(HASLFILEADD) && defined(SETLFILEADD)
247 * Do local initializations.
250 #endif /* defined(HASLFILEADD) && defined(SETLFILEADD) */
253 * See if the file descriptor has been selected.
255 if (!Fdl || (!nm && num < 0))
257 fds = ck_fd_status(nm, num);
259 case 0: /* inclusion list */
263 case 1: /* exclusion list */
271 * alloc_lproc() - allocate local proc structure space
275 alloc_lproc(pid, pgid, ppid, uid, cmd, pss, sf)
276 int pid; /* Process ID */
277 int pgid; /* process group ID */
278 int ppid; /* parent process ID */
279 UID_ARG uid; /* User ID */
280 char *cmd; /* command */
281 int pss; /* process select state */
282 int sf; /* process select flags */
287 if (!(Lproc = (struct lproc *)malloc(
288 (MALLOC_S)(LPROCINCR * sizeof(struct lproc)))))
290 (void) fprintf(stderr,
291 "%s: no malloc space for %d local proc structures\n",
296 } else if ((Nlproc + 1) > sz) {
298 if (!(Lproc = (struct lproc *)realloc((MALLOC_P *)Lproc,
299 (MALLOC_S)(sz * sizeof(struct lproc)))))
301 (void) fprintf(stderr,
302 "%s: no realloc space for %d local proc structures\n",
307 Lp = &Lproc[Nlproc++];
310 #if defined(HASEPTOPTS)
312 #endif /* defined(HASEPTOPTS) */
314 #if defined(HASTASKS)
316 #endif /* defined(HASTASKS) */
320 Lp->file = (struct lfile *)NULL;
322 Lp->pss = (short)pss;
323 Lp->uid = (uid_t)uid;
325 * Allocate space for the full command name and copy it there.
327 if (!(Lp->cmd = mkstrcpy(cmd, (MALLOC_S *)NULL))) {
328 (void) fprintf(stderr, "%s: PID %d, no space for command name: ",
330 safestrprt(cmd, stderr, 1);
334 #if defined(HASZONES)
336 * Clear the zone name pointer. The dialect's own code will set it.
338 Lp->zn = (char *)NULL;
339 #endif /* defined(HASZONES) */
341 #if defined(HASSELINUX)
343 * Clear the security context pointer. The dialect's own code will
346 Lp->cntx = (char *)NULL;
347 #endif /* defined(HASSELINUX) */
353 * ck_fd_status() - check FD status
355 * return: 0 == FD is neither included nor excluded
356 * 1 == FD is excluded
357 * 2 == FD is included
361 ck_fd_status(nm, num)
362 char *nm; /* file descriptor name (may be NULL) */
363 int num; /* file descriptor number -- -1 if
369 if (!(fp = Fdl) || (!nm && num < 0))
372 while (*cp && *cp == ' ')
376 * Check for an exclusion match.
379 for (; fp; fp = fp->next) {
381 if (fp->nm && strcmp(fp->nm, cp) == 0)
385 if (num >= fp->lo && num <= fp->hi)
391 * If Fdl isn't an exclusion list, check for an inclusion match.
393 for (; fp; fp = fp->next) {
395 if (fp->nm && strcmp(fp->nm, cp) == 0)
399 if (num >= fp->lo && num <= fp->hi)
407 * comppid() - compare PIDs
414 struct lproc **p1 = (struct lproc **)a1;
415 struct lproc **p2 = (struct lproc **)a2;
417 if ((*p1)->pid < (*p2)->pid)
419 if ((*p1)->pid > (*p2)->pid)
422 #if defined(HASTASKS)
423 if ((*p1)->tid < (*p2)->tid)
425 if ((*p1)->tid > (*p2)->tid)
427 #endif /* defined(HASTASKS) */
434 * ent_inaddr() - enter Internet addresses
438 ent_inaddr(la, lp, fa, fp, af)
439 unsigned char *la; /* local Internet address */
440 int lp; /* local port */
441 unsigned char *fa; /* foreign Internet address -- may
442 * be NULL to indicate no foreign
443 * address is known */
444 int fp; /* foreign port */
445 int af; /* address family -- e.g, AF_INET,
455 Lf->li[0].ia.a6 = *(struct in6_addr *)la;
457 #endif /* defined(HASIPv6) */
459 Lf->li[0].ia.a4 = *(struct in_addr *)la;
468 Lf->li[1].ia.a6 = *(struct in6_addr *)fa;
470 #endif /* defined(HASIPv6) */
472 Lf->li[1].ia.a4 = *(struct in_addr *)fa;
477 * If network address matching has been selected, check both addresses.
479 if ((Selflags & SELNA) && Nwad) {
480 m = (fa && is_nw_addr(fa, fp, af)) ? 1 : 0;
481 m |= (la && is_nw_addr(la, lp, af)) ? 1 : 0;
489 * examine_lproc() - examine local process
491 * return: 1 = last process
502 * List the process if the process is selected and:
504 * o listing is limited to a single PID selection -- this one;
506 * o listing is selected by an ANDed option set (not all options)
507 * that includes a single PID selection -- this one.
509 if ((Lp->sf & SELPID) && !Selall) {
510 if ((Selflags == SELPID)
511 || (Fand && (Selflags & SELPID))) {
516 if (Lp->pss && Npid == 1 && sbp) {
525 * Deprecate an unselected (or listed) process.
528 (void) free_lproc(Lp);
532 * Indicate last-process if listing is limited to PID selections,
533 * and all selected processes have been listed.
535 return((sbp && Npuns == 0) ? 1 : 0);
540 * free_lproc() - free lproc entry and its associated malloc'd space
547 struct lfile *lf, *nf;
549 for (lf = lp->file; lf; lf = nf) {
551 (void) free((FREE_P *)lf->dev_ch);
552 lf->dev_ch = (char *)NULL;
555 (void) free((FREE_P *)lf->nm);
556 lf->nm = (char *)NULL;
559 (void) free((FREE_P *)lf->nma);
560 lf->nma = (char *)NULL;
563 #if defined(HASLFILEADD) && defined(CLRLFILEADD)
565 #endif /* defined(HASLFILEADD) && defined(CLRLFILEADD) */
568 (void) free((FREE_P *)lf);
570 lp->file = (struct lfile *)NULL;
572 (void) free((FREE_P *)lp->cmd);
573 lp->cmd = (char *)NULL;
579 * is_cmd_excl() - is command excluded?
583 is_cmd_excl(cmd, pss, sf)
584 char *cmd; /* command name */
585 short *pss; /* process state */
586 short *sf; /* process select flags */
591 * See if the command is excluded by a "-c^<command>" option.
594 for (sp = Cmdl; sp; sp = sp->next) {
595 if (sp->x && !strncmp(sp->str, cmd, sp->len))
600 * The command is not excluded if no command selection was requested,
601 * or if its name matches any -c <command> specification.
604 if ((Selflags & SELCMD) == 0)
606 for (sp = Cmdl; sp; sp = sp->next) {
607 if (!sp->x && !strncmp(sp->str, cmd, sp->len)) {
615 * The command name doesn't match any -c <command> specification. See if it
616 * matches a -c /RE/[bix] specification.
618 for (i = 0; i < NCmdRxU; i++) {
619 if (!regexec(&CmdRx[i].cx, cmd, 0, NULL, 0)) {
627 * The command name matches no -c specification.
629 * It's excluded if the only selection condition is command name,
630 * or if command name selection is part of an ANDed set.
632 if (Selflags == SELCMD)
634 return (Fand ? 1 : 0);
639 * is_file_sel() - is file selected?
644 struct lproc *lp; /* lproc structure pointer */
645 struct lfile *lf; /* lfile structure pointer */
649 if (Lf->sf & SELEXCLF)
652 #if defined(HASSECURITY) && defined(HASNOSOCKSECURITY)
653 if (Myuid && (Myuid != lp->uid)) {
654 if (!(lf->sf & (SELNA | SELNET)))
657 #endif /* defined(HASSECURITY) && defined(HASNOSOCKSECURITY) */
661 if (Fand && ((lf->sf & Selflags) != Selflags))
668 * is_proc_excl() - is process excluded?
673 #if defined(HASTASKS)
674 is_proc_excl(pid, pgid, uid, pss, sf, tid)
675 #else /* !defined(HASTASKS) */
676 is_proc_excl(pid, pgid, uid, pss, sf)
677 #endif /* defined(HASTASKS) */
679 int pid; /* Process ID */
680 int pgid; /* process group ID */
681 UID_ARG uid; /* User ID */
682 short *pss; /* process select state for lproc */
683 short *sf; /* select flags for lproc */
685 #if defined(HASTASKS)
686 int tid; /* task ID (not a task if zero) */
687 #endif /* defined(HASTASKS) */
694 #if defined(HASSECURITY)
696 * The process is excluded by virtue of the security option if it
697 * isn't owned by the owner of this lsof process, unless the
698 * HASNOSOCKSECURITY option is also specified. In that case the
699 * selected socket files of any process may be listed.
701 # if !defined(HASNOSOCKSECURITY)
702 if (Myuid && Myuid != (uid_t)uid)
704 # endif /* !defined(HASNOSOCKSECURITY) */
705 #endif /* defined(HASSECURITY) */
708 * If the excluding of process listing by UID has been specified, see if the
709 * owner of this process is excluded.
712 for (i = j = 0; (i < Nuid) && (j < Nuidexcl); i++) {
715 if (Suid[i].uid == (uid_t)uid)
721 * If the excluding of process listing by PGID has been specified, see if this
725 for (i = j = 0; (i < Npgid) && (j < Npgidx); i++) {
728 if (Spgid[i].i == pgid)
734 * If the excluding of process listing by PID has been specified, see if this
738 for (i = j = 0; (i < Npid) && (j < Npidx); i++) {
741 if (Spid[i].i == pid)
747 * If the listing of all processes is selected, then this one is not excluded.
749 * However, if HASSECURITY and HASNOSOCKSECURITY are both specified, exclude
750 * network selections from the file flags, so that the tests in is_file_sel()
756 #if defined(HASSECURITY) && defined(HASNOSOCKSECURITY)
757 *sf = SELALL & ~(SELNA | SELNET);
758 #else /* !defined(HASSECURITY) || !defined(HASNOSOCKSECURITY) */
760 #endif /* defined(HASSECURITY) && defined(HASNOSOCKSECURITY) */
765 * If the listing of processes has been specified by process group ID, see
766 * if this one is included or excluded.
768 if (Npgidi && (Selflags & SELPGID)) {
769 for (i = j = 0; (i < Npgid) && (j < Npgidi); i++) {
772 if (Spgid[i].i == pgid) {
776 if (Selflags == SELPGID)
782 if ((Selflags == SELPGID) && !*sf)
786 * If the listing of processes has been specified by PID, see if this one is
787 * included or excluded.
789 if (Npidi && (Selflags & SELPID)) {
790 for (i = j = 0; (i < Npid) && (j < Npidi); i++) {
793 if (Spid[i].i == pid) {
797 if (Selflags == SELPID)
803 if ((Selflags == SELPID) && !*sf)
807 * If the listing of processes has been specified by UID, see if the owner of
808 * this process has been included.
810 if (Nuidincl && (Selflags & SELUID)) {
811 for (i = j = 0; (i < Nuid) && (j < Nuidincl); i++) {
814 if (Suid[i].uid == (uid_t)uid) {
818 if (Selflags == SELUID)
824 if (Selflags == SELUID && (*sf & SELUID) == 0)
828 #if defined(HASTASKS)
829 if ((Selflags & SELTASK) && tid) {
832 * This is a task and tasks are selected.
836 if ((Selflags == SELTASK)
837 || (Fand && ((*sf & Selflags) == Selflags)))
840 #endif /* defined(HASTASKS) */
843 * When neither the process group ID, nor the PID, nor the task, nor the UID
846 * If list option ANDing of process group IDs, PIDs, UIDs or tasks is
847 * specified, the process is excluded;
849 * Otherwise, it's not excluded by the tests of this function.
852 return((Fand && (Selflags & (SELPGID|SELPID|SELUID|SELTASK)))
855 * When the process group ID, PID, task or UID is selected and the process
856 * group ID, PID, task or UID list option has been specified:
858 * If list option ANDing has been specified, and the correct
859 * combination of selections are in place, reply that the process is no
862 * If list option ANDing has not been specified, reply that the
863 * process is not excluded by the tests of this function.
865 if (Selflags & (SELPGID|SELPID|SELUID|SELTASK)) {
867 return(((Selflags & (SELPGID|SELPID|SELUID|SELTASK)) != *sf)
872 * Finally, when neither the process group ID, nor the PID, nor the UID, nor
873 * the task is selected, and no applicable list option has been specified:
875 * If list option ANDing has been specified, this process is
878 * Otherwise, it isn't excluded by the tests of this function.
880 return(Fand ? 1 : 0);
885 * link_lfile() - link local file structures
891 if (Lf->sf & SELEXCLF)
894 #if defined(HASEPTOPTS)
896 * If endpoint info has been requested, clear the SELPINFO flag from the local
897 * file structure, since it was set only to insure this file would be linked.
898 * While this might leave no file selection flags set, a later call to the
899 * process_pinfo() function might set some. Also set the PS_PIPE flag for
902 * Also set the SELPINFO flag for the process.
908 #endif /* defined(HASEPTOPTS) */
916 if (Fnet && (Lf->sf & SELNET))
918 if (Fnfs && (Lf->sf & SELNFS))
920 if (Ftask && (Lf->sf & SELTASK))
922 Lf = (struct lfile *)NULL;
926 #if defined(HASEPTOPTS)
928 * process_pinfo() -- process pipe info, adding it to selected files and
929 * selecting pipe end files (if requested)
935 * 0 == process selected pipe
936 * 1 == process end point
939 struct lproc *ep; /* pipe endpoint process */
940 struct lfile *ef; /* pipe endpoint file */
941 int i; /* temporary index */
942 char nma[1024]; /* name addition buffer */
943 pinfo_t *pp; /* previous pipe info */
947 for (Lf = Lp->file; Lf; Lf = Lf->next) {
948 if ((Lf->ntype != N_FIFO) || (Lf->inp_ty != 1))
950 pp = (pinfo_t *)NULL;
955 * Process already selected pipe file.
957 if (is_file_sel(Lp, Lf)) {
960 * This file has been selected by some criterion other than its
961 * being a pipe. Look up the pipe's endpoints.
964 if ((pp = find_pendinfo(Lf, pp))) {
967 * This pipe endpoint is linked to the selected pipe
968 * file. Add its PID and FD to the name column
971 ep = &Lproc[pp->lpx];
973 for (i = 0; i < (FDLEN - 1); i++) {
974 if (ef->fd[i] != ' ')
977 (void) snpf(nma, sizeof(nma) - 1, "%d,%.*s,%s%c",
978 ep->pid, CmdLim, ep->cmd,&ef->fd[i],
980 (void) add_nma(nma, strlen(nma));
984 * Endpoint files have been selected, so mark this
985 * one for selection later.
988 ep->pipe |= PS_PIPE_END;
996 if (!is_file_sel(Lp, Lf) && Lf->pipend) {
999 * This is an unselected end point file. Select it and add
1000 * its end point information to its name column addition.
1005 if ((pp = find_pendinfo(Lf, pp))) {
1006 ep = &Lproc[pp->lpx];
1008 for (i = 0; i < (FDLEN - 1); i++) {
1009 if (ef->fd[i] != ' ')
1012 (void) snpf(nma, sizeof(nma) - 1, "%d,%.*s,%s%c",
1013 ep->pid, CmdLim, ep->cmd, &ef->fd[i],
1015 (void) add_nma(nma, strlen(nma));
1024 #endif /* defined(HASEPTOPTS) */
1027 #if defined(HASFSTRUCT)
1029 * print_fflags() - print interpreted f_flag[s]
1033 print_fflags(ffg, pof)
1034 long ffg; /* file structure's flags value */
1035 long pof; /* process open files flags value */
1039 static char *bp = (char *)NULL;
1046 * Reduce the supplied flags according to the definitions in Pff_tab[] and
1049 for (ct = fx = 0; fx < 2; fx++) {
1061 for (; wf && !FsvFlagX; ct += al ) {
1069 al = (int)strlen(tp->nm) + sepl;
1070 bp = alloc_fflbuf(&bp, &bl, al + ct);
1071 (void) snpf(bp + ct, al + 1, "%s%s", sep, tp->nm);
1077 * If flag bits remain, print them in hex. If hex output was
1078 * specified with +fG, print all flag values, including zero,
1081 if (wf || FsvFlagX) {
1082 (void) snpf(xbuf, sizeof(xbuf), "0x%lx", wf);
1083 al = (int)strlen(xbuf) + sepl;
1084 bp = alloc_fflbuf(&bp, &bl, al + ct);
1085 (void) snpf(bp + ct, al + 1, "%s%s", sep, xbuf);
1090 * Make sure there is at least a NUL terminated reply.
1093 bp = alloc_fflbuf(&bp, &bl, 0);
1098 #endif /* defined(HASFSTRUCT) */
1102 * print_proc() - print process
1109 int lc, len, st, ty;
1113 * If nothing in the process has been selected, skip it.
1118 if (Lp->pid == LastPid) /* eliminate duplicates */
1122 * The mode is terse and something in the process appears to have
1123 * been selected. Make sure of that by looking for a selected file,
1124 * so that the HASSECURITY and HASNOSOCKSECURITY option combination
1125 * won't produce a false positive result.
1127 for (Lf = Lp->file; Lf; Lf = Lf->next) {
1128 if (is_file_sel(Lp, Lf)) {
1129 (void) printf("%d\n", Lp->pid);
1136 * If fields have been selected, output the process-only ones, provided
1137 * that some file has also been selected.
1140 for (Lf = Lp->file; Lf; Lf = Lf->next) {
1141 if (is_file_sel(Lp, Lf))
1147 (void) printf("%c%d%c", LSOF_FID_PID, Lp->pid, Terminator);
1149 #if defined(HASTASKS)
1150 if (FieldSel[LSOF_FIX_TID].st && Lp->tid)
1151 (void) printf("%c%d%c", LSOF_FID_TID, Lp->tid, Terminator);
1152 #endif /* defined(HASTASKS) */
1154 #if defined(HASZONES)
1155 if (FieldSel[LSOF_FIX_ZONE].st && Fzone && Lp->zn)
1156 (void) printf("%c%s%c", LSOF_FID_ZONE, Lp->zn, Terminator);
1157 #endif /* defined(HASZONES) */
1159 #if defined(HASSELINUX)
1160 if (FieldSel[LSOF_FIX_CNTX].st && Fcntx && Lp->cntx && CntxStatus)
1161 (void) printf("%c%s%c", LSOF_FID_CNTX, Lp->cntx, Terminator);
1162 #endif /* defined(HASSELINUX) */
1164 if (FieldSel[LSOF_FIX_PGID].st && Fpgid)
1165 (void) printf("%c%d%c", LSOF_FID_PGID, Lp->pgid, Terminator);
1167 #if defined(HASPPID)
1168 if (FieldSel[LSOF_FIX_PPID].st && Fppid)
1169 (void) printf("%c%d%c", LSOF_FID_PPID, Lp->ppid, Terminator);
1170 #endif /* defined(HASPPID) */
1172 if (FieldSel[LSOF_FIX_CMD].st) {
1173 putchar(LSOF_FID_CMD);
1174 safestrprt(Lp->cmd ? Lp->cmd : "(unknown)", stdout, 0);
1175 putchar(Terminator);
1177 if (FieldSel[LSOF_FIX_UID].st)
1178 (void) printf("%c%d%c", LSOF_FID_UID, (int)Lp->uid, Terminator);
1179 if (FieldSel[LSOF_FIX_LOGIN].st) {
1180 cp = printuid((UID_ARG)Lp->uid, &ty);
1182 (void) printf("%c%s%c", LSOF_FID_LOGIN, cp, Terminator);
1184 if (Terminator == '\0')
1190 for (Lf = Lp->file; Lf; Lf = Lf->next) {
1191 if (!is_file_sel(Lp, Lf))
1195 * If no field output selected, print dialect-specific formatted
1203 if (FieldSel[LSOF_FIX_FD].st) {
1206 * Skip leading spaces in the file descriptor. Print the field
1207 * identifier even if there are no characters after leading
1210 for (cp = Lf->fd; *cp == ' '; cp++)
1212 (void) printf("%c%s%c", LSOF_FID_FD, cp, Terminator);
1216 * Print selected fields.
1218 if (FieldSel[LSOF_FIX_ACCESS].st) {
1219 (void) printf("%c%c%c",
1220 LSOF_FID_ACCESS, Lf->access, Terminator);
1223 if (FieldSel[LSOF_FIX_LOCK].st) {
1224 (void) printf("%c%c%c", LSOF_FID_LOCK, Lf->lock, Terminator);
1227 if (FieldSel[LSOF_FIX_TYPE].st) {
1228 for (cp = Lf->type; *cp == ' '; cp++)
1231 (void) printf("%c%s%c", LSOF_FID_TYPE, cp, Terminator);
1236 #if defined(HASFSTRUCT)
1237 if (FieldSel[LSOF_FIX_FA].st && (Fsv & FSV_FA)
1238 && (Lf->fsv & FSV_FA)) {
1239 (void) printf("%c%s%c", LSOF_FID_FA,
1240 print_kptr(Lf->fsa, (char *)NULL, 0), Terminator);
1243 if (FieldSel[LSOF_FIX_CT].st && (Fsv & FSV_CT)
1244 && (Lf->fsv & FSV_CT)) {
1245 (void) printf("%c%ld%c", LSOF_FID_CT, Lf->fct, Terminator);
1248 if (FieldSel[LSOF_FIX_FG].st && (Fsv & FSV_FG)
1249 && (Lf->fsv & FSV_FG) && (FsvFlagX || Lf->ffg || Lf->pof)) {
1250 (void) printf("%c%s%c", LSOF_FID_FG,
1251 print_fflags(Lf->ffg, Lf->pof), Terminator);
1254 if (FieldSel[LSOF_FIX_NI].st && (Fsv & FSV_NI)
1255 && (Lf->fsv & FSV_NI)) {
1256 (void) printf("%c%s%c", LSOF_FID_NI,
1257 print_kptr(Lf->fna, (char *)NULL, 0), Terminator);
1260 #endif /* defined(HASFSTRUCT) */
1262 if (FieldSel[LSOF_FIX_DEVCH].st && Lf->dev_ch && Lf->dev_ch[0]) {
1263 for (cp = Lf->dev_ch; *cp == ' '; cp++)
1266 (void) printf("%c%s%c", LSOF_FID_DEVCH, cp, Terminator);
1270 if (FieldSel[LSOF_FIX_DEVN].st && Lf->dev_def) {
1271 if (sizeof(unsigned long) > sizeof(dev_t))
1272 ul = (unsigned long)((unsigned int)Lf->dev);
1274 ul = (unsigned long)Lf->dev;
1275 (void) printf("%c0x%lx%c", LSOF_FID_DEVN, ul, Terminator);
1278 if (FieldSel[LSOF_FIX_RDEV].st && Lf->rdev_def) {
1279 if (sizeof(unsigned long) > sizeof(dev_t))
1280 ul = (unsigned long)((unsigned int)Lf->rdev);
1282 ul = (unsigned long)Lf->rdev;
1283 (void) printf("%c0x%lx%c", LSOF_FID_RDEV, ul, Terminator);
1286 if (FieldSel[LSOF_FIX_SIZE].st && Lf->sz_def) {
1287 putchar(LSOF_FID_SIZE);
1289 #if defined(HASPRINTSZ)
1290 cp = HASPRINTSZ(Lf);
1291 #else /* !defined(HASPRINTSZ) */
1292 (void) snpf(buf, sizeof(buf), SzOffFmt_d, Lf->sz);
1294 #endif /* defined(HASPRINTSZ) */
1296 (void) printf("%s", cp);
1297 putchar(Terminator);
1300 if (FieldSel[LSOF_FIX_OFFSET].st && Lf->off_def) {
1301 putchar(LSOF_FID_OFFSET);
1303 #if defined(HASPRINTOFF)
1304 cp = HASPRINTOFF(Lf, 0);
1305 #else /* !defined(HASPRINTOFF) */
1306 (void) snpf(buf, sizeof(buf), SzOffFmt_0t, Lf->off);
1308 #endif /* defined(HASPRINTOFF) */
1311 if (OffDecDig && len > (OffDecDig + 2)) {
1313 #if defined(HASPRINTOFF)
1314 cp = HASPRINTOFF(Lf, 1);
1315 #else /* !defined(HASPRINTOFF) */
1316 (void) snpf(buf, sizeof(buf), SzOffFmt_x, Lf->off);
1318 #endif /* defined(HASPRINTOFF) */
1321 (void) printf("%s", cp);
1322 putchar(Terminator);
1325 if (FieldSel[LSOF_FIX_INODE].st && Lf->inp_ty == 1) {
1326 putchar(LSOF_FID_INODE);
1327 (void) printf(InodeFmt_d, Lf->inode);
1328 putchar(Terminator);
1331 if (FieldSel[LSOF_FIX_NLINK].st && Lf->nlink_def) {
1332 (void) printf("%c%ld%c", LSOF_FID_NLINK, Lf->nlink, Terminator);
1335 if (FieldSel[LSOF_FIX_PROTO].st && Lf->inp_ty == 2) {
1336 for (cp = Lf->iproto; *cp == ' '; cp++)
1339 (void) printf("%c%s%c", LSOF_FID_PROTO, cp, Terminator);
1343 if (FieldSel[LSOF_FIX_STREAM].st && Lf->nm && Lf->is_stream) {
1344 if (strncmp(Lf->nm, "STR:", 4) == 0
1345 || strcmp(Lf->iproto, "STR") == 0) {
1346 putchar(LSOF_FID_STREAM);
1348 putchar(Terminator);
1353 if (st == 0 && FieldSel[LSOF_FIX_NAME].st) {
1354 putchar(LSOF_FID_NAME);
1356 putchar(Terminator);
1359 if (Lf->lts.type >= 0 && FieldSel[LSOF_FIX_TCPTPI].st) {
1363 if (Terminator == '\0' && lc)