diff options
| author | Paul Eggert | 2013-07-18 22:36:50 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-07-18 22:36:50 -0700 |
| commit | ab9980cd3ba7e1cefe846610dccdc86923dcdb86 (patch) | |
| tree | db46d81037a960b07d1963cfd9166b8358b0c77d | |
| parent | 1396ac86dea5fccab800e4b25fdb5319381891eb (diff) | |
| download | emacs-ab9980cd3ba7e1cefe846610dccdc86923dcdb86.tar.gz emacs-ab9980cd3ba7e1cefe846610dccdc86923dcdb86.zip | |
* sysdep.c [GNU_LINUX]: Fix fd and memory leaks and similar issues.
(procfs_ttyname): Don't use uninitialized storage if emacs_fopen
or fscanf fails.
(system_process_attributes): Prefer plain char to unsigned char
when either will do. Clean up properly if interrupted or if
memory allocations fail. Don't assume sscanf succeeds. Remove
no-longer-needed workaround to stop GCC from whining. Read
command-line once, instead of multiple times. Check read status a
bit more carefully.
| -rw-r--r-- | src/ChangeLog | 10 | ||||
| -rw-r--r-- | src/sysdep.c | 294 |
2 files changed, 164 insertions, 140 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 73fc64f37c5..b0c486ab8b2 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,15 @@ | |||
| 1 | 2013-07-19 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2013-07-19 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | * sysdep.c [GNU_LINUX]: Fix fd and memory leaks and similar issues. | ||
| 4 | (procfs_ttyname): Don't use uninitialized storage if emacs_fopen | ||
| 5 | or fscanf fails. | ||
| 6 | (system_process_attributes): Prefer plain char to unsigned char | ||
| 7 | when either will do. Clean up properly if interrupted or if | ||
| 8 | memory allocations fail. Don't assume sscanf succeeds. Remove | ||
| 9 | no-longer-needed workaround to stop GCC from whining. Read | ||
| 10 | command-line once, instead of multiple times. Check read status a | ||
| 11 | bit more carefully. | ||
| 12 | |||
| 3 | Fix obscure porting bug with varargs functions. | 13 | Fix obscure porting bug with varargs functions. |
| 4 | The code assumed that int is treated like ptrdiff_t in a vararg | 14 | The code assumed that int is treated like ptrdiff_t in a vararg |
| 5 | function, which is not a portable assumption. There was a similar | 15 | function, which is not a portable assumption. There was a similar |
diff --git a/src/sysdep.c b/src/sysdep.c index 465d271abca..2739583456a 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -2807,11 +2807,12 @@ get_up_time (void) | |||
| 2807 | static Lisp_Object | 2807 | static Lisp_Object |
| 2808 | procfs_ttyname (int rdev) | 2808 | procfs_ttyname (int rdev) |
| 2809 | { | 2809 | { |
| 2810 | FILE *fdev = NULL; | 2810 | FILE *fdev; |
| 2811 | char name[PATH_MAX]; | 2811 | char name[PATH_MAX]; |
| 2812 | 2812 | ||
| 2813 | block_input (); | 2813 | block_input (); |
| 2814 | fdev = emacs_fopen ("/proc/tty/drivers", "r"); | 2814 | fdev = emacs_fopen ("/proc/tty/drivers", "r"); |
| 2815 | name[0] = 0; | ||
| 2815 | 2816 | ||
| 2816 | if (fdev) | 2817 | if (fdev) |
| 2817 | { | 2818 | { |
| @@ -2820,7 +2821,7 @@ procfs_ttyname (int rdev) | |||
| 2820 | char minor[25]; /* 2 32-bit numbers + dash */ | 2821 | char minor[25]; /* 2 32-bit numbers + dash */ |
| 2821 | char *endp; | 2822 | char *endp; |
| 2822 | 2823 | ||
| 2823 | while (!feof (fdev) && !ferror (fdev)) | 2824 | for (; !feof (fdev) && !ferror (fdev); name[0] = 0) |
| 2824 | { | 2825 | { |
| 2825 | if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3 | 2826 | if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3 |
| 2826 | && major == MAJOR (rdev)) | 2827 | && major == MAJOR (rdev)) |
| @@ -2849,7 +2850,7 @@ procfs_ttyname (int rdev) | |||
| 2849 | static unsigned long | 2850 | static unsigned long |
| 2850 | procfs_get_total_memory (void) | 2851 | procfs_get_total_memory (void) |
| 2851 | { | 2852 | { |
| 2852 | FILE *fmem = NULL; | 2853 | FILE *fmem; |
| 2853 | unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */ | 2854 | unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */ |
| 2854 | 2855 | ||
| 2855 | block_input (); | 2856 | block_input (); |
| @@ -2892,7 +2893,7 @@ system_process_attributes (Lisp_Object pid) | |||
| 2892 | int cmdsize = sizeof default_cmd - 1; | 2893 | int cmdsize = sizeof default_cmd - 1; |
| 2893 | char *cmdline = NULL; | 2894 | char *cmdline = NULL; |
| 2894 | ptrdiff_t cmdline_size; | 2895 | ptrdiff_t cmdline_size; |
| 2895 | unsigned char c; | 2896 | char c; |
| 2896 | printmax_t proc_id; | 2897 | printmax_t proc_id; |
| 2897 | int ppid, pgrp, sess, tty, tpgid, thcount; | 2898 | int ppid, pgrp, sess, tty, tpgid, thcount; |
| 2898 | uid_t uid; | 2899 | uid_t uid; |
| @@ -2903,7 +2904,8 @@ system_process_attributes (Lisp_Object pid) | |||
| 2903 | EMACS_TIME tnow, tstart, tboot, telapsed, us_time; | 2904 | EMACS_TIME tnow, tstart, tboot, telapsed, us_time; |
| 2904 | double pcpu, pmem; | 2905 | double pcpu, pmem; |
| 2905 | Lisp_Object attrs = Qnil; | 2906 | Lisp_Object attrs = Qnil; |
| 2906 | Lisp_Object cmd_str, decoded_cmd, tem; | 2907 | Lisp_Object cmd_str, decoded_cmd; |
| 2908 | ptrdiff_t count; | ||
| 2907 | struct gcpro gcpro1, gcpro2; | 2909 | struct gcpro gcpro1, gcpro2; |
| 2908 | 2910 | ||
| 2909 | CHECK_NUMBER_OR_FLOAT (pid); | 2911 | CHECK_NUMBER_OR_FLOAT (pid); |
| @@ -2931,11 +2933,19 @@ system_process_attributes (Lisp_Object pid) | |||
| 2931 | if (gr) | 2933 | if (gr) |
| 2932 | attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); | 2934 | attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); |
| 2933 | 2935 | ||
| 2936 | count = SPECPDL_INDEX (); | ||
| 2934 | strcpy (fn, procfn); | 2937 | strcpy (fn, procfn); |
| 2935 | procfn_end = fn + strlen (fn); | 2938 | procfn_end = fn + strlen (fn); |
| 2936 | strcpy (procfn_end, "/stat"); | 2939 | strcpy (procfn_end, "/stat"); |
| 2937 | fd = emacs_open (fn, O_RDONLY, 0); | 2940 | fd = emacs_open (fn, O_RDONLY, 0); |
| 2938 | if (fd >= 0 && (nread = emacs_read (fd, procbuf, sizeof (procbuf) - 1)) > 0) | 2941 | if (fd < 0) |
| 2942 | nread = 0; | ||
| 2943 | else | ||
| 2944 | { | ||
| 2945 | record_unwind_protect_int (close_file_unwind, fd); | ||
| 2946 | nread = emacs_read (fd, procbuf, sizeof procbuf - 1); | ||
| 2947 | } | ||
| 2948 | if (0 < nread) | ||
| 2939 | { | 2949 | { |
| 2940 | procbuf[nread] = '\0'; | 2950 | procbuf[nread] = '\0'; |
| 2941 | p = procbuf; | 2951 | p = procbuf; |
| @@ -2959,39 +2969,32 @@ system_process_attributes (Lisp_Object pid) | |||
| 2959 | Vlocale_coding_system, 0); | 2969 | Vlocale_coding_system, 0); |
| 2960 | attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); | 2970 | attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); |
| 2961 | 2971 | ||
| 2962 | if (q) | 2972 | /* state ppid pgrp sess tty tpgid . minflt cminflt majflt cmajflt |
| 2973 | utime stime cutime cstime priority nice thcount . start vsize rss */ | ||
| 2974 | if (q | ||
| 2975 | && (sscanf (q + 2, ("%c %d %d %d %d %d %*u %lu %lu %lu %lu " | ||
| 2976 | "%Lu %Lu %Lu %Lu %ld %ld %d %*d %Lu %lu %ld"), | ||
| 2977 | &c, &ppid, &pgrp, &sess, &tty, &tpgid, | ||
| 2978 | &minflt, &cminflt, &majflt, &cmajflt, | ||
| 2979 | &u_time, &s_time, &cutime, &cstime, | ||
| 2980 | &priority, &niceness, &thcount, &start, &vsize, &rss) | ||
| 2981 | == 20)) | ||
| 2963 | { | 2982 | { |
| 2964 | EMACS_INT ppid_eint, pgrp_eint, sess_eint, tpgid_eint, thcount_eint; | 2983 | char state_str[2]; |
| 2965 | p = q + 2; | 2984 | state_str[0] = c; |
| 2966 | /* state ppid pgrp sess tty tpgid . minflt cminflt majflt cmajflt utime stime cutime cstime priority nice thcount . start vsize rss */ | 2985 | state_str[1] = '\0'; |
| 2967 | sscanf (p, "%c %d %d %d %d %d %*u %lu %lu %lu %lu %Lu %Lu %Lu %Lu %ld %ld %d %*d %Lu %lu %ld", | 2986 | attrs = Fcons (Fcons (Qstate, build_string (state_str)), attrs); |
| 2968 | &c, &ppid, &pgrp, &sess, &tty, &tpgid, | 2987 | attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (ppid)), attrs); |
| 2969 | &minflt, &cminflt, &majflt, &cmajflt, | 2988 | attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pgrp)), attrs); |
| 2970 | &u_time, &s_time, &cutime, &cstime, | 2989 | attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (sess)), attrs); |
| 2971 | &priority, &niceness, &thcount, &start, &vsize, &rss); | ||
| 2972 | { | ||
| 2973 | char state_str[2]; | ||
| 2974 | |||
| 2975 | state_str[0] = c; | ||
| 2976 | state_str[1] = '\0'; | ||
| 2977 | tem = build_string (state_str); | ||
| 2978 | attrs = Fcons (Fcons (Qstate, tem), attrs); | ||
| 2979 | } | ||
| 2980 | /* Stops GCC whining about limited range of data type. */ | ||
| 2981 | ppid_eint = ppid; | ||
| 2982 | pgrp_eint = pgrp; | ||
| 2983 | sess_eint = sess; | ||
| 2984 | tpgid_eint = tpgid; | ||
| 2985 | thcount_eint = thcount; | ||
| 2986 | attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (ppid_eint)), attrs); | ||
| 2987 | attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pgrp_eint)), attrs); | ||
| 2988 | attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (sess_eint)), attrs); | ||
| 2989 | attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs); | 2990 | attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs); |
| 2990 | attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (tpgid_eint)), attrs); | 2991 | attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (tpgid)), attrs); |
| 2991 | attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (minflt)), attrs); | 2992 | attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (minflt)), attrs); |
| 2992 | attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (majflt)), attrs); | 2993 | attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (majflt)), attrs); |
| 2993 | attrs = Fcons (Fcons (Qcminflt, make_fixnum_or_float (cminflt)), attrs); | 2994 | attrs = Fcons (Fcons (Qcminflt, make_fixnum_or_float (cminflt)), |
| 2994 | attrs = Fcons (Fcons (Qcmajflt, make_fixnum_or_float (cmajflt)), attrs); | 2995 | attrs); |
| 2996 | attrs = Fcons (Fcons (Qcmajflt, make_fixnum_or_float (cmajflt)), | ||
| 2997 | attrs); | ||
| 2995 | clocks_per_sec = sysconf (_SC_CLK_TCK); | 2998 | clocks_per_sec = sysconf (_SC_CLK_TCK); |
| 2996 | if (clocks_per_sec < 0) | 2999 | if (clocks_per_sec < 0) |
| 2997 | clocks_per_sec = 100; | 3000 | clocks_per_sec = 100; |
| @@ -3012,19 +3015,22 @@ system_process_attributes (Lisp_Object pid) | |||
| 3012 | ltime_from_jiffies (cstime, clocks_per_sec)), | 3015 | ltime_from_jiffies (cstime, clocks_per_sec)), |
| 3013 | attrs); | 3016 | attrs); |
| 3014 | attrs = Fcons (Fcons (Qctime, | 3017 | attrs = Fcons (Fcons (Qctime, |
| 3015 | ltime_from_jiffies (cstime+cutime, clocks_per_sec)), | 3018 | ltime_from_jiffies (cstime + cutime, |
| 3019 | clocks_per_sec)), | ||
| 3016 | attrs); | 3020 | attrs); |
| 3017 | attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs); | 3021 | attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs); |
| 3018 | attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs); | 3022 | attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs); |
| 3019 | attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount_eint)), attrs); | 3023 | attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount)), |
| 3024 | attrs); | ||
| 3020 | tnow = current_emacs_time (); | 3025 | tnow = current_emacs_time (); |
| 3021 | telapsed = get_up_time (); | 3026 | telapsed = get_up_time (); |
| 3022 | tboot = sub_emacs_time (tnow, telapsed); | 3027 | tboot = sub_emacs_time (tnow, telapsed); |
| 3023 | tstart = time_from_jiffies (start, clocks_per_sec); | 3028 | tstart = time_from_jiffies (start, clocks_per_sec); |
| 3024 | tstart = add_emacs_time (tboot, tstart); | 3029 | tstart = add_emacs_time (tboot, tstart); |
| 3025 | attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs); | 3030 | attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs); |
| 3026 | attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize/1024)), attrs); | 3031 | attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize / 1024)), |
| 3027 | attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4*rss)), attrs); | 3032 | attrs); |
| 3033 | attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4 * rss)), attrs); | ||
| 3028 | telapsed = sub_emacs_time (tnow, tstart); | 3034 | telapsed = sub_emacs_time (tnow, tstart); |
| 3029 | attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs); | 3035 | attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs); |
| 3030 | us_time = time_from_jiffies (u_time + s_time, clocks_per_sec); | 3036 | us_time = time_from_jiffies (u_time + s_time, clocks_per_sec); |
| @@ -3039,67 +3045,63 @@ system_process_attributes (Lisp_Object pid) | |||
| 3039 | attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs); | 3045 | attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs); |
| 3040 | } | 3046 | } |
| 3041 | } | 3047 | } |
| 3042 | if (fd >= 0) | 3048 | unbind_to (count, Qnil); |
| 3043 | emacs_close (fd); | ||
| 3044 | 3049 | ||
| 3045 | /* args */ | 3050 | /* args */ |
| 3046 | strcpy (procfn_end, "/cmdline"); | 3051 | strcpy (procfn_end, "/cmdline"); |
| 3047 | fd = emacs_open (fn, O_RDONLY, 0); | 3052 | fd = emacs_open (fn, O_RDONLY, 0); |
| 3048 | if (fd >= 0) | 3053 | if (fd >= 0) |
| 3049 | { | 3054 | { |
| 3050 | char ch; | 3055 | ptrdiff_t readsize, nread_incr; |
| 3051 | for (cmdline_size = 0; cmdline_size < STRING_BYTES_BOUND; cmdline_size++) | 3056 | record_unwind_protect_int (close_file_unwind, fd); |
| 3057 | record_unwind_protect_nothing (); | ||
| 3058 | nread = cmdline_size = 0; | ||
| 3059 | |||
| 3060 | do | ||
| 3052 | { | 3061 | { |
| 3053 | if (emacs_read (fd, &ch, 1) != 1) | 3062 | cmdline = xpalloc (cmdline, &cmdline_size, 2, STRING_BYTES_BOUND, 1); |
| 3054 | break; | 3063 | set_unwind_protect_ptr (count + 1, xfree, cmdline); |
| 3055 | c = ch; | 3064 | |
| 3056 | if (c_isspace (c) || c == '\\') | 3065 | /* Leave room even if every byte needs escaping below. */ |
| 3057 | cmdline_size++; /* for later quoting, see below */ | 3066 | readsize = (cmdline_size >> 1) - nread; |
| 3067 | |||
| 3068 | nread_incr = emacs_read (fd, cmdline + nread, readsize); | ||
| 3069 | nread += max (0, nread_incr); | ||
| 3058 | } | 3070 | } |
| 3059 | if (cmdline_size) | 3071 | while (nread_incr == readsize); |
| 3072 | |||
| 3073 | if (nread) | ||
| 3060 | { | 3074 | { |
| 3061 | cmdline = xmalloc (cmdline_size + 1); | ||
| 3062 | lseek (fd, 0L, SEEK_SET); | ||
| 3063 | cmdline[0] = '\0'; | ||
| 3064 | if ((nread = read (fd, cmdline, cmdline_size)) >= 0) | ||
| 3065 | cmdline[nread++] = '\0'; | ||
| 3066 | else | ||
| 3067 | { | ||
| 3068 | /* Assigning zero to `nread' makes us skip the following | ||
| 3069 | two loops, assign zero to cmdline_size, and enter the | ||
| 3070 | following `if' clause that handles unknown command | ||
| 3071 | lines. */ | ||
| 3072 | nread = 0; | ||
| 3073 | } | ||
| 3074 | /* We don't want trailing null characters. */ | 3075 | /* We don't want trailing null characters. */ |
| 3075 | for (p = cmdline + nread; p > cmdline + 1 && !p[-1]; p--) | 3076 | for (p = cmdline + nread; cmdline < p && !p[-1]; p--) |
| 3076 | nread--; | 3077 | continue; |
| 3077 | for (p = cmdline; p < cmdline + nread; p++) | 3078 | |
| 3079 | /* Escape-quote whitespace and backslashes. */ | ||
| 3080 | q = cmdline + cmdline_size; | ||
| 3081 | while (cmdline < p) | ||
| 3078 | { | 3082 | { |
| 3079 | /* Escape-quote whitespace and backslashes. */ | 3083 | char c = *--p; |
| 3080 | if (c_isspace (*p) || *p == '\\') | 3084 | *--q = c ? c : ' '; |
| 3081 | { | 3085 | if (c_isspace (c) || c == '\\') |
| 3082 | memmove (p + 1, p, nread - (p - cmdline)); | 3086 | *--q = '\\'; |
| 3083 | nread++; | ||
| 3084 | *p++ = '\\'; | ||
| 3085 | } | ||
| 3086 | else if (*p == '\0') | ||
| 3087 | *p = ' '; | ||
| 3088 | } | 3087 | } |
| 3089 | cmdline_size = nread; | 3088 | |
| 3089 | nread = cmdline + cmdline_size - q; | ||
| 3090 | } | 3090 | } |
| 3091 | if (!cmdline_size) | 3091 | |
| 3092 | if (!nread) | ||
| 3092 | { | 3093 | { |
| 3093 | cmdline_size = cmdsize + 2; | 3094 | nread = cmdsize + 2; |
| 3094 | cmdline = xmalloc (cmdline_size + 1); | 3095 | cmdline_size = nread + 1; |
| 3096 | q = cmdline = xrealloc (cmdline, cmdline_size); | ||
| 3097 | set_unwind_protect_ptr (count + 1, xfree, cmdline); | ||
| 3095 | sprintf (cmdline, "[%.*s]", cmdsize, cmd); | 3098 | sprintf (cmdline, "[%.*s]", cmdsize, cmd); |
| 3096 | } | 3099 | } |
| 3097 | emacs_close (fd); | ||
| 3098 | /* Command line is encoded in locale-coding-system; decode it. */ | 3100 | /* Command line is encoded in locale-coding-system; decode it. */ |
| 3099 | cmd_str = make_unibyte_string (cmdline, cmdline_size); | 3101 | cmd_str = make_unibyte_string (q, nread); |
| 3100 | decoded_cmd = code_convert_string_norecord (cmd_str, | 3102 | decoded_cmd = code_convert_string_norecord (cmd_str, |
| 3101 | Vlocale_coding_system, 0); | 3103 | Vlocale_coding_system, 0); |
| 3102 | xfree (cmdline); | 3104 | unbind_to (count, Qnil); |
| 3103 | attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); | 3105 | attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); |
| 3104 | } | 3106 | } |
| 3105 | 3107 | ||
| @@ -3141,8 +3143,9 @@ system_process_attributes (Lisp_Object pid) | |||
| 3141 | uid_t uid; | 3143 | uid_t uid; |
| 3142 | gid_t gid; | 3144 | gid_t gid; |
| 3143 | Lisp_Object attrs = Qnil; | 3145 | Lisp_Object attrs = Qnil; |
| 3144 | Lisp_Object decoded_cmd, tem; | 3146 | Lisp_Object decoded_cmd; |
| 3145 | struct gcpro gcpro1, gcpro2; | 3147 | struct gcpro gcpro1, gcpro2; |
| 3148 | ptrdiff_t count; | ||
| 3146 | 3149 | ||
| 3147 | CHECK_NUMBER_OR_FLOAT (pid); | 3150 | CHECK_NUMBER_OR_FLOAT (pid); |
| 3148 | CONS_TO_INTEGER (pid, pid_t, proc_id); | 3151 | CONS_TO_INTEGER (pid, pid_t, proc_id); |
| @@ -3169,72 +3172,83 @@ system_process_attributes (Lisp_Object pid) | |||
| 3169 | if (gr) | 3172 | if (gr) |
| 3170 | attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); | 3173 | attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); |
| 3171 | 3174 | ||
| 3175 | count = SPECPDL_INDEX (); | ||
| 3172 | strcpy (fn, procfn); | 3176 | strcpy (fn, procfn); |
| 3173 | procfn_end = fn + strlen (fn); | 3177 | procfn_end = fn + strlen (fn); |
| 3174 | strcpy (procfn_end, "/psinfo"); | 3178 | strcpy (procfn_end, "/psinfo"); |
| 3175 | fd = emacs_open (fn, O_RDONLY, 0); | 3179 | fd = emacs_open (fn, O_RDONLY, 0); |
| 3176 | if (fd >= 0 | 3180 | if (fd < 0) |
| 3177 | && (nread = read (fd, (char*)&pinfo, sizeof (struct psinfo)) > 0)) | 3181 | nread = 0; |
| 3182 | else | ||
| 3178 | { | 3183 | { |
| 3179 | attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (pinfo.pr_ppid)), attrs); | 3184 | record_unwind_protect (close_file_unwind, fd); |
| 3180 | attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pinfo.pr_pgid)), attrs); | 3185 | nread = emacs_read (fd, &pinfo, sizeof pinfo); |
| 3181 | attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (pinfo.pr_sid)), attrs); | ||
| 3182 | |||
| 3183 | { | ||
| 3184 | char state_str[2]; | ||
| 3185 | state_str[0] = pinfo.pr_lwp.pr_sname; | ||
| 3186 | state_str[1] = '\0'; | ||
| 3187 | tem = build_string (state_str); | ||
| 3188 | attrs = Fcons (Fcons (Qstate, tem), attrs); | ||
| 3189 | } | ||
| 3190 | |||
| 3191 | /* FIXME: missing Qttyname. psinfo.pr_ttydev is a dev_t, | ||
| 3192 | need to get a string from it. */ | ||
| 3193 | |||
| 3194 | /* FIXME: missing: Qtpgid */ | ||
| 3195 | |||
| 3196 | /* FIXME: missing: | ||
| 3197 | Qminflt | ||
| 3198 | Qmajflt | ||
| 3199 | Qcminflt | ||
| 3200 | Qcmajflt | ||
| 3201 | |||
| 3202 | Qutime | ||
| 3203 | Qcutime | ||
| 3204 | Qstime | ||
| 3205 | Qcstime | ||
| 3206 | Are they available? */ | ||
| 3207 | |||
| 3208 | attrs = Fcons (Fcons (Qtime, make_lisp_time (pinfo.pr_time)), attrs); | ||
| 3209 | attrs = Fcons (Fcons (Qctime, make_lisp_time (pinfo.pr_ctime)), attrs); | ||
| 3210 | attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs); | ||
| 3211 | attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs); | ||
| 3212 | attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)), attrs); | ||
| 3213 | |||
| 3214 | attrs = Fcons (Fcons (Qstart, make_lisp_time (pinfo.pr_start)), attrs); | ||
| 3215 | attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)), attrs); | ||
| 3216 | attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)), attrs); | ||
| 3217 | |||
| 3218 | /* pr_pctcpu and pr_pctmem are unsigned integers in the | ||
| 3219 | range 0 .. 2**15, representing 0.0 .. 1.0. */ | ||
| 3220 | attrs = Fcons (Fcons (Qpcpu, make_float (100.0 / 0x8000 * pinfo.pr_pctcpu)), attrs); | ||
| 3221 | attrs = Fcons (Fcons (Qpmem, make_float (100.0 / 0x8000 * pinfo.pr_pctmem)), attrs); | ||
| 3222 | |||
| 3223 | decoded_cmd | ||
| 3224 | = code_convert_string_norecord (make_unibyte_string (pinfo.pr_fname, | ||
| 3225 | strlen (pinfo.pr_fname)), | ||
| 3226 | Vlocale_coding_system, 0); | ||
| 3227 | attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); | ||
| 3228 | decoded_cmd | ||
| 3229 | = code_convert_string_norecord (make_unibyte_string (pinfo.pr_psargs, | ||
| 3230 | strlen (pinfo.pr_psargs)), | ||
| 3231 | Vlocale_coding_system, 0); | ||
| 3232 | attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); | ||
| 3233 | } | 3186 | } |
| 3234 | 3187 | ||
| 3235 | if (fd >= 0) | 3188 | if (nread == sizeof pinfo) |
| 3236 | emacs_close (fd); | 3189 | { |
| 3190 | attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (pinfo.pr_ppid)), attrs); | ||
| 3191 | attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pinfo.pr_pgid)), attrs); | ||
| 3192 | attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (pinfo.pr_sid)), attrs); | ||
| 3193 | |||
| 3194 | { | ||
| 3195 | char state_str[2]; | ||
| 3196 | state_str[0] = pinfo.pr_lwp.pr_sname; | ||
| 3197 | state_str[1] = '\0'; | ||
| 3198 | attrs = Fcons (Fcons (Qstate, build_string (state_str)), attrs); | ||
| 3199 | } | ||
| 3237 | 3200 | ||
| 3201 | /* FIXME: missing Qttyname. psinfo.pr_ttydev is a dev_t, | ||
| 3202 | need to get a string from it. */ | ||
| 3203 | |||
| 3204 | /* FIXME: missing: Qtpgid */ | ||
| 3205 | |||
| 3206 | /* FIXME: missing: | ||
| 3207 | Qminflt | ||
| 3208 | Qmajflt | ||
| 3209 | Qcminflt | ||
| 3210 | Qcmajflt | ||
| 3211 | |||
| 3212 | Qutime | ||
| 3213 | Qcutime | ||
| 3214 | Qstime | ||
| 3215 | Qcstime | ||
| 3216 | Are they available? */ | ||
| 3217 | |||
| 3218 | attrs = Fcons (Fcons (Qtime, make_lisp_time (pinfo.pr_time)), attrs); | ||
| 3219 | attrs = Fcons (Fcons (Qctime, make_lisp_time (pinfo.pr_ctime)), attrs); | ||
| 3220 | attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs); | ||
| 3221 | attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs); | ||
| 3222 | attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)), | ||
| 3223 | attrs); | ||
| 3224 | |||
| 3225 | attrs = Fcons (Fcons (Qstart, make_lisp_time (pinfo.pr_start)), attrs); | ||
| 3226 | attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)), | ||
| 3227 | attrs); | ||
| 3228 | attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)), | ||
| 3229 | attrs); | ||
| 3230 | |||
| 3231 | /* pr_pctcpu and pr_pctmem are unsigned integers in the | ||
| 3232 | range 0 .. 2**15, representing 0.0 .. 1.0. */ | ||
| 3233 | attrs = Fcons (Fcons (Qpcpu, | ||
| 3234 | make_float (100.0 / 0x8000 * pinfo.pr_pctcpu)), | ||
| 3235 | attrs); | ||
| 3236 | attrs = Fcons (Fcons (Qpmem, | ||
| 3237 | make_float (100.0 / 0x8000 * pinfo.pr_pctmem)), | ||
| 3238 | attrs); | ||
| 3239 | |||
| 3240 | decoded_cmd = (code_convert_string_norecord | ||
| 3241 | (make_unibyte_string (pinfo.pr_fname, | ||
| 3242 | strlen (pinfo.pr_fname)), | ||
| 3243 | Vlocale_coding_system, 0)); | ||
| 3244 | attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); | ||
| 3245 | decoded_cmd = (code_convert_string_norecord | ||
| 3246 | (make_unibyte_string (pinfo.pr_psargs, | ||
| 3247 | strlen (pinfo.pr_psargs)), | ||
| 3248 | Vlocale_coding_system, 0)); | ||
| 3249 | attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); | ||
| 3250 | } | ||
| 3251 | unbind_to (count, Qnil); | ||
| 3238 | UNGCPRO; | 3252 | UNGCPRO; |
| 3239 | return attrs; | 3253 | return attrs; |
| 3240 | } | 3254 | } |