diff options
Diffstat (limited to 'src/sysdep.c')
| -rw-r--r-- | src/sysdep.c | 335 |
1 files changed, 182 insertions, 153 deletions
diff --git a/src/sysdep.c b/src/sysdep.c index f614d8bc557..11a6f4a76ce 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -42,9 +42,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 42 | #endif | 42 | #endif |
| 43 | 43 | ||
| 44 | #ifdef __FreeBSD__ | 44 | #ifdef __FreeBSD__ |
| 45 | #include <sys/user.h> | 45 | /* Sparc/ARM machine/frame.h has 'struct frame' which conflicts with Emacs's |
| 46 | #include <sys/resource.h> | 46 | 'struct frame', so rename it. */ |
| 47 | #include <math.h> | 47 | # define frame freebsd_frame |
| 48 | # include <sys/user.h> | ||
| 49 | # undef frame | ||
| 50 | |||
| 51 | # include <sys/resource.h> | ||
| 52 | # include <math.h> | ||
| 48 | #endif | 53 | #endif |
| 49 | 54 | ||
| 50 | #ifdef WINDOWSNT | 55 | #ifdef WINDOWSNT |
| @@ -2201,6 +2206,20 @@ emacs_fopen (char const *file, char const *mode) | |||
| 2201 | return fd < 0 ? 0 : fdopen (fd, mode); | 2206 | return fd < 0 ? 0 : fdopen (fd, mode); |
| 2202 | } | 2207 | } |
| 2203 | 2208 | ||
| 2209 | /* Create a pipe for Emacs use. */ | ||
| 2210 | |||
| 2211 | int | ||
| 2212 | emacs_pipe (int fd[2]) | ||
| 2213 | { | ||
| 2214 | int result = pipe2 (fd, O_CLOEXEC); | ||
| 2215 | if (! O_CLOEXEC && result == 0) | ||
| 2216 | { | ||
| 2217 | fcntl (fd[0], F_SETFD, FD_CLOEXEC); | ||
| 2218 | fcntl (fd[1], F_SETFD, FD_CLOEXEC); | ||
| 2219 | } | ||
| 2220 | return result; | ||
| 2221 | } | ||
| 2222 | |||
| 2204 | /* Approximate posix_close and POSIX_CLOSE_RESTART well enough for Emacs. | 2223 | /* Approximate posix_close and POSIX_CLOSE_RESTART well enough for Emacs. |
| 2205 | For the background behind this mess, please see Austin Group defect 529 | 2224 | For the background behind this mess, please see Austin Group defect 529 |
| 2206 | <http://austingroupbugs.net/view.php?id=529>. */ | 2225 | <http://austingroupbugs.net/view.php?id=529>. */ |
| @@ -2422,14 +2441,11 @@ safe_strsignal (int code) | |||
| 2422 | #ifndef DOS_NT | 2441 | #ifndef DOS_NT |
| 2423 | /* For make-serial-process */ | 2442 | /* For make-serial-process */ |
| 2424 | int | 2443 | int |
| 2425 | serial_open (char *port) | 2444 | serial_open (Lisp_Object port) |
| 2426 | { | 2445 | { |
| 2427 | int fd = emacs_open (port, O_RDWR | O_NOCTTY | O_NONBLOCK, 0); | 2446 | int fd = emacs_open (SSDATA (port), O_RDWR | O_NOCTTY | O_NONBLOCK, 0); |
| 2428 | if (fd < 0) | 2447 | if (fd < 0) |
| 2429 | { | 2448 | report_file_error ("Opening serial port", port); |
| 2430 | error ("Could not open %s: %s", | ||
| 2431 | port, emacs_strerror (errno)); | ||
| 2432 | } | ||
| 2433 | #ifdef TIOCEXCL | 2449 | #ifdef TIOCEXCL |
| 2434 | ioctl (fd, TIOCEXCL, (char *) 0); | 2450 | ioctl (fd, TIOCEXCL, (char *) 0); |
| 2435 | #endif | 2451 | #endif |
| @@ -2477,7 +2493,7 @@ serial_configure (struct Lisp_Process *p, | |||
| 2477 | /* Read port attributes and prepare default configuration. */ | 2493 | /* Read port attributes and prepare default configuration. */ |
| 2478 | err = tcgetattr (p->outfd, &attr); | 2494 | err = tcgetattr (p->outfd, &attr); |
| 2479 | if (err != 0) | 2495 | if (err != 0) |
| 2480 | error ("tcgetattr() failed: %s", emacs_strerror (errno)); | 2496 | report_file_error ("Failed tcgetattr", Qnil); |
| 2481 | cfmakeraw (&attr); | 2497 | cfmakeraw (&attr); |
| 2482 | #if defined (CLOCAL) | 2498 | #if defined (CLOCAL) |
| 2483 | attr.c_cflag |= CLOCAL; | 2499 | attr.c_cflag |= CLOCAL; |
| @@ -2494,8 +2510,7 @@ serial_configure (struct Lisp_Process *p, | |||
| 2494 | CHECK_NUMBER (tem); | 2510 | CHECK_NUMBER (tem); |
| 2495 | err = cfsetspeed (&attr, XINT (tem)); | 2511 | err = cfsetspeed (&attr, XINT (tem)); |
| 2496 | if (err != 0) | 2512 | if (err != 0) |
| 2497 | error ("cfsetspeed(%"pI"d) failed: %s", XINT (tem), | 2513 | report_file_error ("Failed cfsetspeed", tem); |
| 2498 | emacs_strerror (errno)); | ||
| 2499 | childp2 = Fplist_put (childp2, QCspeed, tem); | 2514 | childp2 = Fplist_put (childp2, QCspeed, tem); |
| 2500 | 2515 | ||
| 2501 | /* Configure bytesize. */ | 2516 | /* Configure bytesize. */ |
| @@ -2617,7 +2632,7 @@ serial_configure (struct Lisp_Process *p, | |||
| 2617 | /* Activate configuration. */ | 2632 | /* Activate configuration. */ |
| 2618 | err = tcsetattr (p->outfd, TCSANOW, &attr); | 2633 | err = tcsetattr (p->outfd, TCSANOW, &attr); |
| 2619 | if (err != 0) | 2634 | if (err != 0) |
| 2620 | error ("tcsetattr() failed: %s", emacs_strerror (errno)); | 2635 | report_file_error ("Failed tcsetattr", Qnil); |
| 2621 | 2636 | ||
| 2622 | childp2 = Fplist_put (childp2, QCsummary, build_string (summary)); | 2637 | childp2 = Fplist_put (childp2, QCsummary, build_string (summary)); |
| 2623 | pset_childp (p, childp2); | 2638 | pset_childp (p, childp2); |
| @@ -2797,11 +2812,12 @@ get_up_time (void) | |||
| 2797 | static Lisp_Object | 2812 | static Lisp_Object |
| 2798 | procfs_ttyname (int rdev) | 2813 | procfs_ttyname (int rdev) |
| 2799 | { | 2814 | { |
| 2800 | FILE *fdev = NULL; | 2815 | FILE *fdev; |
| 2801 | char name[PATH_MAX]; | 2816 | char name[PATH_MAX]; |
| 2802 | 2817 | ||
| 2803 | block_input (); | 2818 | block_input (); |
| 2804 | fdev = emacs_fopen ("/proc/tty/drivers", "r"); | 2819 | fdev = emacs_fopen ("/proc/tty/drivers", "r"); |
| 2820 | name[0] = 0; | ||
| 2805 | 2821 | ||
| 2806 | if (fdev) | 2822 | if (fdev) |
| 2807 | { | 2823 | { |
| @@ -2810,7 +2826,7 @@ procfs_ttyname (int rdev) | |||
| 2810 | char minor[25]; /* 2 32-bit numbers + dash */ | 2826 | char minor[25]; /* 2 32-bit numbers + dash */ |
| 2811 | char *endp; | 2827 | char *endp; |
| 2812 | 2828 | ||
| 2813 | while (!feof (fdev) && !ferror (fdev)) | 2829 | for (; !feof (fdev) && !ferror (fdev); name[0] = 0) |
| 2814 | { | 2830 | { |
| 2815 | if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3 | 2831 | if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3 |
| 2816 | && major == MAJOR (rdev)) | 2832 | && major == MAJOR (rdev)) |
| @@ -2839,7 +2855,7 @@ procfs_ttyname (int rdev) | |||
| 2839 | static unsigned long | 2855 | static unsigned long |
| 2840 | procfs_get_total_memory (void) | 2856 | procfs_get_total_memory (void) |
| 2841 | { | 2857 | { |
| 2842 | FILE *fmem = NULL; | 2858 | FILE *fmem; |
| 2843 | unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */ | 2859 | unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */ |
| 2844 | 2860 | ||
| 2845 | block_input (); | 2861 | block_input (); |
| @@ -2882,7 +2898,7 @@ system_process_attributes (Lisp_Object pid) | |||
| 2882 | int cmdsize = sizeof default_cmd - 1; | 2898 | int cmdsize = sizeof default_cmd - 1; |
| 2883 | char *cmdline = NULL; | 2899 | char *cmdline = NULL; |
| 2884 | ptrdiff_t cmdline_size; | 2900 | ptrdiff_t cmdline_size; |
| 2885 | unsigned char c; | 2901 | char c; |
| 2886 | printmax_t proc_id; | 2902 | printmax_t proc_id; |
| 2887 | int ppid, pgrp, sess, tty, tpgid, thcount; | 2903 | int ppid, pgrp, sess, tty, tpgid, thcount; |
| 2888 | uid_t uid; | 2904 | uid_t uid; |
| @@ -2893,7 +2909,8 @@ system_process_attributes (Lisp_Object pid) | |||
| 2893 | EMACS_TIME tnow, tstart, tboot, telapsed, us_time; | 2909 | EMACS_TIME tnow, tstart, tboot, telapsed, us_time; |
| 2894 | double pcpu, pmem; | 2910 | double pcpu, pmem; |
| 2895 | Lisp_Object attrs = Qnil; | 2911 | Lisp_Object attrs = Qnil; |
| 2896 | Lisp_Object cmd_str, decoded_cmd, tem; | 2912 | Lisp_Object cmd_str, decoded_cmd; |
| 2913 | ptrdiff_t count; | ||
| 2897 | struct gcpro gcpro1, gcpro2; | 2914 | struct gcpro gcpro1, gcpro2; |
| 2898 | 2915 | ||
| 2899 | CHECK_NUMBER_OR_FLOAT (pid); | 2916 | CHECK_NUMBER_OR_FLOAT (pid); |
| @@ -2921,11 +2938,19 @@ system_process_attributes (Lisp_Object pid) | |||
| 2921 | if (gr) | 2938 | if (gr) |
| 2922 | attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); | 2939 | attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); |
| 2923 | 2940 | ||
| 2941 | count = SPECPDL_INDEX (); | ||
| 2924 | strcpy (fn, procfn); | 2942 | strcpy (fn, procfn); |
| 2925 | procfn_end = fn + strlen (fn); | 2943 | procfn_end = fn + strlen (fn); |
| 2926 | strcpy (procfn_end, "/stat"); | 2944 | strcpy (procfn_end, "/stat"); |
| 2927 | fd = emacs_open (fn, O_RDONLY, 0); | 2945 | fd = emacs_open (fn, O_RDONLY, 0); |
| 2928 | if (fd >= 0 && (nread = emacs_read (fd, procbuf, sizeof (procbuf) - 1)) > 0) | 2946 | if (fd < 0) |
| 2947 | nread = 0; | ||
| 2948 | else | ||
| 2949 | { | ||
| 2950 | record_unwind_protect_int (close_file_unwind, fd); | ||
| 2951 | nread = emacs_read (fd, procbuf, sizeof procbuf - 1); | ||
| 2952 | } | ||
| 2953 | if (0 < nread) | ||
| 2929 | { | 2954 | { |
| 2930 | procbuf[nread] = '\0'; | 2955 | procbuf[nread] = '\0'; |
| 2931 | p = procbuf; | 2956 | p = procbuf; |
| @@ -2949,39 +2974,32 @@ system_process_attributes (Lisp_Object pid) | |||
| 2949 | Vlocale_coding_system, 0); | 2974 | Vlocale_coding_system, 0); |
| 2950 | attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); | 2975 | attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); |
| 2951 | 2976 | ||
| 2952 | if (q) | 2977 | /* state ppid pgrp sess tty tpgid . minflt cminflt majflt cmajflt |
| 2978 | utime stime cutime cstime priority nice thcount . start vsize rss */ | ||
| 2979 | if (q | ||
| 2980 | && (sscanf (q + 2, ("%c %d %d %d %d %d %*u %lu %lu %lu %lu " | ||
| 2981 | "%Lu %Lu %Lu %Lu %ld %ld %d %*d %Lu %lu %ld"), | ||
| 2982 | &c, &ppid, &pgrp, &sess, &tty, &tpgid, | ||
| 2983 | &minflt, &cminflt, &majflt, &cmajflt, | ||
| 2984 | &u_time, &s_time, &cutime, &cstime, | ||
| 2985 | &priority, &niceness, &thcount, &start, &vsize, &rss) | ||
| 2986 | == 20)) | ||
| 2953 | { | 2987 | { |
| 2954 | EMACS_INT ppid_eint, pgrp_eint, sess_eint, tpgid_eint, thcount_eint; | 2988 | char state_str[2]; |
| 2955 | p = q + 2; | 2989 | state_str[0] = c; |
| 2956 | /* state ppid pgrp sess tty tpgid . minflt cminflt majflt cmajflt utime stime cutime cstime priority nice thcount . start vsize rss */ | 2990 | state_str[1] = '\0'; |
| 2957 | sscanf (p, "%c %d %d %d %d %d %*u %lu %lu %lu %lu %Lu %Lu %Lu %Lu %ld %ld %d %*d %Lu %lu %ld", | 2991 | attrs = Fcons (Fcons (Qstate, build_string (state_str)), attrs); |
| 2958 | &c, &ppid, &pgrp, &sess, &tty, &tpgid, | 2992 | attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (ppid)), attrs); |
| 2959 | &minflt, &cminflt, &majflt, &cmajflt, | 2993 | attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pgrp)), attrs); |
| 2960 | &u_time, &s_time, &cutime, &cstime, | 2994 | attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (sess)), attrs); |
| 2961 | &priority, &niceness, &thcount, &start, &vsize, &rss); | ||
| 2962 | { | ||
| 2963 | char state_str[2]; | ||
| 2964 | |||
| 2965 | state_str[0] = c; | ||
| 2966 | state_str[1] = '\0'; | ||
| 2967 | tem = build_string (state_str); | ||
| 2968 | attrs = Fcons (Fcons (Qstate, tem), attrs); | ||
| 2969 | } | ||
| 2970 | /* Stops GCC whining about limited range of data type. */ | ||
| 2971 | ppid_eint = ppid; | ||
| 2972 | pgrp_eint = pgrp; | ||
| 2973 | sess_eint = sess; | ||
| 2974 | tpgid_eint = tpgid; | ||
| 2975 | thcount_eint = thcount; | ||
| 2976 | attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (ppid_eint)), attrs); | ||
| 2977 | attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pgrp_eint)), attrs); | ||
| 2978 | attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (sess_eint)), attrs); | ||
| 2979 | attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs); | 2995 | attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs); |
| 2980 | attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (tpgid_eint)), attrs); | 2996 | attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (tpgid)), attrs); |
| 2981 | attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (minflt)), attrs); | 2997 | attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (minflt)), attrs); |
| 2982 | attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (majflt)), attrs); | 2998 | attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (majflt)), attrs); |
| 2983 | attrs = Fcons (Fcons (Qcminflt, make_fixnum_or_float (cminflt)), attrs); | 2999 | attrs = Fcons (Fcons (Qcminflt, make_fixnum_or_float (cminflt)), |
| 2984 | attrs = Fcons (Fcons (Qcmajflt, make_fixnum_or_float (cmajflt)), attrs); | 3000 | attrs); |
| 3001 | attrs = Fcons (Fcons (Qcmajflt, make_fixnum_or_float (cmajflt)), | ||
| 3002 | attrs); | ||
| 2985 | clocks_per_sec = sysconf (_SC_CLK_TCK); | 3003 | clocks_per_sec = sysconf (_SC_CLK_TCK); |
| 2986 | if (clocks_per_sec < 0) | 3004 | if (clocks_per_sec < 0) |
| 2987 | clocks_per_sec = 100; | 3005 | clocks_per_sec = 100; |
| @@ -3002,19 +3020,22 @@ system_process_attributes (Lisp_Object pid) | |||
| 3002 | ltime_from_jiffies (cstime, clocks_per_sec)), | 3020 | ltime_from_jiffies (cstime, clocks_per_sec)), |
| 3003 | attrs); | 3021 | attrs); |
| 3004 | attrs = Fcons (Fcons (Qctime, | 3022 | attrs = Fcons (Fcons (Qctime, |
| 3005 | ltime_from_jiffies (cstime+cutime, clocks_per_sec)), | 3023 | ltime_from_jiffies (cstime + cutime, |
| 3024 | clocks_per_sec)), | ||
| 3006 | attrs); | 3025 | attrs); |
| 3007 | attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs); | 3026 | attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs); |
| 3008 | attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs); | 3027 | attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs); |
| 3009 | attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount_eint)), attrs); | 3028 | attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount)), |
| 3029 | attrs); | ||
| 3010 | tnow = current_emacs_time (); | 3030 | tnow = current_emacs_time (); |
| 3011 | telapsed = get_up_time (); | 3031 | telapsed = get_up_time (); |
| 3012 | tboot = sub_emacs_time (tnow, telapsed); | 3032 | tboot = sub_emacs_time (tnow, telapsed); |
| 3013 | tstart = time_from_jiffies (start, clocks_per_sec); | 3033 | tstart = time_from_jiffies (start, clocks_per_sec); |
| 3014 | tstart = add_emacs_time (tboot, tstart); | 3034 | tstart = add_emacs_time (tboot, tstart); |
| 3015 | attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs); | 3035 | attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs); |
| 3016 | attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize/1024)), attrs); | 3036 | attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize / 1024)), |
| 3017 | attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4*rss)), attrs); | 3037 | attrs); |
| 3038 | attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4 * rss)), attrs); | ||
| 3018 | telapsed = sub_emacs_time (tnow, tstart); | 3039 | telapsed = sub_emacs_time (tnow, tstart); |
| 3019 | attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs); | 3040 | attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs); |
| 3020 | us_time = time_from_jiffies (u_time + s_time, clocks_per_sec); | 3041 | us_time = time_from_jiffies (u_time + s_time, clocks_per_sec); |
| @@ -3029,67 +3050,63 @@ system_process_attributes (Lisp_Object pid) | |||
| 3029 | attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs); | 3050 | attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs); |
| 3030 | } | 3051 | } |
| 3031 | } | 3052 | } |
| 3032 | if (fd >= 0) | 3053 | unbind_to (count, Qnil); |
| 3033 | emacs_close (fd); | ||
| 3034 | 3054 | ||
| 3035 | /* args */ | 3055 | /* args */ |
| 3036 | strcpy (procfn_end, "/cmdline"); | 3056 | strcpy (procfn_end, "/cmdline"); |
| 3037 | fd = emacs_open (fn, O_RDONLY, 0); | 3057 | fd = emacs_open (fn, O_RDONLY, 0); |
| 3038 | if (fd >= 0) | 3058 | if (fd >= 0) |
| 3039 | { | 3059 | { |
| 3040 | char ch; | 3060 | ptrdiff_t readsize, nread_incr; |
| 3041 | for (cmdline_size = 0; cmdline_size < STRING_BYTES_BOUND; cmdline_size++) | 3061 | record_unwind_protect_int (close_file_unwind, fd); |
| 3062 | record_unwind_protect_nothing (); | ||
| 3063 | nread = cmdline_size = 0; | ||
| 3064 | |||
| 3065 | do | ||
| 3042 | { | 3066 | { |
| 3043 | if (emacs_read (fd, &ch, 1) != 1) | 3067 | cmdline = xpalloc (cmdline, &cmdline_size, 2, STRING_BYTES_BOUND, 1); |
| 3044 | break; | 3068 | set_unwind_protect_ptr (count + 1, xfree, cmdline); |
| 3045 | c = ch; | 3069 | |
| 3046 | if (c_isspace (c) || c == '\\') | 3070 | /* Leave room even if every byte needs escaping below. */ |
| 3047 | cmdline_size++; /* for later quoting, see below */ | 3071 | readsize = (cmdline_size >> 1) - nread; |
| 3072 | |||
| 3073 | nread_incr = emacs_read (fd, cmdline + nread, readsize); | ||
| 3074 | nread += max (0, nread_incr); | ||
| 3048 | } | 3075 | } |
| 3049 | if (cmdline_size) | 3076 | while (nread_incr == readsize); |
| 3077 | |||
| 3078 | if (nread) | ||
| 3050 | { | 3079 | { |
| 3051 | cmdline = xmalloc (cmdline_size + 1); | ||
| 3052 | lseek (fd, 0L, SEEK_SET); | ||
| 3053 | cmdline[0] = '\0'; | ||
| 3054 | if ((nread = read (fd, cmdline, cmdline_size)) >= 0) | ||
| 3055 | cmdline[nread++] = '\0'; | ||
| 3056 | else | ||
| 3057 | { | ||
| 3058 | /* Assigning zero to `nread' makes us skip the following | ||
| 3059 | two loops, assign zero to cmdline_size, and enter the | ||
| 3060 | following `if' clause that handles unknown command | ||
| 3061 | lines. */ | ||
| 3062 | nread = 0; | ||
| 3063 | } | ||
| 3064 | /* We don't want trailing null characters. */ | 3080 | /* We don't want trailing null characters. */ |
| 3065 | for (p = cmdline + nread; p > cmdline + 1 && !p[-1]; p--) | 3081 | for (p = cmdline + nread; cmdline < p && !p[-1]; p--) |
| 3066 | nread--; | 3082 | continue; |
| 3067 | for (p = cmdline; p < cmdline + nread; p++) | 3083 | |
| 3084 | /* Escape-quote whitespace and backslashes. */ | ||
| 3085 | q = cmdline + cmdline_size; | ||
| 3086 | while (cmdline < p) | ||
| 3068 | { | 3087 | { |
| 3069 | /* Escape-quote whitespace and backslashes. */ | 3088 | char c = *--p; |
| 3070 | if (c_isspace (*p) || *p == '\\') | 3089 | *--q = c ? c : ' '; |
| 3071 | { | 3090 | if (c_isspace (c) || c == '\\') |
| 3072 | memmove (p + 1, p, nread - (p - cmdline)); | 3091 | *--q = '\\'; |
| 3073 | nread++; | ||
| 3074 | *p++ = '\\'; | ||
| 3075 | } | ||
| 3076 | else if (*p == '\0') | ||
| 3077 | *p = ' '; | ||
| 3078 | } | 3092 | } |
| 3079 | cmdline_size = nread; | 3093 | |
| 3094 | nread = cmdline + cmdline_size - q; | ||
| 3080 | } | 3095 | } |
| 3081 | if (!cmdline_size) | 3096 | |
| 3097 | if (!nread) | ||
| 3082 | { | 3098 | { |
| 3083 | cmdline_size = cmdsize + 2; | 3099 | nread = cmdsize + 2; |
| 3084 | cmdline = xmalloc (cmdline_size + 1); | 3100 | cmdline_size = nread + 1; |
| 3101 | q = cmdline = xrealloc (cmdline, cmdline_size); | ||
| 3102 | set_unwind_protect_ptr (count + 1, xfree, cmdline); | ||
| 3085 | sprintf (cmdline, "[%.*s]", cmdsize, cmd); | 3103 | sprintf (cmdline, "[%.*s]", cmdsize, cmd); |
| 3086 | } | 3104 | } |
| 3087 | emacs_close (fd); | ||
| 3088 | /* Command line is encoded in locale-coding-system; decode it. */ | 3105 | /* Command line is encoded in locale-coding-system; decode it. */ |
| 3089 | cmd_str = make_unibyte_string (cmdline, cmdline_size); | 3106 | cmd_str = make_unibyte_string (q, nread); |
| 3090 | decoded_cmd = code_convert_string_norecord (cmd_str, | 3107 | decoded_cmd = code_convert_string_norecord (cmd_str, |
| 3091 | Vlocale_coding_system, 0); | 3108 | Vlocale_coding_system, 0); |
| 3092 | xfree (cmdline); | 3109 | unbind_to (count, Qnil); |
| 3093 | attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); | 3110 | attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); |
| 3094 | } | 3111 | } |
| 3095 | 3112 | ||
| @@ -3131,8 +3148,9 @@ system_process_attributes (Lisp_Object pid) | |||
| 3131 | uid_t uid; | 3148 | uid_t uid; |
| 3132 | gid_t gid; | 3149 | gid_t gid; |
| 3133 | Lisp_Object attrs = Qnil; | 3150 | Lisp_Object attrs = Qnil; |
| 3134 | Lisp_Object decoded_cmd, tem; | 3151 | Lisp_Object decoded_cmd; |
| 3135 | struct gcpro gcpro1, gcpro2; | 3152 | struct gcpro gcpro1, gcpro2; |
| 3153 | ptrdiff_t count; | ||
| 3136 | 3154 | ||
| 3137 | CHECK_NUMBER_OR_FLOAT (pid); | 3155 | CHECK_NUMBER_OR_FLOAT (pid); |
| 3138 | CONS_TO_INTEGER (pid, pid_t, proc_id); | 3156 | CONS_TO_INTEGER (pid, pid_t, proc_id); |
| @@ -3159,72 +3177,83 @@ system_process_attributes (Lisp_Object pid) | |||
| 3159 | if (gr) | 3177 | if (gr) |
| 3160 | attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); | 3178 | attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); |
| 3161 | 3179 | ||
| 3180 | count = SPECPDL_INDEX (); | ||
| 3162 | strcpy (fn, procfn); | 3181 | strcpy (fn, procfn); |
| 3163 | procfn_end = fn + strlen (fn); | 3182 | procfn_end = fn + strlen (fn); |
| 3164 | strcpy (procfn_end, "/psinfo"); | 3183 | strcpy (procfn_end, "/psinfo"); |
| 3165 | fd = emacs_open (fn, O_RDONLY, 0); | 3184 | fd = emacs_open (fn, O_RDONLY, 0); |
| 3166 | if (fd >= 0 | 3185 | if (fd < 0) |
| 3167 | && (nread = read (fd, (char*)&pinfo, sizeof (struct psinfo)) > 0)) | 3186 | nread = 0; |
| 3187 | else | ||
| 3168 | { | 3188 | { |
| 3169 | attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (pinfo.pr_ppid)), attrs); | 3189 | record_unwind_protect (close_file_unwind, fd); |
| 3170 | attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pinfo.pr_pgid)), attrs); | 3190 | nread = emacs_read (fd, &pinfo, sizeof pinfo); |
| 3171 | attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (pinfo.pr_sid)), attrs); | ||
| 3172 | |||
| 3173 | { | ||
| 3174 | char state_str[2]; | ||
| 3175 | state_str[0] = pinfo.pr_lwp.pr_sname; | ||
| 3176 | state_str[1] = '\0'; | ||
| 3177 | tem = build_string (state_str); | ||
| 3178 | attrs = Fcons (Fcons (Qstate, tem), attrs); | ||
| 3179 | } | ||
| 3180 | |||
| 3181 | /* FIXME: missing Qttyname. psinfo.pr_ttydev is a dev_t, | ||
| 3182 | need to get a string from it. */ | ||
| 3183 | |||
| 3184 | /* FIXME: missing: Qtpgid */ | ||
| 3185 | |||
| 3186 | /* FIXME: missing: | ||
| 3187 | Qminflt | ||
| 3188 | Qmajflt | ||
| 3189 | Qcminflt | ||
| 3190 | Qcmajflt | ||
| 3191 | |||
| 3192 | Qutime | ||
| 3193 | Qcutime | ||
| 3194 | Qstime | ||
| 3195 | Qcstime | ||
| 3196 | Are they available? */ | ||
| 3197 | |||
| 3198 | attrs = Fcons (Fcons (Qtime, make_lisp_time (pinfo.pr_time)), attrs); | ||
| 3199 | attrs = Fcons (Fcons (Qctime, make_lisp_time (pinfo.pr_ctime)), attrs); | ||
| 3200 | attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs); | ||
| 3201 | attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs); | ||
| 3202 | attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)), attrs); | ||
| 3203 | |||
| 3204 | attrs = Fcons (Fcons (Qstart, make_lisp_time (pinfo.pr_start)), attrs); | ||
| 3205 | attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)), attrs); | ||
| 3206 | attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)), attrs); | ||
| 3207 | |||
| 3208 | /* pr_pctcpu and pr_pctmem are unsigned integers in the | ||
| 3209 | range 0 .. 2**15, representing 0.0 .. 1.0. */ | ||
| 3210 | attrs = Fcons (Fcons (Qpcpu, make_float (100.0 / 0x8000 * pinfo.pr_pctcpu)), attrs); | ||
| 3211 | attrs = Fcons (Fcons (Qpmem, make_float (100.0 / 0x8000 * pinfo.pr_pctmem)), attrs); | ||
| 3212 | |||
| 3213 | decoded_cmd | ||
| 3214 | = code_convert_string_norecord (make_unibyte_string (pinfo.pr_fname, | ||
| 3215 | strlen (pinfo.pr_fname)), | ||
| 3216 | Vlocale_coding_system, 0); | ||
| 3217 | attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); | ||
| 3218 | decoded_cmd | ||
| 3219 | = code_convert_string_norecord (make_unibyte_string (pinfo.pr_psargs, | ||
| 3220 | strlen (pinfo.pr_psargs)), | ||
| 3221 | Vlocale_coding_system, 0); | ||
| 3222 | attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); | ||
| 3223 | } | 3191 | } |
| 3224 | 3192 | ||
| 3225 | if (fd >= 0) | 3193 | if (nread == sizeof pinfo) |
| 3226 | emacs_close (fd); | 3194 | { |
| 3195 | attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (pinfo.pr_ppid)), attrs); | ||
| 3196 | attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pinfo.pr_pgid)), attrs); | ||
| 3197 | attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (pinfo.pr_sid)), attrs); | ||
| 3227 | 3198 | ||
| 3199 | { | ||
| 3200 | char state_str[2]; | ||
| 3201 | state_str[0] = pinfo.pr_lwp.pr_sname; | ||
| 3202 | state_str[1] = '\0'; | ||
| 3203 | attrs = Fcons (Fcons (Qstate, build_string (state_str)), attrs); | ||
| 3204 | } | ||
| 3205 | |||
| 3206 | /* FIXME: missing Qttyname. psinfo.pr_ttydev is a dev_t, | ||
| 3207 | need to get a string from it. */ | ||
| 3208 | |||
| 3209 | /* FIXME: missing: Qtpgid */ | ||
| 3210 | |||
| 3211 | /* FIXME: missing: | ||
| 3212 | Qminflt | ||
| 3213 | Qmajflt | ||
| 3214 | Qcminflt | ||
| 3215 | Qcmajflt | ||
| 3216 | |||
| 3217 | Qutime | ||
| 3218 | Qcutime | ||
| 3219 | Qstime | ||
| 3220 | Qcstime | ||
| 3221 | Are they available? */ | ||
| 3222 | |||
| 3223 | attrs = Fcons (Fcons (Qtime, make_lisp_time (pinfo.pr_time)), attrs); | ||
| 3224 | attrs = Fcons (Fcons (Qctime, make_lisp_time (pinfo.pr_ctime)), attrs); | ||
| 3225 | attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs); | ||
| 3226 | attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs); | ||
| 3227 | attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)), | ||
| 3228 | attrs); | ||
| 3229 | |||
| 3230 | attrs = Fcons (Fcons (Qstart, make_lisp_time (pinfo.pr_start)), attrs); | ||
| 3231 | attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)), | ||
| 3232 | attrs); | ||
| 3233 | attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)), | ||
| 3234 | attrs); | ||
| 3235 | |||
| 3236 | /* pr_pctcpu and pr_pctmem are unsigned integers in the | ||
| 3237 | range 0 .. 2**15, representing 0.0 .. 1.0. */ | ||
| 3238 | attrs = Fcons (Fcons (Qpcpu, | ||
| 3239 | make_float (100.0 / 0x8000 * pinfo.pr_pctcpu)), | ||
| 3240 | attrs); | ||
| 3241 | attrs = Fcons (Fcons (Qpmem, | ||
| 3242 | make_float (100.0 / 0x8000 * pinfo.pr_pctmem)), | ||
| 3243 | attrs); | ||
| 3244 | |||
| 3245 | decoded_cmd = (code_convert_string_norecord | ||
| 3246 | (make_unibyte_string (pinfo.pr_fname, | ||
| 3247 | strlen (pinfo.pr_fname)), | ||
| 3248 | Vlocale_coding_system, 0)); | ||
| 3249 | attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); | ||
| 3250 | decoded_cmd = (code_convert_string_norecord | ||
| 3251 | (make_unibyte_string (pinfo.pr_psargs, | ||
| 3252 | strlen (pinfo.pr_psargs)), | ||
| 3253 | Vlocale_coding_system, 0)); | ||
| 3254 | attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); | ||
| 3255 | } | ||
| 3256 | unbind_to (count, Qnil); | ||
| 3228 | UNGCPRO; | 3257 | UNGCPRO; |
| 3229 | return attrs; | 3258 | return attrs; |
| 3230 | } | 3259 | } |