aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2013-07-18 22:36:50 -0700
committerPaul Eggert2013-07-18 22:36:50 -0700
commitab9980cd3ba7e1cefe846610dccdc86923dcdb86 (patch)
treedb46d81037a960b07d1963cfd9166b8358b0c77d
parent1396ac86dea5fccab800e4b25fdb5319381891eb (diff)
downloademacs-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/ChangeLog10
-rw-r--r--src/sysdep.c294
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 @@
12013-07-19 Paul Eggert <eggert@cs.ucla.edu> 12013-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)
2807static Lisp_Object 2807static Lisp_Object
2808procfs_ttyname (int rdev) 2808procfs_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)
2849static unsigned long 2850static unsigned long
2850procfs_get_total_memory (void) 2851procfs_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}