diff options
| author | Eli Zaretskii | 2008-08-02 16:27:44 +0000 |
|---|---|---|
| committer | Eli Zaretskii | 2008-08-02 16:27:44 +0000 |
| commit | 934e2a689422aca8e2a91ac064b7a504770d4642 (patch) | |
| tree | e662efc04bc839c8c4b3660eb93e875248d99629 /src/process.c | |
| parent | 02db701b5d3356005bdc2368899c5c6a5393ec5b (diff) | |
| download | emacs-934e2a689422aca8e2a91ac064b7a504770d4642.tar.gz emacs-934e2a689422aca8e2a91ac064b7a504770d4642.zip | |
(Fsystem_processes_list, Fsystem_process_attributes): New functions.
(syms_of_process): Defsubr them. Add initializations for various Q* symbols
used in procfs_system_process_attributes.
(procfs_list_system_processes, procfs_system_process_attributes) [HAVE_PROCFS]:
New functions.
(time_from_jiffies, ltime_from_jiffies, get_up_time, procfs_ttyname)
(procfs_get_total_memory): New functions.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 611 |
1 files changed, 607 insertions, 4 deletions
diff --git a/src/process.c b/src/process.c index f343ccc0cc4..cb7d2c237c0 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -33,6 +33,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 33 | #ifdef subprocesses | 33 | #ifdef subprocesses |
| 34 | 34 | ||
| 35 | #include <stdio.h> | 35 | #include <stdio.h> |
| 36 | #include <stdlib.h> | ||
| 37 | #include <ctype.h> | ||
| 36 | #include <errno.h> | 38 | #include <errno.h> |
| 37 | #include <setjmp.h> | 39 | #include <setjmp.h> |
| 38 | #include <sys/types.h> /* some typedefs are used in sys/file.h */ | 40 | #include <sys/types.h> /* some typedefs are used in sys/file.h */ |
| @@ -41,14 +43,16 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 41 | #ifdef HAVE_INTTYPES_H | 43 | #ifdef HAVE_INTTYPES_H |
| 42 | #include <inttypes.h> | 44 | #include <inttypes.h> |
| 43 | #endif | 45 | #endif |
| 46 | |||
| 47 | #ifdef HAVE_PWD_H | ||
| 48 | #include <pwd.h> | ||
| 49 | #include <grp.h> | ||
| 50 | #endif | ||
| 51 | |||
| 44 | #ifdef HAVE_UNISTD_H | 52 | #ifdef HAVE_UNISTD_H |
| 45 | #include <unistd.h> | 53 | #include <unistd.h> |
| 46 | #endif | 54 | #endif |
| 47 | |||
| 48 | #if defined(WINDOWSNT) || defined(UNIX98_PTYS) | ||
| 49 | #include <stdlib.h> | ||
| 50 | #include <fcntl.h> | 55 | #include <fcntl.h> |
| 51 | #endif /* not WINDOWSNT */ | ||
| 52 | 56 | ||
| 53 | #ifdef HAVE_SOCKETS /* TCP connection support, if kernel can do it */ | 57 | #ifdef HAVE_SOCKETS /* TCP connection support, if kernel can do it */ |
| 54 | #include <sys/socket.h> | 58 | #include <sys/socket.h> |
| @@ -146,6 +150,11 @@ extern Lisp_Object QCfamily; | |||
| 146 | /* QCfilter is defined in keyboard.c. */ | 150 | /* QCfilter is defined in keyboard.c. */ |
| 147 | extern Lisp_Object QCfilter; | 151 | extern Lisp_Object QCfilter; |
| 148 | 152 | ||
| 153 | Lisp_Object Qeuid, Qegid, Qcomm, Qstate, Qppid, Qpgrp, Qsess, Qttname, Qtpgid; | ||
| 154 | Lisp_Object Qminflt, Qmajflt, Qcminflt, Qcmajflt, Qutime, Qstime, Qcstime; | ||
| 155 | Lisp_Object Qcutime, Qpri, Qnice, Qthcount, Qstart, Qvsize, Qrss, Qargs; | ||
| 156 | Lisp_Object Quser, Qgroup, Qetime, Qpcpu, Qpmem; | ||
| 157 | |||
| 149 | #ifdef HAVE_SOCKETS | 158 | #ifdef HAVE_SOCKETS |
| 150 | #define NETCONN_P(p) (EQ (XPROCESS (p)->type, Qnetwork)) | 159 | #define NETCONN_P(p) (EQ (XPROCESS (p)->type, Qnetwork)) |
| 151 | #define NETCONN1_P(p) (EQ ((p)->type, Qnetwork)) | 160 | #define NETCONN1_P(p) (EQ ((p)->type, Qnetwork)) |
| @@ -7057,6 +7066,465 @@ keyboard_bit_set (mask) | |||
| 7057 | return 0; | 7066 | return 0; |
| 7058 | } | 7067 | } |
| 7059 | 7068 | ||
| 7069 | /* Enumeration of and access to system processes a-la ps(1). */ | ||
| 7070 | |||
| 7071 | #if HAVE_PROCFS | ||
| 7072 | |||
| 7073 | /* Process enumeration and access via /proc. */ | ||
| 7074 | |||
| 7075 | static Lisp_Object | ||
| 7076 | procfs_list_system_processes () | ||
| 7077 | { | ||
| 7078 | Lisp_Object procdir, match, proclist, next; | ||
| 7079 | struct gcpro gcpro1, gcpro2; | ||
| 7080 | register Lisp_Object tail; | ||
| 7081 | |||
| 7082 | GCPRO2 (procdir, match); | ||
| 7083 | /* For every process on the system, there's a directory in the | ||
| 7084 | "/proc" pseudo-directory whose name is the numeric ID of that | ||
| 7085 | process. */ | ||
| 7086 | procdir = build_string ("/proc"); | ||
| 7087 | match = build_string ("[0-9]+"); | ||
| 7088 | proclist = directory_files_internal (procdir, Qnil, match, Qt, 0, Qnil); | ||
| 7089 | |||
| 7090 | /* `proclist' gives process IDs as strings. Destructively convert | ||
| 7091 | each string into a number. */ | ||
| 7092 | for (tail = proclist; CONSP (tail); tail = next) | ||
| 7093 | { | ||
| 7094 | next = XCDR (tail); | ||
| 7095 | XSETCAR (tail, Fstring_to_number (XCAR (tail), Qnil)); | ||
| 7096 | } | ||
| 7097 | UNGCPRO; | ||
| 7098 | |||
| 7099 | /* directory_files_internal returns the files in reverse order; undo | ||
| 7100 | that. */ | ||
| 7101 | proclist = Fnreverse (proclist); | ||
| 7102 | return proclist; | ||
| 7103 | } | ||
| 7104 | |||
| 7105 | static void | ||
| 7106 | time_from_jiffies (unsigned long long tval, long hz, | ||
| 7107 | time_t *sec, unsigned *usec) | ||
| 7108 | { | ||
| 7109 | unsigned long long ullsec; | ||
| 7110 | |||
| 7111 | *sec = tval / hz; | ||
| 7112 | ullsec = *sec; | ||
| 7113 | tval -= ullsec * hz; | ||
| 7114 | /* Careful: if HZ > 1 million, then integer division by it yields zero. */ | ||
| 7115 | if (hz <= 1000000) | ||
| 7116 | *usec = tval * 1000000 / hz; | ||
| 7117 | else | ||
| 7118 | *usec = tval / (hz / 1000000); | ||
| 7119 | } | ||
| 7120 | |||
| 7121 | static Lisp_Object | ||
| 7122 | ltime_from_jiffies (unsigned long long tval, long hz) | ||
| 7123 | { | ||
| 7124 | time_t sec; | ||
| 7125 | unsigned usec; | ||
| 7126 | |||
| 7127 | time_from_jiffies (tval, hz, &sec, &usec); | ||
| 7128 | |||
| 7129 | return list3 (make_number ((sec >> 16) & 0xffff), | ||
| 7130 | make_number (sec & 0xffff), | ||
| 7131 | make_number (usec)); | ||
| 7132 | } | ||
| 7133 | |||
| 7134 | static void | ||
| 7135 | get_up_time (time_t *sec, unsigned *usec) | ||
| 7136 | { | ||
| 7137 | FILE *fup; | ||
| 7138 | |||
| 7139 | *sec = *usec = 0; | ||
| 7140 | |||
| 7141 | BLOCK_INPUT; | ||
| 7142 | fup = fopen ("/proc/uptime", "r"); | ||
| 7143 | |||
| 7144 | if (fup) | ||
| 7145 | { | ||
| 7146 | double uptime, idletime; | ||
| 7147 | |||
| 7148 | /* The numbers in /proc/uptime use C-locale decimal point, but | ||
| 7149 | we already set ourselves to the C locale (see `fixup_locale' | ||
| 7150 | in emacs.c). */ | ||
| 7151 | if (2 <= fscanf (fup, "%lf %lf", &uptime, &idletime)) | ||
| 7152 | { | ||
| 7153 | *sec = uptime; | ||
| 7154 | *usec = (uptime - *sec) * 1000000; | ||
| 7155 | } | ||
| 7156 | fclose (fup); | ||
| 7157 | } | ||
| 7158 | UNBLOCK_INPUT; | ||
| 7159 | } | ||
| 7160 | |||
| 7161 | #define MAJOR(d) (((unsigned)(d) >> 8) & 0xfff) | ||
| 7162 | #define MINOR(d) (((unsigned)(d) & 0xff) | (((unsigned)(d) & 0xfff00000) >> 12)) | ||
| 7163 | |||
| 7164 | static Lisp_Object | ||
| 7165 | procfs_ttyname (rdev) | ||
| 7166 | { | ||
| 7167 | FILE *fdev = NULL; | ||
| 7168 | char name[PATH_MAX]; | ||
| 7169 | |||
| 7170 | BLOCK_INPUT; | ||
| 7171 | fdev = fopen ("/proc/tty/drivers", "r"); | ||
| 7172 | |||
| 7173 | if (fdev) | ||
| 7174 | { | ||
| 7175 | unsigned major; | ||
| 7176 | unsigned long minor_beg, minor_end; | ||
| 7177 | char minor[25]; /* 2 32-bit numbers + dash */ | ||
| 7178 | char *endp; | ||
| 7179 | |||
| 7180 | while (!feof (fdev) && !ferror (fdev)) | ||
| 7181 | { | ||
| 7182 | if (3 <= fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) | ||
| 7183 | && major == MAJOR (rdev)) | ||
| 7184 | { | ||
| 7185 | minor_beg = strtoul (minor, &endp, 0); | ||
| 7186 | if (*endp == '\0') | ||
| 7187 | minor_end = minor_beg; | ||
| 7188 | else if (*endp == '-') | ||
| 7189 | minor_end = strtoul (endp + 1, &endp, 0); | ||
| 7190 | else | ||
| 7191 | continue; | ||
| 7192 | |||
| 7193 | if (MINOR (rdev) >= minor_beg && MINOR (rdev) <= minor_end) | ||
| 7194 | { | ||
| 7195 | sprintf (name + strlen (name), "%lu", MINOR (rdev)); | ||
| 7196 | break; | ||
| 7197 | } | ||
| 7198 | } | ||
| 7199 | } | ||
| 7200 | fclose (fdev); | ||
| 7201 | } | ||
| 7202 | UNBLOCK_INPUT; | ||
| 7203 | return build_string (name); | ||
| 7204 | } | ||
| 7205 | |||
| 7206 | static unsigned long | ||
| 7207 | procfs_get_total_memory (void) | ||
| 7208 | { | ||
| 7209 | FILE *fmem = NULL; | ||
| 7210 | unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */ | ||
| 7211 | |||
| 7212 | BLOCK_INPUT; | ||
| 7213 | fmem = fopen ("/proc/meminfo", "r"); | ||
| 7214 | |||
| 7215 | if (fmem) | ||
| 7216 | { | ||
| 7217 | unsigned long entry_value; | ||
| 7218 | char entry_name[20]; /* the longest I saw is 13+1 */ | ||
| 7219 | |||
| 7220 | while (!feof (fmem) && !ferror (fmem)) | ||
| 7221 | { | ||
| 7222 | if (2 <= fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value) | ||
| 7223 | && strcmp (entry_name, "MemTotal:") == 0) | ||
| 7224 | { | ||
| 7225 | retval = entry_value; | ||
| 7226 | break; | ||
| 7227 | } | ||
| 7228 | } | ||
| 7229 | fclose (fmem); | ||
| 7230 | } | ||
| 7231 | UNBLOCK_INPUT; | ||
| 7232 | return retval; | ||
| 7233 | } | ||
| 7234 | |||
| 7235 | static Lisp_Object | ||
| 7236 | procfs_system_process_attributes (pid) | ||
| 7237 | Lisp_Object pid; | ||
| 7238 | { | ||
| 7239 | char procfn[PATH_MAX], fn[PATH_MAX]; | ||
| 7240 | struct stat st; | ||
| 7241 | struct passwd *pw; | ||
| 7242 | struct group *gr; | ||
| 7243 | long clocks_per_sec; | ||
| 7244 | char *procfn_end; | ||
| 7245 | char procbuf[1025], *p, *q; | ||
| 7246 | int fd; | ||
| 7247 | ssize_t nread; | ||
| 7248 | char cmd[PATH_MAX]; | ||
| 7249 | char *cmdline = NULL; | ||
| 7250 | size_t cmdsize; | ||
| 7251 | int c; | ||
| 7252 | int proc_id, ppid, uid, gid, pgrp, sess, tty, tpgid, thcount; | ||
| 7253 | unsigned long long utime, stime, cutime, cstime, start; | ||
| 7254 | long priority, nice, rss; | ||
| 7255 | unsigned long minflt, majflt, cminflt, cmajflt, vsize; | ||
| 7256 | time_t sec; | ||
| 7257 | unsigned usec; | ||
| 7258 | EMACS_TIME tnow, tstart, tboot, telapsed,ttotal; | ||
| 7259 | double pcpu, pmem; | ||
| 7260 | Lisp_Object attrs = Qnil; | ||
| 7261 | Lisp_Object cmd_str, decoded_cmd, tem; | ||
| 7262 | struct gcpro gcpro1, gcpro2; | ||
| 7263 | |||
| 7264 | CHECK_NUMBER_OR_FLOAT (pid); | ||
| 7265 | proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid); | ||
| 7266 | sprintf (procfn, "/proc/%lu", proc_id); | ||
| 7267 | if (stat (procfn, &st) < 0) | ||
| 7268 | return attrs; | ||
| 7269 | |||
| 7270 | GCPRO2 (attrs, decoded_cmd); | ||
| 7271 | |||
| 7272 | /* euid egid */ | ||
| 7273 | uid = st.st_uid; | ||
| 7274 | attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid)), attrs); | ||
| 7275 | BLOCK_INPUT; | ||
| 7276 | pw = (struct passwd *) getpwuid (uid); | ||
| 7277 | UNBLOCK_INPUT; | ||
| 7278 | if (pw) | ||
| 7279 | attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs); | ||
| 7280 | |||
| 7281 | gid = st.st_gid; | ||
| 7282 | attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid)), attrs); | ||
| 7283 | BLOCK_INPUT; | ||
| 7284 | gr = (struct group *) getgrgid (gid); | ||
| 7285 | UNBLOCK_INPUT; | ||
| 7286 | if (gr) | ||
| 7287 | attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); | ||
| 7288 | |||
| 7289 | strcpy (fn, procfn); | ||
| 7290 | procfn_end = fn + strlen (fn); | ||
| 7291 | strcpy (procfn_end, "/stat"); | ||
| 7292 | fd = emacs_open (fn, O_RDONLY, 0); | ||
| 7293 | if (fd >= 0 && (nread = emacs_read (fd, procbuf, sizeof(procbuf) - 1)) > 0) | ||
| 7294 | { | ||
| 7295 | procbuf[nread] = '\0'; | ||
| 7296 | p = procbuf; | ||
| 7297 | |||
| 7298 | p = strchr (p, '(') + 1; | ||
| 7299 | q = strchr (p, ')'); | ||
| 7300 | /* comm */ | ||
| 7301 | if (q > p) | ||
| 7302 | { | ||
| 7303 | memcpy (cmd, p, q - p); | ||
| 7304 | cmd[q - p] = '\0'; | ||
| 7305 | } | ||
| 7306 | else | ||
| 7307 | strcpy (cmd, "???"); | ||
| 7308 | /* Command name is encoded in locale-coding-system; decode it. */ | ||
| 7309 | cmd_str = make_unibyte_string (cmd, q ? q - p : 3); | ||
| 7310 | decoded_cmd = code_convert_string_norecord (cmd_str, | ||
| 7311 | Vlocale_coding_system, 0); | ||
| 7312 | attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); | ||
| 7313 | |||
| 7314 | if (q) | ||
| 7315 | { | ||
| 7316 | p = q + 2; | ||
| 7317 | /* state ppid pgrp sess tty tpgid . minflt cminflt majflt cmajflt utime stime cutime cstime priority nice thcount . start vsize rss */ | ||
| 7318 | sscanf (p, "%c %d %d %d %d %d %*u %lu %lu %lu %lu %Lu %Lu %Lu %Lu %ld %ld %d %*d %Lu %lu %ld", | ||
| 7319 | &c, &ppid, &pgrp, &sess, &tty, &tpgid, | ||
| 7320 | &minflt, &cminflt, &majflt, &cmajflt, | ||
| 7321 | &utime, &stime, &cutime, &cstime, | ||
| 7322 | &priority, &nice, &thcount, &start, &vsize, &rss); | ||
| 7323 | { | ||
| 7324 | char state_str[2]; | ||
| 7325 | |||
| 7326 | state_str[0] = c; | ||
| 7327 | state_str[1] = '\0'; | ||
| 7328 | tem = build_string (state_str); | ||
| 7329 | attrs = Fcons (Fcons (Qstate, tem), attrs); | ||
| 7330 | } | ||
| 7331 | attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (ppid)), attrs); | ||
| 7332 | attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pgrp)), attrs); | ||
| 7333 | attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (sess)), attrs); | ||
| 7334 | attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs); | ||
| 7335 | attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (tpgid)), attrs); | ||
| 7336 | attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (minflt)), attrs); | ||
| 7337 | attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (majflt)), attrs); | ||
| 7338 | attrs = Fcons (Fcons (Qcminflt, make_fixnum_or_float (cminflt)), attrs); | ||
| 7339 | attrs = Fcons (Fcons (Qcmajflt, make_fixnum_or_float (cmajflt)), attrs); | ||
| 7340 | clocks_per_sec = sysconf (_SC_CLK_TCK); | ||
| 7341 | if (clocks_per_sec < 0) | ||
| 7342 | clocks_per_sec = 100; | ||
| 7343 | attrs = Fcons (Fcons (Qutime, | ||
| 7344 | ltime_from_jiffies (utime, clocks_per_sec)), | ||
| 7345 | attrs); | ||
| 7346 | attrs = Fcons (Fcons (Qstime, | ||
| 7347 | ltime_from_jiffies (stime, clocks_per_sec)), | ||
| 7348 | attrs); | ||
| 7349 | attrs = Fcons (Fcons (Qcutime, | ||
| 7350 | ltime_from_jiffies (cutime, clocks_per_sec)), | ||
| 7351 | attrs); | ||
| 7352 | attrs = Fcons (Fcons (Qcstime, | ||
| 7353 | ltime_from_jiffies (cstime, clocks_per_sec)), | ||
| 7354 | attrs); | ||
| 7355 | attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs); | ||
| 7356 | attrs = Fcons (Fcons (Qnice, make_number (nice)), attrs); | ||
| 7357 | attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount)), attrs); | ||
| 7358 | EMACS_GET_TIME (tnow); | ||
| 7359 | get_up_time (&sec, &usec); | ||
| 7360 | EMACS_SET_SECS (telapsed, sec); | ||
| 7361 | EMACS_SET_USECS (telapsed, usec); | ||
| 7362 | EMACS_SUB_TIME (tboot, tnow, telapsed); | ||
| 7363 | time_from_jiffies (start, clocks_per_sec, &sec, &usec); | ||
| 7364 | EMACS_SET_SECS (tstart, sec); | ||
| 7365 | EMACS_SET_USECS (tstart, usec); | ||
| 7366 | EMACS_ADD_TIME (tstart, tboot, tstart); | ||
| 7367 | attrs = Fcons (Fcons (Qstart, | ||
| 7368 | list3 (make_number | ||
| 7369 | ((EMACS_SECS (tstart) >> 16) & 0xffff), | ||
| 7370 | make_number | ||
| 7371 | (EMACS_SECS (tstart) & 0xffff), | ||
| 7372 | make_number | ||
| 7373 | (EMACS_USECS (tstart)))), | ||
| 7374 | attrs); | ||
| 7375 | attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize/1024)), attrs); | ||
| 7376 | attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4*rss)), attrs); | ||
| 7377 | EMACS_SUB_TIME (telapsed, tnow, tstart); | ||
| 7378 | attrs = Fcons (Fcons (Qetime, | ||
| 7379 | list3 (make_number | ||
| 7380 | ((EMACS_SECS (telapsed) >> 16) & 0xffff), | ||
| 7381 | make_number | ||
| 7382 | (EMACS_SECS (telapsed) & 0xffff), | ||
| 7383 | make_number | ||
| 7384 | (EMACS_USECS (telapsed)))), | ||
| 7385 | attrs); | ||
| 7386 | time_from_jiffies (utime + stime, clocks_per_sec, &sec, &usec); | ||
| 7387 | pcpu = (sec + usec / 1000000.0) / (EMACS_SECS (telapsed) + EMACS_USECS (telapsed) / 1000000.0); | ||
| 7388 | attrs = Fcons (Fcons (Qpcpu, make_float (pcpu)), attrs); | ||
| 7389 | pmem = 4.0 * 100 * rss / procfs_get_total_memory (); | ||
| 7390 | if (pmem > 100) | ||
| 7391 | pmem = 100; | ||
| 7392 | attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs); | ||
| 7393 | } | ||
| 7394 | } | ||
| 7395 | if (fd >= 0) | ||
| 7396 | emacs_close (fd); | ||
| 7397 | |||
| 7398 | /* args */ | ||
| 7399 | strcpy (procfn_end, "/cmdline"); | ||
| 7400 | fd = emacs_open (fn, O_RDONLY, 0); | ||
| 7401 | if (fd >= 0) | ||
| 7402 | { | ||
| 7403 | for (cmdsize = 0; emacs_read (fd, (char *)&c, 1) == 1; cmdsize++) | ||
| 7404 | { | ||
| 7405 | if (isspace (c) || c == '\\') | ||
| 7406 | cmdsize++; /* for later quoting, see below */ | ||
| 7407 | } | ||
| 7408 | if (cmdsize) | ||
| 7409 | { | ||
| 7410 | cmdline = xmalloc (cmdsize + 1); | ||
| 7411 | lseek (fd, 0L, SEEK_SET); | ||
| 7412 | cmdline[0] = '\0'; | ||
| 7413 | if ((nread = read (fd, cmdline, cmdsize)) >= 0) | ||
| 7414 | cmdline[nread++] = '\0'; | ||
| 7415 | /* We don't want trailing null characters. */ | ||
| 7416 | for (p = cmdline + nread - 1; p > cmdline && !*p; p--) | ||
| 7417 | nread--; | ||
| 7418 | for (p = cmdline; p < cmdline + nread; p++) | ||
| 7419 | { | ||
| 7420 | /* Escape-quote whitespace and backslashes. */ | ||
| 7421 | if (isspace (*p) || *p == '\\') | ||
| 7422 | { | ||
| 7423 | memmove (p + 1, p, nread - (p - cmdline)); | ||
| 7424 | nread++; | ||
| 7425 | *p++ = '\\'; | ||
| 7426 | } | ||
| 7427 | else if (*p == '\0') | ||
| 7428 | *p = ' '; | ||
| 7429 | } | ||
| 7430 | cmdsize = nread; | ||
| 7431 | } | ||
| 7432 | else | ||
| 7433 | { | ||
| 7434 | cmdsize = strlen (cmd) + 2; | ||
| 7435 | cmdline = xmalloc (cmdsize + 1); | ||
| 7436 | strcpy (cmdline, "["); | ||
| 7437 | strcat (strcat (cmdline, cmd), "]"); | ||
| 7438 | } | ||
| 7439 | emacs_close (fd); | ||
| 7440 | /* Command line is encoded in locale-coding-system; decode it. */ | ||
| 7441 | cmd_str = make_unibyte_string (cmdline, cmdsize); | ||
| 7442 | decoded_cmd = code_convert_string_norecord (cmd_str, | ||
| 7443 | Vlocale_coding_system, 0); | ||
| 7444 | xfree (cmdline); | ||
| 7445 | attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); | ||
| 7446 | } | ||
| 7447 | |||
| 7448 | UNGCPRO; | ||
| 7449 | return attrs; | ||
| 7450 | } | ||
| 7451 | |||
| 7452 | #endif /* !HAVE_PROCFS */ | ||
| 7453 | |||
| 7454 | DEFUN ("list-system-processes", Flist_system_processes, Slist_system_processes, | ||
| 7455 | 0, 0, 0, | ||
| 7456 | doc: /* Return a list of numerical process IDs of all running processes. | ||
| 7457 | If this functionality is unsupported, return nil. | ||
| 7458 | |||
| 7459 | See `system-process-attributes' for getting attributes of a process | ||
| 7460 | given its ID. */) | ||
| 7461 | () | ||
| 7462 | { | ||
| 7463 | #ifdef LISTPROC | ||
| 7464 | return LISTPROC (); | ||
| 7465 | #else | ||
| 7466 | return Qnil; | ||
| 7467 | #endif | ||
| 7468 | } | ||
| 7469 | |||
| 7470 | DEFUN ("system-process-attributes", Fsystem_process_attributes, | ||
| 7471 | Ssystem_process_attributeses, 1, 1, 0, | ||
| 7472 | doc: /* Return attributes of the process given by its PID, a number. | ||
| 7473 | |||
| 7474 | Value is an alist where each element is a cons cell of the form | ||
| 7475 | |||
| 7476 | \(ATTR . VALUE) | ||
| 7477 | |||
| 7478 | If this functionality is unsupported, the value is nil. | ||
| 7479 | |||
| 7480 | See `list-system-processes' for getting a list of all process IDs. | ||
| 7481 | |||
| 7482 | The attributes that this function may return are listed below, | ||
| 7483 | together with the type of the associated value (in parentheses). | ||
| 7484 | Unless explicitly indicated otherwise, numbers can have either | ||
| 7485 | integer or floating point values. | ||
| 7486 | |||
| 7487 | euid -- Effective user User ID of the process (number) | ||
| 7488 | user -- User name corresponding to euid (string) | ||
| 7489 | egid -- Effective user Group ID of the process (number) | ||
| 7490 | group -- Group name corresponding to egid (string) | ||
| 7491 | comm -- Command name (executable name only) (string) | ||
| 7492 | state -- Process state code, such as "S", "R", or "T" (string) | ||
| 7493 | ppid -- Parent process ID (number) | ||
| 7494 | pgrp -- Process group ID (number) | ||
| 7495 | sess -- Session ID, i.e. process ID of session leader (number) | ||
| 7496 | ttname -- Controlling tty name (string) | ||
| 7497 | tpgid -- ID of foreground process group on the process's tty (number) | ||
| 7498 | minflt -- number of minor page faults (number) | ||
| 7499 | majflt -- number of major page faults (number) | ||
| 7500 | cminflt -- cumulative number of minor page faults (number) | ||
| 7501 | cmajflt -- cumulative number of major page faults (number) | ||
| 7502 | utime -- user time used by the process, in the (HIGH LOW USEC) format | ||
| 7503 | stime -- system time used by the process, in the (HIGH LOW USEC) format | ||
| 7504 | cutime -- user time used by the process and its children, (HIGH LOW USEC) | ||
| 7505 | cstime -- system time used by the process and its children, (HIGH LOW USEC) | ||
| 7506 | pri -- priority of the process (number) | ||
| 7507 | nice -- nice value of the process (number) | ||
| 7508 | thcount -- process thread count (number) | ||
| 7509 | start -- time the process started, in the (HIGH LOW USEC) format | ||
| 7510 | vsize -- virtual memory size of the process in KB's (number) | ||
| 7511 | rss -- resident set size of the process in KB's (number) | ||
| 7512 | etime -- elapsed time the process is running, in (HIGH LOW USEC) format | ||
| 7513 | pcpu -- percents of CPU time used by the process (floating-point number) | ||
| 7514 | pmem -- percents of total physical memory used by process's resident set | ||
| 7515 | (floating-point number) | ||
| 7516 | args -- command line which invoked the process (string). */) | ||
| 7517 | (pid) | ||
| 7518 | |||
| 7519 | Lisp_Object pid; | ||
| 7520 | { | ||
| 7521 | #ifdef PROCATTR | ||
| 7522 | return PROCATTR (pid); | ||
| 7523 | #else | ||
| 7524 | return Qnil; | ||
| 7525 | #endif | ||
| 7526 | } | ||
| 7527 | |||
| 7060 | void | 7528 | void |
| 7061 | init_process () | 7529 | init_process () |
| 7062 | { | 7530 | { |
| @@ -7270,6 +7738,65 @@ syms_of_process () | |||
| 7270 | staticpro (&deleted_pid_list); | 7738 | staticpro (&deleted_pid_list); |
| 7271 | #endif | 7739 | #endif |
| 7272 | 7740 | ||
| 7741 | Qeuid = intern ("euid"); | ||
| 7742 | staticpro (&Qeuid); | ||
| 7743 | Qegid = intern ("egid"); | ||
| 7744 | staticpro (&Qegid); | ||
| 7745 | Quser = intern ("user"); | ||
| 7746 | staticpro (&Quser); | ||
| 7747 | Qgroup = intern ("group"); | ||
| 7748 | staticpro (&Qgroup); | ||
| 7749 | Qcomm = intern ("comm"); | ||
| 7750 | staticpro (&Qcomm); | ||
| 7751 | Qstate = intern ("state"); | ||
| 7752 | staticpro (&Qstate); | ||
| 7753 | Qppid = intern ("ppid"); | ||
| 7754 | staticpro (&Qppid); | ||
| 7755 | Qpgrp = intern ("pgrp"); | ||
| 7756 | staticpro (&Qpgrp); | ||
| 7757 | Qsess = intern ("sess"); | ||
| 7758 | staticpro (&Qsess); | ||
| 7759 | Qttname = intern ("ttname"); | ||
| 7760 | staticpro (&Qttname); | ||
| 7761 | Qtpgid = intern ("tpgid"); | ||
| 7762 | staticpro (&Qtpgid); | ||
| 7763 | Qminflt = intern ("minflt"); | ||
| 7764 | staticpro (&Qminflt); | ||
| 7765 | Qmajflt = intern ("majflt"); | ||
| 7766 | staticpro (&Qmajflt); | ||
| 7767 | Qcminflt = intern ("cminflt"); | ||
| 7768 | staticpro (&Qcminflt); | ||
| 7769 | Qcmajflt = intern ("cmajflt"); | ||
| 7770 | staticpro (&Qcmajflt); | ||
| 7771 | Qutime = intern ("utime"); | ||
| 7772 | staticpro (&Qutime); | ||
| 7773 | Qstime = intern ("stime"); | ||
| 7774 | staticpro (&Qstime); | ||
| 7775 | Qcutime = intern ("cutime"); | ||
| 7776 | staticpro (&Qcutime); | ||
| 7777 | Qcstime = intern ("cstime"); | ||
| 7778 | staticpro (&Qcstime); | ||
| 7779 | Qpri = intern ("pri"); | ||
| 7780 | staticpro (&Qpri); | ||
| 7781 | Qnice = intern ("nice"); | ||
| 7782 | staticpro (&Qnice); | ||
| 7783 | Qthcount = intern ("thcount"); | ||
| 7784 | staticpro (&Qthcount); | ||
| 7785 | Qstart = intern ("start"); | ||
| 7786 | staticpro (&Qstart); | ||
| 7787 | Qvsize = intern ("vsize"); | ||
| 7788 | staticpro (&Qvsize); | ||
| 7789 | Qrss = intern ("rss"); | ||
| 7790 | staticpro (&Qrss); | ||
| 7791 | Qetime = intern ("etime"); | ||
| 7792 | staticpro (&Qetime); | ||
| 7793 | Qpcpu = intern ("pcpu"); | ||
| 7794 | staticpro (&Qpcpu); | ||
| 7795 | Qpmem = intern ("pmem"); | ||
| 7796 | staticpro (&Qpmem); | ||
| 7797 | Qargs = intern ("args"); | ||
| 7798 | staticpro (&Qargs); | ||
| 7799 | |||
| 7273 | DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes, | 7800 | DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes, |
| 7274 | doc: /* *Non-nil means delete processes immediately when they exit. | 7801 | doc: /* *Non-nil means delete processes immediately when they exit. |
| 7275 | A value of nil means don't delete them until `list-processes' is run. */); | 7802 | A value of nil means don't delete them until `list-processes' is run. */); |
| @@ -7364,6 +7891,8 @@ The variable takes effect when `start-process' is called. */); | |||
| 7364 | defsubr (&Sprocess_coding_system); | 7891 | defsubr (&Sprocess_coding_system); |
| 7365 | defsubr (&Sset_process_filter_multibyte); | 7892 | defsubr (&Sset_process_filter_multibyte); |
| 7366 | defsubr (&Sprocess_filter_multibyte_p); | 7893 | defsubr (&Sprocess_filter_multibyte_p); |
| 7894 | defsubr (&Slist_system_processes); | ||
| 7895 | defsubr (&Ssystem_process_attributeses); | ||
| 7367 | } | 7896 | } |
| 7368 | 7897 | ||
| 7369 | 7898 | ||
| @@ -7371,6 +7900,12 @@ The variable takes effect when `start-process' is called. */); | |||
| 7371 | 7900 | ||
| 7372 | #include <sys/types.h> | 7901 | #include <sys/types.h> |
| 7373 | #include <errno.h> | 7902 | #include <errno.h> |
| 7903 | #include <sys/stat.h> | ||
| 7904 | #include <stdlib.h> | ||
| 7905 | #include <fcntl.h> | ||
| 7906 | #ifdef HAVE_UNISTD_H | ||
| 7907 | #include <unistd.h> | ||
| 7908 | #endif | ||
| 7374 | 7909 | ||
| 7375 | #include "lisp.h" | 7910 | #include "lisp.h" |
| 7376 | #include "systime.h" | 7911 | #include "systime.h" |
| @@ -7646,6 +8181,72 @@ kill_buffer_processes (buffer) | |||
| 7646 | { | 8181 | { |
| 7647 | } | 8182 | } |
| 7648 | 8183 | ||
| 8184 | DEFUN ("list-system-processes", Flist_system_processes, Slist_system_processes, | ||
| 8185 | 0, 0, 0, | ||
| 8186 | doc: /* Return a list of numerical process IDs of all running processes. | ||
| 8187 | If this functionality is unsupported, return nil. | ||
| 8188 | |||
| 8189 | See `system-process-attributes' for getting attributes of a process | ||
| 8190 | given its ID. */) | ||
| 8191 | () | ||
| 8192 | { | ||
| 8193 | return Qnil; | ||
| 8194 | } | ||
| 8195 | |||
| 8196 | DEFUN ("system-process-attributes", Fsystem_process_attributes, | ||
| 8197 | Ssystem_process_attributeses, 1, 1, 0, | ||
| 8198 | doc: /* Return attributes of the process given by its PID, a number. | ||
| 8199 | |||
| 8200 | Value is an alist where each element is a cons cell of the form | ||
| 8201 | |||
| 8202 | \(ATTR . VALUE) | ||
| 8203 | |||
| 8204 | If this functionality is unsupported, the value is nil. | ||
| 8205 | |||
| 8206 | See `list-system-processes' for getting a list of all process IDs. | ||
| 8207 | |||
| 8208 | The attributes that this function may return are listed below, | ||
| 8209 | together with the type of the associated value (in parentheses). | ||
| 8210 | Unless explicitly indicated otherwise, numbers can have either | ||
| 8211 | integer or floating point values. | ||
| 8212 | |||
| 8213 | euid -- Effective user User ID of the process (number) | ||
| 8214 | user -- User name corresponding to euid (string) | ||
| 8215 | egid -- Effective user Group ID of the process (number) | ||
| 8216 | group -- Group name corresponding to egid (string) | ||
| 8217 | comm -- Command name (executable name only) (string) | ||
| 8218 | state -- Process state code, such as "S", "R", or "T" (string) | ||
| 8219 | ppid -- Parent process ID (number) | ||
| 8220 | pgrp -- Process group ID (number) | ||
| 8221 | sess -- Session ID, i.e. process ID of session leader (number) | ||
| 8222 | ttname -- Controlling tty name (string) | ||
| 8223 | tpgid -- ID of foreground process group on the process's tty (number) | ||
| 8224 | minflt -- number of minor page faults (number) | ||
| 8225 | majflt -- number of major page faults (number) | ||
| 8226 | cminflt -- cumulative number of minor page faults (number) | ||
| 8227 | cmajflt -- cumulative number of major page faults (number) | ||
| 8228 | utime -- user time used by the process, in the (HIGH LOW USEC) format | ||
| 8229 | stime -- system time used by the process, in the (HIGH LOW USEC) format | ||
| 8230 | cutime -- user time used by the process and its children, (HIGH LOW USEC) | ||
| 8231 | cstime -- system time used by the process and its children, (HIGH LOW USEC) | ||
| 8232 | pri -- priority of the process (number) | ||
| 8233 | nice -- nice value of the process (number) | ||
| 8234 | thcount -- process thread count (number) | ||
| 8235 | start -- time the process started, in the (HIGH LOW USEC) format | ||
| 8236 | vsize -- virtual memory size of the process in KB's (number) | ||
| 8237 | rss -- resident set size of the process in KB's (number) | ||
| 8238 | etime -- elapsed time the process is running, in (HIGH LOW USEC) format | ||
| 8239 | pcpu -- percents of CPU time used by the process (floating-point number) | ||
| 8240 | pmem -- percents of total physical memory used by process's resident set | ||
| 8241 | (floating-point number) | ||
| 8242 | args -- command line which invoked the process (string). */) | ||
| 8243 | (pid) | ||
| 8244 | |||
| 8245 | Lisp_Object pid; | ||
| 8246 | { | ||
| 8247 | return Qnil; | ||
| 8248 | } | ||
| 8249 | |||
| 7649 | void | 8250 | void |
| 7650 | init_process () | 8251 | init_process () |
| 7651 | { | 8252 | { |
| @@ -7659,6 +8260,8 @@ syms_of_process () | |||
| 7659 | 8260 | ||
| 7660 | defsubr (&Sget_buffer_process); | 8261 | defsubr (&Sget_buffer_process); |
| 7661 | defsubr (&Sprocess_inherit_coding_system_flag); | 8262 | defsubr (&Sprocess_inherit_coding_system_flag); |
| 8263 | defsubr (&Slist_system_processes); | ||
| 8264 | defsubr (&Ssystem_process_attributeses); | ||
| 7662 | } | 8265 | } |
| 7663 | 8266 | ||
| 7664 | 8267 | ||