3 * Third version to get process arg info; this time by using
4 * a combination of reading the /proc/<pid>/psinfo structures
5 * and reading the complete arg vector from kernel memory structures.
7 * Developed and tested under Solaris 5.8 (both 32 and 64 bit modes).
9 * NOTE: This program must be setuid-root (or run by root) to work!
11 * Written: 2005-04-28 R.W.Ingraham
18 #include <sys/param.h>
22 #include <sys/types.h>
38 #define PROC_DIR "/proc"
53 static struct proc
* pProc
;
54 static struct user
* pUser
;
55 static char ** myArgv
;
62 static int HandleFile (struct dirent
*pDent
);
63 static int HandlePsInfo (char *szPath
, psinfo_t
*pPsInfo
);
64 static int GetArgVectors (pid_t pid
);
65 static void ShowArgVectors (void);
66 static void ReleaseArgVectors();
69 /*----------------------------------------------------------------------------*/
71 int main (int argc
, char **argv
)
78 /* Set our program name global */
79 if ((szProg
= strrchr(argv
[0], '/')) != NULL
)
84 /* Make sure that our euid is root */
87 fprintf(stderr
, "%s: This program can only be run by the root user!\n", szProg
);
91 /* Get a handle to the running kernel image */
92 if ((kd
= kvm_open(NULL
, NULL
, NULL
, O_RDONLY
, argv
[0])) == NULL
)
94 fprintf(stderr
, "%s: Failed to open kernel memory: %s\n", szProg
, strerror(errno
));
98 /* Open the /proc directory */
99 if ((pDir
= opendir(PROC_DIR
)) != NULL
)
101 /* Display column headings */
102 printf("S UID PPID VSZ RSS %%CPU COMMAND ARGS\n");
104 /* Zip through all of the process entries */
105 while ((pDent
= readdir(pDir
)) != NULL
)
107 /* Handle each pid sub-directory */
111 /* Close the directory */
114 else /* ERROR: Failure to open PROC_DIR */
116 fprintf(stderr
, "%s: Failed to open \"%s\": %s\n", szProg
, PROC_DIR
, strerror(errno
));
120 /* Close the handle to the running kernel image */
126 /*----------------------------------------------------------------------------*/
128 static int HandleFile (struct dirent
*pDent
)
130 char szPath
[MAX_PATH
];
135 /* Skip files beginning with a "." */
136 if (pDent
->d_name
[0] == '.')
139 /* Cosntruct the path to the psinfo file */
140 len
= sprintf(szPath
, "%s/%s/psinfo", PROC_DIR
, pDent
->d_name
);
142 /* Open the psinfo file for this pid and print out its arg vectors */
143 if ((fd
= open(szPath
, O_RDONLY
)) >= 0)
145 /* Read the psinfo struct */
146 if ((len
= read(fd
, &sPsInfo
, sizeof(sPsInfo
))) != sizeof(sPsInfo
))
149 fprintf(stderr
, "%s: Read error of psinfo structure (%d)\n", szPath
, len
);
153 /* Close the psinfo file */
156 /* Pass psinfo struct to reporting function */
157 HandlePsInfo(szPath
, &sPsInfo
);
159 else if (errno
!= ENOENT
)
162 fprintf(stderr
, "%s: %s\n", szPath
, strerror(errno
));
168 /*----------------------------------------------------------------------------*/
170 static int HandlePsInfo (char *szPath
, psinfo_t
*pPsInfo
)
175 /* Make sure that the process is still there */
176 if ((retcode
= GetArgVectors(pPsInfo
->pr_pid
)) == 0)
178 /* We use the program name from the kvm argv[0] instead
179 * of pr_fname from the psinfo struct because pr_fname
182 * Also, strip-off leading path information.
184 if ((thisProg
= strrchr(myArgv
[0], '/')) != NULL
)
187 thisProg
= myArgv
[0];
189 /* Display the ps columns (except for argv) */
190 printf("%c %5d %5d %5d %6lu %6lu %4.1f %s ",
191 pPsInfo
->pr_lwp
.pr_sname
,
192 (int)(pPsInfo
->pr_euid
),
193 (int)(pPsInfo
->pr_pid
),
194 (int)(pPsInfo
->pr_ppid
),
195 (unsigned long)(pPsInfo
->pr_size
),
196 (unsigned long)(pPsInfo
->pr_rssize
),
197 ((float)(pPsInfo
->pr_pctcpu
) / 0x8000 * 100.0),
200 /* Display the arg vectors associated with this pid */
203 /* Release the arg vector buffer memory */
210 /*----------------------------------------------------------------------------*/
212 static int GetArgVectors (pid_t pid
)
216 /* Get the proc structure for the specified PID */
217 if ((pProc
= kvm_getproc(kd
, pid
)) != NULL
)
219 /* Save a copy of the process' u-area */
220 if ((pUser
= kvm_getu(kd
, pProc
)) != NULL
)
222 /* Reconstruct the process' argv vector array */
223 if (kvm_getcmd(kd
, pProc
, pUser
, &myArgv
, NULL
) == 0)
233 /*----------------------------------------------------------------------------*/
235 static void ShowArgVectors (void)
239 for (i
=0; myArgv
[i
]; i
++)
241 printf(" %s", myArgv
[i
]);
246 /*----------------------------------------------------------------------------*/
248 static void ReleaseArgVectors()
253 /*----------------------------------------------------------------------------*/