2 * LTunix.c -- Lsof Test UNIX domain socket test
10 * Copyright 2002 Purdue Research Foundation, West Lafayette, Indiana
11 * 47907. All rights reserved.
13 * Written by V. Abell.
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.
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:
22 * 1. Neither the authors nor Purdue University are responsible for any
23 * consequences of the use of this software.
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.
29 * 3. Altered versions must be plainly marked as such, and must not be
30 * misrepresented as being the original software.
32 * 4. This notice may not be removed or altered.
36 static char copyright[] =
37 "@(#) Copyright 2002 Purdue Research Foundation.\nAll rights reserved.\n";
41 #include "lsof_fields.h"
43 #include <sys/socket.h>
51 #if !defined(MAXPATHLEN)
52 #define MAXPATHLEN 1024 /* maximum path length */
53 #endif /* !defined(MAXPATHLEN) */
60 pid_t MyPid = (pid_t)0; /* PID of this process */
61 char *Pn = (char *)NULL; /* program name */
62 int SpFd[2] = {-1,-1}; /* socket pair FDs */
63 char *Path[2] = {(char *)NULL, (char *)NULL};
64 /* socket pair paths */
68 * Local function prototypes
71 _PROTOTYPE(static void cleanup,(void));
72 _PROTOTYPE(static char *FindUsocks,(void));
81 int argc; /* argument count */
82 char *argv[]; /* arguments */
84 char buf[2048]; /* temporary buffer */
85 char cwd[MAXPATHLEN + 1]; /* CWD buffer */
86 char *em; /* error message pointer */
87 int ti, tj; /* temporary indexes */
88 struct sockaddr_un ua; /* UNIX socket address */
89 int xv = 0; /* exit value */
91 * Get program name and PID, issue start message, and build space prefix.
93 if ((Pn = strrchr(argv[0], '/')))
98 (void) printf("%s ... ", Pn);
99 (void) fflush(stdout);
100 PrtMsg((char *)NULL, Pn);
104 if (ScanArg(argc, argv, "h", Pn))
107 (void) PrtMsg("usage: [-h]", Pn);
108 PrtMsgX(" -h print help (this panel)", Pn, cleanup, xv);
111 * See if lsof can be executed and can access kernel memory.
113 if ((em = IsLsofExec()))
114 (void) PrtMsgX(em, Pn, cleanup, 1);
115 if ((em = CanRdKmem()))
116 (void) PrtMsgX(em, Pn, cleanup, 1);
118 * Construct the socket paths.
121 #if defined(USE_GETCWD)
122 if (!getcwd(cwd, sizeof(cwd)))
123 #else /* ! defined(USE_GETCWD) */
125 #endif /* defined(USE_GETCWD) */
128 em = "ERROR!!! can't get CWD";
131 cwd[sizeof(cwd) - 1] = '\0';
132 if ((strlen(cwd) + strlen("/config.LT#U9223372036854775807") + 1)
133 > sizeof(ua.sun_path))
135 strncpy(cwd, "/tmp", sizeof(cwd) - 1);
137 for (ti = 0; ti < 2; ti++) {
138 (void) snprintf(buf, sizeof(buf) - 1, "%s/config.LT%dU%ld", cwd, ti,
140 buf[sizeof(buf) - 1] = '\0';
141 Path[ti] = MkStrCpy(buf, &tj);
142 (void) unlink(Path[ti]);
145 * Get two UNIX domain socket FDs.
147 for (ti = 0; ti < 2; ti++) {
148 if ((SpFd[ti] = socket(AF_UNIX, SOCK_STREAM, PF_UNSPEC)) < 0) {
153 (void) snprintf(buf, sizeof(buf) - 1, "ERROR!!! %s(%s) failure",
155 buf[sizeof(buf) - 1] = '\0';
161 (void) snprintf(buf, sizeof(buf) - 1, " Errno %d: %s", errno,
163 buf[sizeof(buf) - 1] = '\0';
164 PrtMsgX(buf, Pn, cleanup, 1);
168 * Bind file system names to the sockets.
170 for (ti = 0; ti < 2; ti++) {
171 (void) memset((void *)&ua, 0, sizeof(ua));
172 ua.sun_family = AF_UNIX;
173 (void) strncpy(ua.sun_path, Path[ti], sizeof(ua.sun_path));
174 ua.sun_path[sizeof(ua.sun_path) - 1] = '\0';
175 if (bind(SpFd[ti], (struct sockaddr *)&ua, sizeof(ua)) < 0) {
177 goto print_errno_by_ti;
181 * Look for the open UNIX domain socket files with lsof.
183 if ((em = FindUsocks()))
184 (void) PrtMsgX(em, Pn, cleanup, 1);
188 (void) PrtMsgX("OK", Pn, cleanup, 0);
194 * cleanup() -- release resources
202 for (ti = 0; ti < 2; ti++) {
204 (void) close(SpFd[ti]);
208 (void) unlink(Path[ti]);
209 (void) free((void *)Path[ti]);
210 Path[ti] = (char *)NULL;
217 * FindUsocks() -- find UNIX sockets with lsof
223 char buf[2048]; /* temporary buffer */
224 char *cem; /* current error message pointer */
225 LTfldo_t *cmdp; /* command pointer */
226 int ff[2]; /* file-found flags */
227 LTfldo_t *fop; /* field output pointer */
228 int nf; /* number of fields */
229 int nl; /* name length */
230 LTfldo_t *nmp; /* name pointer */
231 char *opv[5]; /* option vector for ExecLsof() */
232 char *pem = (char *)NULL; /* previous error message pointer */
234 int pids = 0; /* PID found status */
235 char *tcp; /* temporary character pointer */
236 int ti, tj; /* temporary integers */
237 LTfldo_t *typ; /* file type pointer */
239 * Build the option vector and start lsof execution.
241 ff[0] = ff[1] = ti = 0;
244 (void) snprintf(buf, sizeof(buf) - 1, "%ld", (long)MyPid);
245 buf[sizeof(buf) - 1] = '\0';
246 opv[ti++] = MkStrCpy(buf, &tj);
248 #if defined(USE_LSOF_C_OPT)
250 #endif /* defined(USE_LSOF_C_OPT) */
252 opv[ti] = (char *)NULL;
253 if ((cem = ExecLsof(opv)))
258 while (((ff[0] + ff[1]) < 2) && (fop = RdFrLsof(&nf, &cem))) {
261 (void) PrtMsg(pem, Pn);
268 * This is a process information line.
270 pid = (pid_t)atoi(fop->v);
272 cmdp = (LTfldo_t *)NULL;
273 for (fop++, ti = 1; ti < nf; fop++, ti++) {
280 if (!cmdp || (pid != MyPid))
286 * This is a file descriptor line. Make sure its number matches a
287 * test file descriptor number.
291 for (ti = 0, tcp = fop->v; *tcp; tcp++) {
294 * Convert file descriptor to a number.
298 if (((int)*tcp < (int)'0') || ((int)*tcp > (int)'9')) {
302 ti = (ti * 10) + (int)*tcp - (int)'0';
304 for (tj = 0; tj < 2; tj++) {
313 * Scan for name and type.
315 nmp = typ = (LTfldo_t *)NULL;
316 for (fop++, ti = 1; ti < nf; fop++, ti++) {
327 * Check the type of the file.
329 if (!typ || strcasecmp(typ->v, "unix"))
336 nl = strlen(Path[tj]);
337 for (tcp = nmp->v; tcp; tcp = strchr(tcp + 1, '/')) {
338 if (!strncmp(tcp, Path[tj], nl)) {
341 * Mark a file as found.
350 * Clean up and return.
353 for (ti = 0; ti < 2; ti++) {
356 (void) snprintf(buf, sizeof(buf) - 1, "ERROR!!! not found: %s",
358 buf[sizeof(buf) - 1] = '\0';
360 (void) PrtMsg(pem, Pn);
361 pem = MkStrCpy(buf, &tj);