1/*
2 * LTbigf.c -- Lsof Test big file size and offset tests
3 *
4 * V. Abell
5 * Purdue University
6 */
7
8
9/*
10 * Copyright 2002 Purdue Research Foundation, West Lafayette, Indiana
11 * 47907.  All rights reserved.
12 *
13 * Written by V. Abell.
14 *
15 * This software is not subject to any license of the American Telephone
16 * and Telegraph Company or the Regents of the University of California.
17 *
18 * Permission is granted to anyone to use this software for any purpose on
19 * any computer system, and to alter it and redistribute it freely, subject
20 * to the following restrictions:
21 *
22 * 1. Neither the authors nor Purdue University are responsible for any
23 *    consequences of the use of this software.
24 *
25 * 2. The origin of this software must not be misrepresented, either by
26 *    explicit claim or by omission.  Credit to the authors and Purdue
27 *    University must appear in documentation and sources.
28 *
29 * 3. Altered versions must be plainly marked as such, and must not be
30 *    misrepresented as being the original software.
31 *
32 * 4. This notice may not be removed or altered.
33 */
34
35#ifndef lint
36static char copyright[] =
37"@(#) Copyright 2002 Purdue Research Foundation.\nAll rights reserved.\n";
38#endif
39
40#include "LsofTest.h"
41
42#if	!defined(LT_BIGF)
43
44/*
45 * Here begins the version of this program for dialects that don't support
46 * large files.
47 */
48
49
50/*
51 * Main program for dialects that don't support large files
52 */
53
54int
55main(argc, argv)
56	int argc;			/* argument count */
57	char *argv[];			/* arguments */
58{
59    char *pn;			/* program name */
60/*
61 * Get program name and issue start and exit message.
62 */
63    if ((pn = (char *)strrchr(argv[0], '/')))
64	    pn++;
65    else
66	    pn = argv[0];
67
68    (void) printf("%s ... %s\n", pn, LT_DONT_DO_TEST);
69    return(0);
70}
71#else	/* defined(LT_BIGF) */
72
73/*
74 * Here begins the version of this program for dialects that support
75 * large files.
76 */
77
78#include "lsof_fields.h"
79
80
81/*
82 * Pre-definitions that may be changed by specific dialects
83 */
84
85#define	OFFTST_STAT	1		/* offset tests status */
86
87
88#if	defined(LT_DIAL_aix)
89/*
90 * AIX-specific definitions
91 */
92
93#define	OFFSET_T	off64_t		/* define offset type */
94#endif	/* defined(LT_DIAL_aix) */
95
96
97#if	defined(LT_DIAL_bsdi)
98/*
99 * BSDI-specific definitions
100 */
101
102#define	OFFSET_T	off_t		/* define offset type */
103#define	OPENF		open		/* define open function */
104#define	SEEKF		lseek		/* define seek function */
105#define	STATF		stat		/* define stat function */
106#define	STATS		struct stat	/* define stat structure */
107#endif	/* defined(LT_DIAL_bsdi) */
108
109
110#if	defined(LT_DIAL_darwin)
111/*
112 * Darwin-specific definitions
113 */
114
115# if	LT_VERS>=900
116#define	OFFSET_T	off_t		/* define offset type */
117#define	OPENF		open		/* define open function */
118#define	SEEKF		lseek		/* define seek function */
119#define	STATF		stat		/* define stat function */
120#define	STATS		struct stat	/* define stat structure */
121# endif	/* LT_VERS>=900 */
122#endif	/* defined(LT_DIAL_darwin) */
123
124
125#if	defined(LT_DIAL_du)
126/*
127 * DEC_OSF/1|Digital_UNIX|Tru64_UNIX-specific items
128 */
129
130#define	OFFSET_T	off_t		/* define offset type */
131#define	OPENF		open		/* define open function */
132#define	SEEKF		lseek		/* define seek function */
133#define	STATF		stat		/* define stat function */
134#define	STATS		struct stat	/* define stat structure */
135#endif	/* defined(LT_DIAL_du) */
136
137
138#if	defined(LT_DIAL_freebsd)
139/*
140 * FreeBSD-specific definitions
141 */
142
143#define	OFFSET_T	off_t		/* define offset type */
144#define	OPENF		open		/* define open function */
145#define	SEEKF		lseek		/* define seek function */
146#define	STATF		stat		/* define stat function */
147#define	STATS		struct stat	/* define stat structure */
148#endif	/* defined(LT_DIAL_freebsd) */
149
150
151#if	defined(LT_DIAL_linux)
152/*
153 * Linux-specific definitions
154 */
155
156#undef	OFFTST_STAT
157#define	OFFTST_STAT	0		/* Linux lsof may not be able to report
158					 * offsets -- see the function
159					 * ck_Linux_offset_support() */
160#define	OFFSET_T	off_t		/* define offset type */
161#define	OPENF		open		/* define open function */
162#define	SEEKF		lseek		/* define seek function */
163#define	STATF		stat		/* define stat function */
164#define	STATS		struct stat	/* define stat structure */
165
166_PROTOTYPE(static int ck_Linux_offset_support,(void));
167#endif	/* defined(LT_DIAL_linux) */
168
169
170#if	defined(LT_DIAL_hpux)
171/*
172 * HP-UX-specific definitions
173 */
174
175#define	OFFSET_T	off64_t		/* define offset type */
176#endif	/* defined(LT_DIAL_hpux) */
177
178
179#if	defined(LT_DIAL_netbsd)
180/*
181 * NetBSD-specific definitions
182 */
183
184#define	OFFSET_T	off_t		/* define offset type */
185#define	OPENF		open		/* define open function */
186#define	SEEKF		lseek		/* define seek function */
187#define	STATF		stat		/* define stat function */
188#define	STATS		struct stat	/* define stat structure */
189#endif	/* defined(LT_DIAL_netbsd) */
190
191
192#if	defined(LT_DIAL_openbsd)
193/*
194 * OpenBSD-specific definitions
195 */
196
197#define	OFFSET_T	off_t		/* define offset type */
198#define	OPENF		open		/* define open function */
199#define	SEEKF		lseek		/* define seek function */
200#define	STATF		stat		/* define stat function */
201#define	STATS		struct stat	/* define stat structure */
202#endif	/* defined(LT_DIAL_openbsd) */
203
204
205#if	defined(LT_DIAL_ou)
206/*
207 * OpenUNIX-specific items
208 */
209
210#include <signal.h>
211
212#define	IGNORE_SIGXFSZ
213#define	OFFSET_T	off64_t		/* define offset type */
214#endif	/* defined(LT_DIAL_ou) */
215
216
217#if	defined(LT_DIAL_solaris)
218/*
219 * Solaris-specific definitions
220 */
221
222#define	OFFSET_T	off64_t		/* define offset type */
223#endif	/* defined(LT_DIAL_solaris) */
224
225
226#if	defined(LT_DIAL_uw)
227/*
228 * UnixWare-specific items
229 */
230
231#include <signal.h>
232
233#define	IGNORE_SIGXFSZ
234#define	OFFSET_T	off64_t		/* define offset type */
235#endif	/* defined(LT_DIAL_uw) */
236
237
238/*
239 * Local definitions
240 */
241
242#if	!defined(OPENF)
243#define	OPENF		open64		/* open() function */
244#endif	/* !defined(OPENF) */
245
246#if	!defined(OFFSET_T)
247#define	OFFSET_T unsigned long long	/* offset type */
248#endif	/* !defined(OFFSET_T) */
249
250#if	!defined(SEEKF)
251#define	SEEKF		lseek64		/* seek() function */
252# endif	/* !defined(SEEKF) */
253
254#if	!defined(STATF)
255#define	STATF		stat64		/* stat(2) structure */
256#endif	/* !defined(STATF) */
257
258#if	!defined(STATS)
259#define	STATS		struct stat64	/* stat(2) structure */
260#endif	/* !defined(STATS) */
261
262#define	TST_OFFT	0		/* test offset in 0t decimal*/
263#define	TST_OFFX	1		/* test offset in hex */
264#define	TST_SZ		2		/* test size */
265
266
267/*
268 * Globals
269 */
270
271int Fd = -1;			/* test file descriptor; open if >= 0 */
272pid_t MyPid = (pid_t)0;		/* PID of this process */
273char *Path = (char *)NULL;	/* test file path; none if NULL */
274char *Pn = (char *)NULL;	/* program name */
275
276
277/*
278 * Local function prototypes
279 */
280
281_PROTOTYPE(static void cleanup,(void));
282_PROTOTYPE(static int tstwlsof,(int tt, char *opt, OFFSET_T sz));
283
284
285/*
286 * Main program for dialects that support large files
287 */
288
289int
290main(argc, argv)
291    int argc;				/* argument count */
292    char *argv[];			/* arguments */
293{
294    char buf[2048];			/* temporary buffer */
295    int do_offt = OFFTST_STAT;		/* do offset tests if == 1 */
296    char *em;				/* error message pointer */
297    int i;				/* temporary integer */
298    int len;				/* string length */
299    OFFSET_T sz = 0x140000000ll;	/* test file size */
300    char szbuf[64];			/* size buffer */
301    char *tcp;				/* temporary character pointer */
302    int tofft = 0;			/* 0t offset test result */
303    int toffx = 0;			/* 0x offset test result */
304    int tsz = 0;			/* size test result */
305    int xv = 0;				/* exit value */
306/*
307 * Get program name and PID, issue start message, and build space prefix.
308 */
309    if ((Pn = strrchr(argv[0], '/')))
310	Pn++;
311    else
312	Pn = argv[0];
313    MyPid = getpid();
314    (void) printf("%s ... ", Pn);
315    (void) fflush(stdout);
316    PrtMsg((char *)NULL, Pn);
317/*
318 * Process arguments.
319 */
320    if (ScanArg(argc, argv, "hp:", Pn))
321	xv = 1;
322    if (xv || LTopt_h) {
323	(void) PrtMsg("usage: [-h] [-p path]", Pn);
324	PrtMsg       ("       -h       print help (this panel)", Pn);
325	PrtMsgX      ("       -p path  define test file path", Pn, cleanup, xv);
326    }
327
328#if	defined(LT_DIAL_linux)
329/*
330 * If this is Linux, see if lsof can report file offsets.
331 */
332	do_offt = ck_Linux_offset_support();
333#endif	/* defined(LT_DIAL_linux) */
334
335/*
336 * See if lsof can be executed and can access kernel memory.
337 */
338    if ((em = IsLsofExec()))
339	(void) PrtMsgX(em, Pn, cleanup, 1);
340    if ((em = CanRdKmem()))
341	(void) PrtMsgX(em, Pn, cleanup, 1);
342/*
343 * Construct the path.  If LT_BIGSZOFF_PATH is defined in the environment,
344 * use it. otherwise construct a path in the CWD.
345 */
346    if (!(Path = LTopt_p)) {
347	(void) snprintf(buf, sizeof(buf), "./config.LTbigf%ld",
348	(long)MyPid);
349	buf[sizeof(buf) - 1] = '\0';
350	Path = MkStrCpy(buf, &len);
351    }
352/*
353 * Fill buffer for writing to the test file.
354 */
355    for (i = 0; i < sizeof(buf); i++) {
356	buf[i] = (char)(i & 0xff);
357    }
358
359#if	defined(IGNORE_SIGXFSZ)
360/*
361 * Ignore SIGXFSZ, if directed by a dialect-specific option.
362 */
363	(void) signal(SIGXFSZ, SIG_IGN);
364#endif	/* defined(IGNORE_SIGXFSZ) */
365
366/*
367 * Open a new test file at the specified path.
368 */
369    (void) unlink(Path);
370    if ((Fd = OPENF(Path, O_RDWR|O_CREAT, 0600)) < 0) {
371	(void) fprintf(stderr, "ERROR!!!  can't open %s\n", Path);
372
373print_hint:
374
375    /*
376     * Print a hint about the LT_BIGSZOFF_PATH environment variable.
377     */
378
379	MsgStat = 1;
380	(void) snprintf(buf, sizeof(buf) - 1, "      Errno %d: %s",
381	    errno, strerror(errno));
382	buf[sizeof(buf) - 1] = '\0';
383	(void) PrtMsg(buf, Pn);
384	(void) PrtMsg("Hint: try using \"-p path\" to supply a path in a", Pn);
385	(void) PrtMsg("file system that has large file support enabled.\n", Pn);
386	(void) PrtMsg("Hint: try raising the process ulimit file block", Pn);
387	(void) PrtMsg("size to a value that will permit this test to", Pn);
388	(void) snprintf(szbuf, sizeof(szbuf) - 1, "%lld", (long long)sz);
389	szbuf[sizeof(szbuf) - 1] = '\0';
390	(void) snprintf(buf, sizeof(buf) - 1,
391	    "write a file whose size appears to be %s", szbuf);
392	buf[sizeof(buf) - 1] = '\0';
393	(void) PrtMsg(buf, Pn);
394	(void) PrtMsg("bytes.  (The file really isn't that big -- it", Pn);
395	(void) PrtMsg("just has a large \"hole\" in its mid-section.)\n", Pn);
396	(void) PrtMsgX("See 00FAQ and 00TEST for more information.", Pn,
397		       cleanup, 1);
398    }
399/*
400 * Write a buffer load at the beginning of the file.
401 */
402    if (SEEKF(Fd, (OFFSET_T)0, SEEK_SET) < 0) {
403	(void) fprintf(stderr,
404	    "ERROR!!!  can't seek to the beginning of %s\n", Path);
405	goto print_hint;
406    }
407    if (write(Fd, buf, sizeof(buf)) != sizeof(buf)) {
408	(void) fprintf(stderr,
409	    "ERROR!!!  can't write %d bytes to the beginning of %s\n",
410	    (int)sizeof(buf), Path);
411	goto print_hint;
412    }
413/*
414 * Write a buffer load near the end of the file to bring it to the
415 * specified length.  Leave the file open so lsof can find it.
416 */
417    if (SEEKF(Fd, (OFFSET_T)(sz - sizeof(buf)), SEEK_SET) < 0) {
418	(void) snprintf(szbuf, sizeof(szbuf) - 1, "%lld",
419	    (unsigned long long)(sz - sizeof(buf)));
420	(void) fprintf(stderr, "ERROR!!!  can't seek to %s in %s\n", szbuf,
421	    Path);
422	goto print_hint;
423    }
424    if (write(Fd, buf, sizeof(buf)) != sizeof(buf)) {
425	(void) fprintf(stderr,
426	    "ERROR!!!  can't write %d bytes near the end of %s\n",
427	    (int)sizeof(buf), Path);
428	goto print_hint;
429    }
430/*
431 * Fsync() the file.
432 */
433    if (fsync(Fd)) {
434	(void) fprintf(stderr, "ERROR!!!  can't fsync %s\n", Path);
435	goto print_hint;
436    }
437
438/*
439 * If this dialect can't report offsets, disable the offset tests.
440 */
441    if (!do_offt) {
442	tofft = toffx = 1;
443	PrtMsg("WARNING!!!  lsof can't return file offsets for this dialect,",
444	    Pn);
445	PrtMsg("  so offset tests have been disabled.", Pn);
446    }
447/*
448 * Do file size test.
449 */
450    tsz = tstwlsof(TST_SZ, "-s", sz);
451/*
452 * If enabled, do offset tests.
453 */
454    if (!tofft)
455	tofft = tstwlsof(TST_OFFT, "-oo20", sz);
456    if (!toffx)
457	toffx = tstwlsof(TST_OFFX, "-oo2", sz);
458/*
459 * Compute exit value and exit.
460 */
461    if ((tsz != 1) || (tofft != 1) || (toffx != 1)) {
462	tcp = (char *)NULL;
463	xv = 1;
464    } else {
465	tcp = "OK";
466	xv = 0;
467    }
468    (void) PrtMsgX(tcp, Pn, cleanup, xv);
469    return(0);
470}
471
472
473#if	defined(LT_DIAL_linux)
474/*
475 * ck_Linux_offset_support() -- see if lsof can report offsets for this
476 *				Linux implementation
477 */
478
479static int
480ck_Linux_offset_support()
481{
482	char buf[1024];			/* lsof output line buffer */
483	int bufl = sizeof(buf);		/* size of buf[] */
484	char *opv[5];			/* option vector for lsof */
485	int rv = 1;			/* return value:
486					 *     0 == no lsof offset support
487					 *     1 == lsof offset support */
488/*
489 * Ask lsof to report the test's FD zero offset.
490 */
491	if (IsLsofExec())
492	    return(0);
493	opv[0] = "-o";
494	snprintf(buf, bufl - 1, "-p%d", (int)getpid());
495	opv[1] = buf;
496	opv[2] = "-ad0";
497	opv[3] = "+w";
498	opv[4] = (char *)NULL;
499	if (ExecLsof(opv))
500	    return(0);
501/*
502 * Read the lsof output.  Look for a line with "WARNING: can't report offset"
503 * in it.  If it is found, then this Linux lsof can't report offsets.
504 */
505	while(fgets(buf, bufl - 1, LsofFs)) {
506	    if (strstr(buf, "WARNING: can't report offset")) {
507		rv = 0;
508		break;
509	    }
510	}
511	(void) StopLsof();
512	return(rv);
513}
514#endif	/* defined(LT_DIAL_linux) */
515
516
517/*
518 * cleanup() -- release resources
519 */
520
521static void
522cleanup()
523{
524    if (Fd >= 0) {
525/*
526 * Close the test file.
527 *
528 * But first unlink it to discourage some kernel file system implementations
529 * (e.g., HFS on Apple Darwin, aka Mac OS X) from trying to fill the file's
530 * large holes.  (Filling can take a long time.)
531 */
532	if (Path) {
533	    (void) unlink(Path);
534	    Path = (char *)NULL;
535	}
536	(void) close(Fd);
537	Fd = -1;
538    }
539}
540
541
542/*
543 * tstwlsof() -- test the open file with lsof
544 */
545
546static int
547tstwlsof(tt, opt, sz)
548    int tt;				/* test type -- i.e., TST_* */
549    char *opt;				/* additional lsof options */
550    OFFSET_T sz;			/* expected size (and offset) */
551{
552    char buf[2048], buf1[2048];		/* temporary buffers */
553    LTfldo_t *cmdp;			/* command pointer */
554    LTfldo_t *devp;			/* device pointer */
555    char *em;				/* error message pointer */
556    int ff = 0;				/* file found status */
557    LTfldo_t *fop;			/* field output pointer */
558    LTfldo_t *inop;			/* inode number pointer */
559    LTdev_t lsofdc;			/* lsof device components */
560    int nf;				/* number of fields */
561    LTfldo_t *nmp;			/* file name pointer */
562    LTfldo_t *offp;			/* file offset pointer */
563    char *opv[4];			/* option vector for ExecLsof() */
564    pid_t pid;				/* PID */
565    int pids = 0;			/* PID found status */
566    STATS sb;				/* stat(2) buffer */
567    LTdev_t stdc;			/* stat(2) device components */
568    LTfldo_t *szp;			/* file size pointer */
569    LTfldo_t *tfop;			/* temporary field output pointer */
570    int ti;				/* temporary index */
571    LTfldo_t *typ;			/* file type pointer */
572    int xv = 0;				/* exit value */
573/*
574 * Check the test type.
575 */
576    switch (tt) {
577    case TST_OFFT:
578    case TST_OFFX:
579    case TST_SZ:
580	break;
581    default:
582	(void) snprintf(buf, sizeof(buf) - 1,
583	    "ERROR!!! unknown test type: %d", tt);
584	buf[sizeof(buf) - 1] = '\0';
585	(void) PrtMsgX(buf, Pn, cleanup, 1);
586    }
587/*
588 * Get test file's information.
589 */
590    if (STATF(Path, &sb)) {
591	(void) snprintf(buf, sizeof(buf) - 1,
592	    "ERROR!!! can't stat(2) %s: %s", Path, strerror(errno));
593	buf[sizeof(buf) - 1] = '\0';
594	(void) PrtMsgX(buf, Pn, cleanup, 1);
595    }
596/*
597 * Extract components from test file's device number.
598 */
599    if ((em = ConvStatDev(&sb.st_dev, &stdc))) {
600	(void) PrtMsg(em, Pn);
601	return(0);
602    }
603/*
604 * Complete the option vector and start lsof execution.
605 */
606    ti = 0;
607    if (opt && *opt)
608	opv[ti++] = opt;
609
610#if	defined(USE_LSOF_C_OPT)
611    opv[ti++] = "-C";
612#else	/* !defined(USE_LSOF_C_OPT) */
613    opv[ti++] = "--";
614#endif	/* defined(USE_LSOF_C_OPT) */
615
616    opv[ti++] = Path;
617    opv[ti] = (char *)NULL;
618    if ((em = ExecLsof(opv))) {
619	(void) PrtMsg(em, Pn);
620	return(0);
621    }
622/*
623 * Read lsof output.
624 */
625    while (!ff && (fop = RdFrLsof(&nf, &em))) {
626	switch (fop->ft) {
627	case LSOF_FID_PID:
628
629	/*
630	 * This is a process information line.
631	 */
632	    pid = (pid_t)atoi(fop->v);
633	    pids = 1;
634	    cmdp = (LTfldo_t *)NULL;
635	    for (fop++, ti = 1; ti < nf; fop++, ti++) {
636		switch (fop->ft) {
637		case LSOF_FID_CMD:
638		    cmdp = fop;
639		    break;
640		}
641	    }
642	    if (!cmdp || (pid != MyPid))
643		pids = 0;
644	    break;
645	case LSOF_FID_FD:
646
647	/*
648	 * This is a file descriptor line.
649	 *
650	 * Scan for device number, inode number, name, offset, size, and type
651	 * fields.
652	 */
653	    if (!pids)
654		break;
655	    devp = inop = nmp = offp = szp = typ = (LTfldo_t *)NULL;
656	    for (fop++, ti = 1; ti < nf; fop++, ti++) {
657		switch(fop->ft) {
658		case LSOF_FID_DEVN:
659		    devp = fop;
660		    break;
661		case LSOF_FID_INODE:
662		    inop = fop;
663		    break;
664		case LSOF_FID_NAME:
665		    nmp = fop;
666		    break;
667		case LSOF_FID_OFFSET:
668		    offp = fop;
669		    break;
670		case LSOF_FID_SIZE:
671		    szp = fop;
672		    break;
673		case LSOF_FID_TYPE:
674		    typ = fop;
675		    break;
676		}
677	    }
678	/*
679	 * Check the results of the file descriptor field scan.
680	 *
681	 * (Don't compare path names because of symbolic link interference.)
682	 */
683	    if (!devp || !inop || !nmp || !typ)
684		break;
685	    if (strcasecmp(typ->v, "reg") && strcasecmp(typ->v, "vreg"))
686		break;
687	    if (ConvLsofDev(devp->v, &lsofdc))
688		break;
689	    if ((stdc.maj != lsofdc.maj)
690	    ||  (stdc.min != lsofdc.min)
691	    ||  (stdc.unit != lsofdc.unit))
692		break;
693	    (void) snprintf(buf, sizeof(buf) - 1, "%llu",
694		(unsigned long long)sb.st_ino);
695	    buf[sizeof(buf) - 1] = '\0';
696	    if (strcmp(inop->v, buf))
697		break;
698	/*
699	 * The specifed file has been located.  Check its size or offset,
700	 * according to the tt argument.
701	 */
702	    ff = 1;
703	    switch (tt) {
704	    case TST_OFFT:
705	    case TST_SZ:
706
707	    /*
708	     * Test the size as an offset in decimal with a leading "0t", or
709	     * test the size as a size in decimal.
710	     */
711		(void) snprintf(buf, sizeof(buf) - 1,
712		    (tt == TST_SZ) ? "%llu" : "0t%llu",
713		    (unsigned long long)sz);
714		buf[sizeof(buf) - 1] = '\0';
715		tfop = (tt == TST_SZ) ? szp : offp;
716		if (!tfop || strcmp(tfop->v, buf)) {
717		    (void) snprintf(buf1, sizeof(buf1) - 1,
718			"%s mismatch: expected %s, got %s",
719			(tt == TST_SZ) ? "size" : "0t offset",
720			buf,
721			tfop ? tfop->v : "nothing");
722		    buf1[sizeof(buf1) - 1] = '\0';
723		    (void) PrtMsg(buf1, Pn);
724		    xv = 0;
725		} else
726		    xv = 1;
727		break;
728	    case TST_OFFX:
729
730	    /*
731	     * Test the size as an offset in hex.
732	     */
733		(void) snprintf(buf, sizeof(buf) - 1, "0x%llx",
734		    (unsigned long long)sz);
735		buf[sizeof(buf) - 1] = '\0';
736		if (!offp || strcmp(offp->v, buf)) {
737		    (void) snprintf(buf1, sizeof(buf1) - 1,
738			"0x offset mismatch: expected %s, got %s",
739			buf,
740			offp ? offp->v : "nothing");
741		    buf1[sizeof(buf1) - 1] = '\0';
742		    (void) PrtMsg(buf1, Pn);
743		    xv = 0;
744		} else
745		    xv = 1;
746	    }
747	    break;
748	}
749    }
750    (void) StopLsof();
751    if (em) {
752
753    /*
754     * RdFrLsof() encountered an error.
755     */
756	(void) PrtMsg(em, Pn);
757	xv = 0;
758    }
759    if (!ff) {
760	(void) snprintf(buf, sizeof(buf) - 1, "%s not found by lsof", Path);
761	buf[sizeof(buf) - 1] = '\0';
762	PrtMsg(buf, Pn);
763	xv = 0;
764    }
765    return(xv);
766}
767#endif	/* defined(LT_BIG) */
768