diff options
| author | Dan Nicolaescu | 2008-12-19 19:50:35 +0000 |
|---|---|---|
| committer | Dan Nicolaescu | 2008-12-19 19:50:35 +0000 |
| commit | 06e111a6efbbe275e8f7c364ff8e5955d1ab75f0 (patch) | |
| tree | 3ed4dc7cbf6c74663a3c4bd4c35b71e40ab2e3e9 /src/sysdep.c | |
| parent | 349b3256608412d33ddabc7c3f9b429123e7c353 (diff) | |
| download | emacs-06e111a6efbbe275e8f7c364ff8e5955d1ab75f0.tar.gz emacs-06e111a6efbbe275e8f7c364ff8e5955d1ab75f0.zip | |
Reorganize implementation of Flist_system_processes and
Fsystem_process_attributes. No functional changes.
* process.c: Don't #include pwd.h, grp.h and limits.h.
(Flist_system_processes): Just call list_system_processes.
(Fsystem_process_attributes): Just call system_process_attributes.
(procfs_list_system_processes, time_from_jiffies)
(ltime_from_jiffies, get_up_time, procfs_ttyname, MAJOR, MINOR)
(procfs_get_total_memory, procfs_system_process_attributes): Move ...
* sysdep.c: ... here. Include pwd.h, grp.h and limits.h.
(list_system_processes): Rename from
procfs_list_system_processes. Enclose in #ifdef HAVE_PROCFS.
Provide a do nothing implementation.
(system_process_attributes): Rename from
procfs_list_system_processes.
(ltime_from_jiffies, get_up_time, procfs_ttyname, MAJOR, MINOR)
(procfs_get_total_memory): Enclose in #ifdef GNU_LINUX.
* w32.c (list_system_processes): Rename from
w32_list_system_processes.
(system_process_attributes): Rename from
w32_system_process_attributes.
* s/gnu-linux.h (LISTPROC, PROCATTR): Remove.
* process.h (w32_list_system_processes)
(w32_system_process_attributes): Remove.
(list_system_processes, system_process_attributes): New
prototypes.
* config.nt (LISTPROC, PROCATTR): Remove.
Diffstat (limited to 'src/sysdep.c')
| -rw-r--r-- | src/sysdep.c | 444 |
1 files changed, 444 insertions, 0 deletions
diff --git a/src/sysdep.c b/src/sysdep.c index 0a2e2ed1614..7f53ea2f788 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -25,6 +25,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 25 | #include <signal.h> | 25 | #include <signal.h> |
| 26 | #include <stdio.h> | 26 | #include <stdio.h> |
| 27 | #include <setjmp.h> | 27 | #include <setjmp.h> |
| 28 | #ifdef HAVE_PWD_H | ||
| 29 | #include <pwd.h> | ||
| 30 | #include <grp.h> | ||
| 31 | #endif /* HAVE_PWD_H */ | ||
| 32 | #ifdef HAVE_LIMITS_H | ||
| 33 | #include <limits.h> | ||
| 34 | #endif /* HAVE_LIMITS_H */ | ||
| 28 | #ifdef HAVE_UNISTD_H | 35 | #ifdef HAVE_UNISTD_H |
| 29 | #include <unistd.h> | 36 | #include <unistd.h> |
| 30 | #endif | 37 | #endif |
| @@ -3171,6 +3178,443 @@ serial_configure (struct Lisp_Process *p, | |||
| 3171 | 3178 | ||
| 3172 | } | 3179 | } |
| 3173 | #endif /* TERMIOS */ | 3180 | #endif /* TERMIOS */ |
| 3181 | |||
| 3182 | /* System depended enumeration of and access to system processes a-la ps(1). */ | ||
| 3183 | |||
| 3184 | #ifdef HAVE_PROCFS | ||
| 3185 | |||
| 3186 | /* Process enumeration and access via /proc. */ | ||
| 3187 | |||
| 3188 | Lisp_Object | ||
| 3189 | list_system_processes () | ||
| 3190 | { | ||
| 3191 | Lisp_Object procdir, match, proclist, next; | ||
| 3192 | struct gcpro gcpro1, gcpro2; | ||
| 3193 | register Lisp_Object tail; | ||
| 3194 | |||
| 3195 | GCPRO2 (procdir, match); | ||
| 3196 | /* For every process on the system, there's a directory in the | ||
| 3197 | "/proc" pseudo-directory whose name is the numeric ID of that | ||
| 3198 | process. */ | ||
| 3199 | procdir = build_string ("/proc"); | ||
| 3200 | match = build_string ("[0-9]+"); | ||
| 3201 | proclist = directory_files_internal (procdir, Qnil, match, Qt, 0, Qnil); | ||
| 3202 | |||
| 3203 | /* `proclist' gives process IDs as strings. Destructively convert | ||
| 3204 | each string into a number. */ | ||
| 3205 | for (tail = proclist; CONSP (tail); tail = next) | ||
| 3206 | { | ||
| 3207 | next = XCDR (tail); | ||
| 3208 | XSETCAR (tail, Fstring_to_number (XCAR (tail), Qnil)); | ||
| 3209 | } | ||
| 3210 | UNGCPRO; | ||
| 3211 | |||
| 3212 | /* directory_files_internal returns the files in reverse order; undo | ||
| 3213 | that. */ | ||
| 3214 | proclist = Fnreverse (proclist); | ||
| 3215 | return proclist; | ||
| 3216 | } | ||
| 3217 | |||
| 3218 | #elif !defined (WINDOWSNT) | ||
| 3219 | |||
| 3220 | Lisp_Object | ||
| 3221 | list_system_processes () | ||
| 3222 | { | ||
| 3223 | return Qnil; | ||
| 3224 | } | ||
| 3225 | #endif /* !defined (WINDOWSNT)*/ | ||
| 3226 | |||
| 3227 | #ifdef GNU_LINUX | ||
| 3228 | static void | ||
| 3229 | time_from_jiffies (unsigned long long tval, long hz, | ||
| 3230 | time_t *sec, unsigned *usec) | ||
| 3231 | { | ||
| 3232 | unsigned long long ullsec; | ||
| 3233 | |||
| 3234 | *sec = tval / hz; | ||
| 3235 | ullsec = *sec; | ||
| 3236 | tval -= ullsec * hz; | ||
| 3237 | /* Careful: if HZ > 1 million, then integer division by it yields zero. */ | ||
| 3238 | if (hz <= 1000000) | ||
| 3239 | *usec = tval * 1000000 / hz; | ||
| 3240 | else | ||
| 3241 | *usec = tval / (hz / 1000000); | ||
| 3242 | } | ||
| 3243 | |||
| 3244 | static Lisp_Object | ||
| 3245 | ltime_from_jiffies (unsigned long long tval, long hz) | ||
| 3246 | { | ||
| 3247 | time_t sec; | ||
| 3248 | unsigned usec; | ||
| 3249 | |||
| 3250 | time_from_jiffies (tval, hz, &sec, &usec); | ||
| 3251 | |||
| 3252 | return list3 (make_number ((sec >> 16) & 0xffff), | ||
| 3253 | make_number (sec & 0xffff), | ||
| 3254 | make_number (usec)); | ||
| 3255 | } | ||
| 3256 | |||
| 3257 | static void | ||
| 3258 | get_up_time (time_t *sec, unsigned *usec) | ||
| 3259 | { | ||
| 3260 | FILE *fup; | ||
| 3261 | |||
| 3262 | *sec = *usec = 0; | ||
| 3263 | |||
| 3264 | BLOCK_INPUT; | ||
| 3265 | fup = fopen ("/proc/uptime", "r"); | ||
| 3266 | |||
| 3267 | if (fup) | ||
| 3268 | { | ||
| 3269 | double uptime, idletime; | ||
| 3270 | |||
| 3271 | /* The numbers in /proc/uptime use C-locale decimal point, but | ||
| 3272 | we already set ourselves to the C locale (see `fixup_locale' | ||
| 3273 | in emacs.c). */ | ||
| 3274 | if (2 <= fscanf (fup, "%lf %lf", &uptime, &idletime)) | ||
| 3275 | { | ||
| 3276 | *sec = uptime; | ||
| 3277 | *usec = (uptime - *sec) * 1000000; | ||
| 3278 | } | ||
| 3279 | fclose (fup); | ||
| 3280 | } | ||
| 3281 | UNBLOCK_INPUT; | ||
| 3282 | } | ||
| 3283 | |||
| 3284 | #define MAJOR(d) (((unsigned)(d) >> 8) & 0xfff) | ||
| 3285 | #define MINOR(d) (((unsigned)(d) & 0xff) | (((unsigned)(d) & 0xfff00000) >> 12)) | ||
| 3286 | |||
| 3287 | static Lisp_Object | ||
| 3288 | procfs_ttyname (rdev) | ||
| 3289 | { | ||
| 3290 | FILE *fdev = NULL; | ||
| 3291 | char name[PATH_MAX]; | ||
| 3292 | |||
| 3293 | BLOCK_INPUT; | ||
| 3294 | fdev = fopen ("/proc/tty/drivers", "r"); | ||
| 3295 | |||
| 3296 | if (fdev) | ||
| 3297 | { | ||
| 3298 | unsigned major; | ||
| 3299 | unsigned long minor_beg, minor_end; | ||
| 3300 | char minor[25]; /* 2 32-bit numbers + dash */ | ||
| 3301 | char *endp; | ||
| 3302 | |||
| 3303 | while (!feof (fdev) && !ferror (fdev)) | ||
| 3304 | { | ||
| 3305 | if (3 <= fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) | ||
| 3306 | && major == MAJOR (rdev)) | ||
| 3307 | { | ||
| 3308 | minor_beg = strtoul (minor, &endp, 0); | ||
| 3309 | if (*endp == '\0') | ||
| 3310 | minor_end = minor_beg; | ||
| 3311 | else if (*endp == '-') | ||
| 3312 | minor_end = strtoul (endp + 1, &endp, 0); | ||
| 3313 | else | ||
| 3314 | continue; | ||
| 3315 | |||
| 3316 | if (MINOR (rdev) >= minor_beg && MINOR (rdev) <= minor_end) | ||
| 3317 | { | ||
| 3318 | sprintf (name + strlen (name), "%lu", MINOR (rdev)); | ||
| 3319 | break; | ||
| 3320 | } | ||
| 3321 | } | ||
| 3322 | } | ||
| 3323 | fclose (fdev); | ||
| 3324 | } | ||
| 3325 | UNBLOCK_INPUT; | ||
| 3326 | return build_string (name); | ||
| 3327 | } | ||
| 3328 | |||
| 3329 | static unsigned long | ||
| 3330 | procfs_get_total_memory (void) | ||
| 3331 | { | ||
| 3332 | FILE *fmem = NULL; | ||
| 3333 | unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */ | ||
| 3334 | |||
| 3335 | BLOCK_INPUT; | ||
| 3336 | fmem = fopen ("/proc/meminfo", "r"); | ||
| 3337 | |||
| 3338 | if (fmem) | ||
| 3339 | { | ||
| 3340 | unsigned long entry_value; | ||
| 3341 | char entry_name[20]; /* the longest I saw is 13+1 */ | ||
| 3342 | |||
| 3343 | while (!feof (fmem) && !ferror (fmem)) | ||
| 3344 | { | ||
| 3345 | if (2 <= fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value) | ||
| 3346 | && strcmp (entry_name, "MemTotal:") == 0) | ||
| 3347 | { | ||
| 3348 | retval = entry_value; | ||
| 3349 | break; | ||
| 3350 | } | ||
| 3351 | } | ||
| 3352 | fclose (fmem); | ||
| 3353 | } | ||
| 3354 | UNBLOCK_INPUT; | ||
| 3355 | return retval; | ||
| 3356 | } | ||
| 3357 | |||
| 3358 | Lisp_Object | ||
| 3359 | system_process_attributes (pid) | ||
| 3360 | Lisp_Object pid; | ||
| 3361 | { | ||
| 3362 | char procfn[PATH_MAX], fn[PATH_MAX]; | ||
| 3363 | struct stat st; | ||
| 3364 | struct passwd *pw; | ||
| 3365 | struct group *gr; | ||
| 3366 | long clocks_per_sec; | ||
| 3367 | char *procfn_end; | ||
| 3368 | char procbuf[1025], *p, *q; | ||
| 3369 | int fd; | ||
| 3370 | ssize_t nread; | ||
| 3371 | const char *cmd = NULL; | ||
| 3372 | char *cmdline = NULL; | ||
| 3373 | size_t cmdsize = 0, cmdline_size; | ||
| 3374 | unsigned char c; | ||
| 3375 | int proc_id, ppid, uid, gid, pgrp, sess, tty, tpgid, thcount; | ||
| 3376 | unsigned long long utime, stime, cutime, cstime, start; | ||
| 3377 | long priority, nice, rss; | ||
| 3378 | unsigned long minflt, majflt, cminflt, cmajflt, vsize; | ||
| 3379 | time_t sec; | ||
| 3380 | unsigned usec; | ||
| 3381 | EMACS_TIME tnow, tstart, tboot, telapsed,ttotal; | ||
| 3382 | double pcpu, pmem; | ||
| 3383 | Lisp_Object attrs = Qnil; | ||
| 3384 | Lisp_Object cmd_str, decoded_cmd, tem; | ||
| 3385 | struct gcpro gcpro1, gcpro2; | ||
| 3386 | EMACS_INT uid_eint, gid_eint; | ||
| 3387 | |||
| 3388 | CHECK_NUMBER_OR_FLOAT (pid); | ||
| 3389 | proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid); | ||
| 3390 | sprintf (procfn, "/proc/%lu", proc_id); | ||
| 3391 | if (stat (procfn, &st) < 0) | ||
| 3392 | return attrs; | ||
| 3393 | |||
| 3394 | GCPRO2 (attrs, decoded_cmd); | ||
| 3395 | |||
| 3396 | /* euid egid */ | ||
| 3397 | uid = st.st_uid; | ||
| 3398 | /* Use of EMACS_INT stops GCC whining about limited range of data type. */ | ||
| 3399 | uid_eint = uid; | ||
| 3400 | attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid_eint)), attrs); | ||
| 3401 | BLOCK_INPUT; | ||
| 3402 | pw = getpwuid (uid); | ||
| 3403 | UNBLOCK_INPUT; | ||
| 3404 | if (pw) | ||
| 3405 | attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs); | ||
| 3406 | |||
| 3407 | gid = st.st_gid; | ||
| 3408 | gid_eint = gid; | ||
| 3409 | attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid_eint)), attrs); | ||
| 3410 | BLOCK_INPUT; | ||
| 3411 | gr = getgrgid (gid); | ||
| 3412 | UNBLOCK_INPUT; | ||
| 3413 | if (gr) | ||
| 3414 | attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); | ||
| 3415 | |||
| 3416 | strcpy (fn, procfn); | ||
| 3417 | procfn_end = fn + strlen (fn); | ||
| 3418 | strcpy (procfn_end, "/stat"); | ||
| 3419 | fd = emacs_open (fn, O_RDONLY, 0); | ||
| 3420 | if (fd >= 0 && (nread = emacs_read (fd, procbuf, sizeof(procbuf) - 1)) > 0) | ||
| 3421 | { | ||
| 3422 | procbuf[nread] = '\0'; | ||
| 3423 | p = procbuf; | ||
| 3424 | |||
| 3425 | p = strchr (p, '('); | ||
| 3426 | if (p != NULL) | ||
| 3427 | { | ||
| 3428 | q = strrchr (p + 1, ')'); | ||
| 3429 | /* comm */ | ||
| 3430 | if (q != NULL) | ||
| 3431 | { | ||
| 3432 | cmd = p + 1; | ||
| 3433 | cmdsize = q - cmd; | ||
| 3434 | } | ||
| 3435 | } | ||
| 3436 | else | ||
| 3437 | q = NULL; | ||
| 3438 | if (cmd == NULL) | ||
| 3439 | { | ||
| 3440 | cmd = "???"; | ||
| 3441 | cmdsize = 3; | ||
| 3442 | } | ||
| 3443 | /* Command name is encoded in locale-coding-system; decode it. */ | ||
| 3444 | cmd_str = make_unibyte_string (cmd, cmdsize); | ||
| 3445 | decoded_cmd = code_convert_string_norecord (cmd_str, | ||
| 3446 | Vlocale_coding_system, 0); | ||
| 3447 | attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); | ||
| 3448 | |||
| 3449 | if (q) | ||
| 3450 | { | ||
| 3451 | EMACS_INT ppid_eint, pgrp_eint, sess_eint, tpgid_eint, thcount_eint; | ||
| 3452 | p = q + 2; | ||
| 3453 | /* state ppid pgrp sess tty tpgid . minflt cminflt majflt cmajflt utime stime cutime cstime priority nice thcount . start vsize rss */ | ||
| 3454 | sscanf (p, "%c %d %d %d %d %d %*u %lu %lu %lu %lu %Lu %Lu %Lu %Lu %ld %ld %d %*d %Lu %lu %ld", | ||
| 3455 | &c, &ppid, &pgrp, &sess, &tty, &tpgid, | ||
| 3456 | &minflt, &cminflt, &majflt, &cmajflt, | ||
| 3457 | &utime, &stime, &cutime, &cstime, | ||
| 3458 | &priority, &nice, &thcount, &start, &vsize, &rss); | ||
| 3459 | { | ||
| 3460 | char state_str[2]; | ||
| 3461 | |||
| 3462 | state_str[0] = c; | ||
| 3463 | state_str[1] = '\0'; | ||
| 3464 | tem = build_string (state_str); | ||
| 3465 | attrs = Fcons (Fcons (Qstate, tem), attrs); | ||
| 3466 | } | ||
| 3467 | /* Stops GCC whining about limited range of data type. */ | ||
| 3468 | ppid_eint = ppid; | ||
| 3469 | pgrp_eint = pgrp; | ||
| 3470 | sess_eint = sess; | ||
| 3471 | tpgid_eint = tpgid; | ||
| 3472 | thcount_eint = thcount; | ||
| 3473 | attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (ppid_eint)), attrs); | ||
| 3474 | attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pgrp_eint)), attrs); | ||
| 3475 | attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (sess_eint)), attrs); | ||
| 3476 | attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs); | ||
| 3477 | attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (tpgid_eint)), attrs); | ||
| 3478 | attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (minflt)), attrs); | ||
| 3479 | attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (majflt)), attrs); | ||
| 3480 | attrs = Fcons (Fcons (Qcminflt, make_fixnum_or_float (cminflt)), attrs); | ||
| 3481 | attrs = Fcons (Fcons (Qcmajflt, make_fixnum_or_float (cmajflt)), attrs); | ||
| 3482 | clocks_per_sec = sysconf (_SC_CLK_TCK); | ||
| 3483 | if (clocks_per_sec < 0) | ||
| 3484 | clocks_per_sec = 100; | ||
| 3485 | attrs = Fcons (Fcons (Qutime, | ||
| 3486 | ltime_from_jiffies (utime, clocks_per_sec)), | ||
| 3487 | attrs); | ||
| 3488 | attrs = Fcons (Fcons (Qstime, | ||
| 3489 | ltime_from_jiffies (stime, clocks_per_sec)), | ||
| 3490 | attrs); | ||
| 3491 | attrs = Fcons (Fcons (Qcutime, | ||
| 3492 | ltime_from_jiffies (cutime, clocks_per_sec)), | ||
| 3493 | attrs); | ||
| 3494 | attrs = Fcons (Fcons (Qcstime, | ||
| 3495 | ltime_from_jiffies (cstime, clocks_per_sec)), | ||
| 3496 | attrs); | ||
| 3497 | attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs); | ||
| 3498 | attrs = Fcons (Fcons (Qnice, make_number (nice)), attrs); | ||
| 3499 | attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount_eint)), attrs); | ||
| 3500 | EMACS_GET_TIME (tnow); | ||
| 3501 | get_up_time (&sec, &usec); | ||
| 3502 | EMACS_SET_SECS (telapsed, sec); | ||
| 3503 | EMACS_SET_USECS (telapsed, usec); | ||
| 3504 | EMACS_SUB_TIME (tboot, tnow, telapsed); | ||
| 3505 | time_from_jiffies (start, clocks_per_sec, &sec, &usec); | ||
| 3506 | EMACS_SET_SECS (tstart, sec); | ||
| 3507 | EMACS_SET_USECS (tstart, usec); | ||
| 3508 | EMACS_ADD_TIME (tstart, tboot, tstart); | ||
| 3509 | attrs = Fcons (Fcons (Qstart, | ||
| 3510 | list3 (make_number | ||
| 3511 | ((EMACS_SECS (tstart) >> 16) & 0xffff), | ||
| 3512 | make_number | ||
| 3513 | (EMACS_SECS (tstart) & 0xffff), | ||
| 3514 | make_number | ||
| 3515 | (EMACS_USECS (tstart)))), | ||
| 3516 | attrs); | ||
| 3517 | attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize/1024)), attrs); | ||
| 3518 | attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4*rss)), attrs); | ||
| 3519 | EMACS_SUB_TIME (telapsed, tnow, tstart); | ||
| 3520 | attrs = Fcons (Fcons (Qetime, | ||
| 3521 | list3 (make_number | ||
| 3522 | ((EMACS_SECS (telapsed) >> 16) & 0xffff), | ||
| 3523 | make_number | ||
| 3524 | (EMACS_SECS (telapsed) & 0xffff), | ||
| 3525 | make_number | ||
| 3526 | (EMACS_USECS (telapsed)))), | ||
| 3527 | attrs); | ||
| 3528 | time_from_jiffies (utime + stime, clocks_per_sec, &sec, &usec); | ||
| 3529 | pcpu = (sec + usec / 1000000.0) / (EMACS_SECS (telapsed) + EMACS_USECS (telapsed) / 1000000.0); | ||
| 3530 | if (pcpu > 1.0) | ||
| 3531 | pcpu = 1.0; | ||
| 3532 | attrs = Fcons (Fcons (Qpcpu, make_float (100 * pcpu)), attrs); | ||
| 3533 | pmem = 4.0 * 100 * rss / procfs_get_total_memory (); | ||
| 3534 | if (pmem > 100) | ||
| 3535 | pmem = 100; | ||
| 3536 | attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs); | ||
| 3537 | } | ||
| 3538 | } | ||
| 3539 | if (fd >= 0) | ||
| 3540 | emacs_close (fd); | ||
| 3541 | |||
| 3542 | /* args */ | ||
| 3543 | strcpy (procfn_end, "/cmdline"); | ||
| 3544 | fd = emacs_open (fn, O_RDONLY, 0); | ||
| 3545 | if (fd >= 0) | ||
| 3546 | { | ||
| 3547 | for (cmdline_size = 0; emacs_read (fd, &c, 1) == 1; cmdline_size++) | ||
| 3548 | { | ||
| 3549 | if (isspace (c) || c == '\\') | ||
| 3550 | cmdline_size++; /* for later quoting, see below */ | ||
| 3551 | } | ||
| 3552 | if (cmdline_size) | ||
| 3553 | { | ||
| 3554 | cmdline = xmalloc (cmdline_size + 1); | ||
| 3555 | lseek (fd, 0L, SEEK_SET); | ||
| 3556 | cmdline[0] = '\0'; | ||
| 3557 | if ((nread = read (fd, cmdline, cmdline_size)) >= 0) | ||
| 3558 | cmdline[nread++] = '\0'; | ||
| 3559 | else | ||
| 3560 | { | ||
| 3561 | /* Assigning zero to `nread' makes us skip the following | ||
| 3562 | two loops, assign zero to cmdline_size, and enter the | ||
| 3563 | following `if' clause that handles unknown command | ||
| 3564 | lines. */ | ||
| 3565 | nread = 0; | ||
| 3566 | } | ||
| 3567 | /* We don't want trailing null characters. */ | ||
| 3568 | for (p = cmdline + nread - 1; p > cmdline && !*p; p--) | ||
| 3569 | nread--; | ||
| 3570 | for (p = cmdline; p < cmdline + nread; p++) | ||
| 3571 | { | ||
| 3572 | /* Escape-quote whitespace and backslashes. */ | ||
| 3573 | if (isspace (*p) || *p == '\\') | ||
| 3574 | { | ||
| 3575 | memmove (p + 1, p, nread - (p - cmdline)); | ||
| 3576 | nread++; | ||
| 3577 | *p++ = '\\'; | ||
| 3578 | } | ||
| 3579 | else if (*p == '\0') | ||
| 3580 | *p = ' '; | ||
| 3581 | } | ||
| 3582 | cmdline_size = nread; | ||
| 3583 | } | ||
| 3584 | if (!cmdline_size) | ||
| 3585 | { | ||
| 3586 | if (!cmd) | ||
| 3587 | cmd = "???"; | ||
| 3588 | if (!cmdsize) | ||
| 3589 | cmdsize = strlen (cmd); | ||
| 3590 | cmdline_size = cmdsize + 2; | ||
| 3591 | cmdline = xmalloc (cmdline_size + 1); | ||
| 3592 | strcpy (cmdline, "["); | ||
| 3593 | strcat (strncat (cmdline, cmd, cmdsize), "]"); | ||
| 3594 | } | ||
| 3595 | emacs_close (fd); | ||
| 3596 | /* Command line is encoded in locale-coding-system; decode it. */ | ||
| 3597 | cmd_str = make_unibyte_string (cmdline, cmdline_size); | ||
| 3598 | decoded_cmd = code_convert_string_norecord (cmd_str, | ||
| 3599 | Vlocale_coding_system, 0); | ||
| 3600 | xfree (cmdline); | ||
| 3601 | attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); | ||
| 3602 | } | ||
| 3603 | |||
| 3604 | UNGCPRO; | ||
| 3605 | return attrs; | ||
| 3606 | } | ||
| 3607 | |||
| 3608 | #elif !defined (WINDOWSNT) | ||
| 3609 | |||
| 3610 | Lisp_Object | ||
| 3611 | system_process_attributes (Lisp_Object pid) | ||
| 3612 | { | ||
| 3613 | return Qnil | ||
| 3614 | } | ||
| 3615 | |||
| 3616 | #endif /* !defined (WINDOWSNT) */ | ||
| 3617 | |||
| 3174 | 3618 | ||
| 3175 | /* arch-tag: edb43589-4e09-4544-b325-978b5b121dcf | 3619 | /* arch-tag: edb43589-4e09-4544-b325-978b5b121dcf |
| 3176 | (do not change this comment) */ | 3620 | (do not change this comment) */ |