Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef _XOPEN_SOURCE
- # define _XOPEN_SOURCE 500
- #endif
- /* C headers */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <errno.h>
- /* System headers */
- #include <sys/types.h>
- #include <dirent.h>
- #include <unistd.h>
- #include <fcntl.h>
- /* illumos headers */
- #include <procfs.h>
- static int single_shot = 0;
- static int only_same_root = 0;
- static int scripts_too = 0;
- static int *omit_pids = NULL;
- static int progidx = 0;
- static const char *progname;
- void usage()
- {
- printf("Usage: %s [OPTIONS] program [program ...]\n", progname);
- printf("Find the process ID of a running program.\n\n");
- printf("Options:\n");
- printf(" -s single shot - only return one pid.\n");
- printf(" -c only return process ids that are running with the same root directory.\n");
- printf(" -x scripts too - also return process ids of shells running the named scripts.\n");
- printf(" -o pid omit processes with that process id (-o pid1,pid2 or -o pid1 -o pid2, etc.)\n");
- printf("\n");
- printf(" -h this help message.\n");
- printf("\n");
- printf("Exit status:\n");
- printf(" 0 at least one program was found with the requested name.\n");
- printf(" 1 no program was found with the requested name.\n");
- exit(1);
- }
- void parse_args(int argc, char *argv[])
- {
- int opt;
- progname = argv[0];
- while ((opt = getopt(argc, argv, "hscxo:")) != -1) {
- switch (opt) {
- case 's':
- single_shot++;
- break;
- case 'c':
- only_same_root++;
- break;
- case 'x':
- scripts_too++;
- break;
- default:
- usage();
- }
- }
- /* all arguments after options are program names */
- progidx = optind;
- }
- int name_matches(const char *name, int start, int n, char *progs[])
- {
- while (start < n) {
- if (progs[start][0] != '\0') {
- if (0 == strcmp(name, progs[start])) {
- if (single_shot) progs[start] = "";
- return 1;
- }
- }
- start++;
- }
- return 0;
- }
- int main(int argc, char *argv[])
- {
- DIR *dirp; /* directory handler for /proc */
- struct dirent *pdr /* dir entry for /proc/<pid> */;
- psinfo_t pi; /* contents of /proc/<pid>/psinfo */
- int fd; /* file descriptor for /proc/<pid>/psinfo */
- int rc; /* return value of various function*/
- const char *pid_s; /* string representation of pid */
- int found = 0; /* number of found pids */
- #define MAX_PID_LENGTH 6 /* 999999 max, see http://docs.oracle.com/cd/E19082-01/819-2724/chapter2-107/index.html */
- char fname[6 + MAX_PID_LENGTH + 7 + 1]; /* length of /proc/<pid>/psinfo + '0' */
- parse_args(argc, argv);
- if (!(dirp = opendir("/proc"))) {
- perror("Failed to open directory /proc");
- exit(1);
- }
- while ((pdr = readdir(dirp))) {
- if (pdr->d_name[0] == '.') /* skip . and .. */
- continue;
- pid_s = pdr->d_name;
- rc = snprintf(fname, sizeof(fname), "/proc/%s/psinfo", pid_s);
- if (rc < 0) {
- perror("snprintf failed");
- errno = 0;
- continue;
- }
- if (rc >= (int) sizeof(fname)) {
- fprintf(stderr, "Not enough space to hold `%s'\n", pid_s);
- continue;
- }
- if ((fd = open(fname, O_RDONLY)) < 0) {
- perror(fname);
- errno = 0;
- continue;
- }
- if (read(fd, (void *)&pi, sizeof(pi)) < 0) {
- perror(fname);
- errno = 0;
- } else {
- if (name_matches(pi.pr_fname, progidx, argc, argv)) {
- printf("%s ", pid_s);
- found++;
- }
- /*
- printf("%s\n", pi.pr_fname);
- printf("%s\n", pi.pr_psargs);
- */
- }
- (void) close(fd);
- }
- if (errno) {
- perror("Error while listing /proc");
- }
- (void) closedir(dirp);
- return (found > 0) ? 0 : 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment