~aviksil/smartt/master

« back to all changes in this revision

Viewing changes to smartt-top/pwdx.c

  • Committer: Avik Sil
  • Date: 2011-06-16 06:43:28 UTC
  • Revision ID: git-v1:a36795846bf0de4ec0d7344b2f41c94b7317bb42
SMARTTĀ ReleaseĀ 0.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2004 Nicholas Miell
 
2
//
 
3
// This file may be used subject to the terms and conditions of the
 
4
// GNU Library General Public License Version 2 as published by the
 
5
// Free Software Foundation.This program is distributed in the hope
 
6
// that it will be useful, but WITHOUT ANY WARRANTY; without even the
 
7
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 
8
// PURPOSE. See the GNU Library General Public License for more
 
9
// details.
 
10
 
 
11
#include <stdio.h>
 
12
#include <string.h>
 
13
#include <stdlib.h>
 
14
#include <sys/types.h>
 
15
#include <regex.h>
 
16
#include <limits.h>
 
17
#include <unistd.h>
 
18
#include <errno.h>
 
19
 
 
20
#include "proc/version.h"
 
21
 
 
22
static void die(const char *msg) NORETURN;
 
23
static void die(const char *msg)
 
24
{
 
25
     fputs(msg, stderr);
 
26
     exit(1);
 
27
}
 
28
 
 
29
static void version(void) NORETURN;
 
30
static void version(void)
 
31
{
 
32
     printf("pwdx (%s)\n", procps_version);
 
33
     exit(0);
 
34
}
 
35
 
 
36
int main(int argc, char* argv[])
 
37
{
 
38
     regex_t re;
 
39
     int i;
 
40
 
 
41
     if (argc < 2)
 
42
          die("Usage: pwdx pid...\n");
 
43
 
 
44
     // Allowed on the command line:
 
45
     //
 
46
     // --version
 
47
     // -V
 
48
     // /proc/nnnn
 
49
     // nnnn
 
50
     //
 
51
     // where nnnn is any number that doesn't begin with 0.
 
52
     //
 
53
     // If --version or -V are present, further arguments are ignored
 
54
     // completely.
 
55
        
 
56
     regcomp(&re, "^((/proc/+)?[1-9][0-9]*|-V|--version)$",
 
57
             REG_EXTENDED|REG_NOSUB);
 
58
 
 
59
     for (i = 1; i < argc; i++) {
 
60
          if (regexec(&re, argv[i], 0, NULL, 0) != 0) {
 
61
               char buf[27 + strlen (argv[i]) + 1];  // Constant 27 is the length of the error string "pwdx: ... "
 
62
               snprintf(buf, sizeof buf, "pwdx: invalid process id: %s\n", argv[i]);
 
63
               die(buf);
 
64
          }
 
65
          if (!strcmp("-V", argv[i]) || !strcmp("--version", argv[i]))
 
66
               version();
 
67
     }
 
68
 
 
69
     regfree(&re);
 
70
 
 
71
     int alloclen = 128;
 
72
     char *pathbuf = malloc(alloclen);
 
73
 
 
74
     for (i = 1; i < argc; i++) {
 
75
          char * s;
 
76
          int len;
 
77
          char buf[10 + strlen(argv[i]) + 1]; // Constant 10 is the length of strings "/proc/" + "/cwd" + 1
 
78
          
 
79
          // At this point, all arguments are in the form /proc/nnnn
 
80
          // or nnnn, so a simple check based on the first char is
 
81
          // possible
 
82
          if (argv[i][0] != '/')
 
83
               snprintf(buf, sizeof buf, "/proc/%s/cwd", argv[i]);
 
84
          else
 
85
               snprintf(buf, sizeof buf, "%s/cwd", argv[i]);
 
86
 
 
87
          // buf contains /proc/nnnn/cwd symlink name on entry, the
 
88
          // target of that symlink on return
 
89
          while ((len = readlink(buf, pathbuf, alloclen)) == alloclen) {
 
90
               alloclen *= 2;
 
91
               pathbuf = realloc(pathbuf, alloclen);
 
92
          }
 
93
 
 
94
          if (len < 0) {
 
95
               s = strerror(errno == ENOENT ? ESRCH : errno);
 
96
          } else {
 
97
               pathbuf[len] = 0;
 
98
               s = pathbuf;
 
99
          }
 
100
 
 
101
          printf("%s: %s\n", argv[i], s);
 
102
     }
 
103
 
 
104
     free(pathbuf);
 
105
 
 
106
     return 0;
 
107
}