aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2013-07-20 20:51:53 +0900
committerKenichi Handa2013-07-20 20:51:53 +0900
commit7e67809332c7ac0c798eb13d5573a5804db8134e (patch)
treeee8d4702ed94e7179ae30740f6575ca698539d30 /src
parent0efe47a860bba25617132f02e2220056bfa098b0 (diff)
parent6b1b199dc0e3e7f8028fabe87fac446f5a845479 (diff)
downloademacs-7e67809332c7ac0c798eb13d5573a5804db8134e.tar.gz
emacs-7e67809332c7ac0c798eb13d5573a5804db8134e.zip
merge trunk
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog78
-rw-r--r--src/alloc.c101
-rw-r--r--src/coding.c39
-rw-r--r--src/conf_post.h6
-rw-r--r--src/editfns.c5
-rw-r--r--src/fileio.c3
-rw-r--r--src/filelock.c6
-rw-r--r--src/font.c2
-rw-r--r--src/ftfont.c2
-rw-r--r--src/image.c35
-rw-r--r--src/keyboard.c14
-rw-r--r--src/keymap.c4
-rw-r--r--src/lisp.h43
-rw-r--r--src/lread.c4
-rw-r--r--src/nsterm.m2
-rw-r--r--src/process.c22
-rw-r--r--src/sysdep.c294
-rw-r--r--src/w32fns.c2
-rw-r--r--src/w32term.c15
-rw-r--r--src/xfaces.c20
-rw-r--r--src/xmenu.c3
21 files changed, 432 insertions, 268 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index c3a9ee4c145..5f3a48cbe88 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -3,6 +3,84 @@
3 * coding.c (CODING_ISO_FLAG_LEVEL_4): New macro. 3 * coding.c (CODING_ISO_FLAG_LEVEL_4): New macro.
4 (decode_coding_iso_2022): Check the single-shift area. (Bug#8522) 4 (decode_coding_iso_2022): Check the single-shift area. (Bug#8522)
5 5
62013-07-20 Andreas Schwab <schwab@linux-m68k.org>
7
8 * lread.c (Fload): Avoid uninitialized warning.
9
102013-07-19 Paul Eggert <eggert@cs.ucla.edu>
11
12 Fix some minor file descriptor leaks and related glitches.
13 * filelock.c (create_lock_file) [!O_CLOEXEC]: Use fcntl with FD_CLOEXEC.
14 (create_lock_file): Use write, not emacs_write.
15 * image.c (slurp_file, png_load_body):
16 * process.c (Fnetwork_interface_list, Fnetwork_interface_info)
17 (server_accept_connection):
18 Don't leak an fd on memory allocation failure.
19 * image.c (slurp_file): Add a cheap heuristic for growing files.
20 * xfaces.c (Fx_load_color_file): Block input around the fopen too,
21 as that's what the other routines do. Maybe input need not be
22 blocked at all, but it's better to be consistent.
23 Avoid undefined behavior when strlen is zero.
24
25 * alloc.c (staticpro): Avoid buffer overrun on repeated calls.
26 (NSTATICS): Now a constant; doesn't need to be a macro.
27
282013-07-19 Richard Stallman <rms@gnu.org>
29
30 * coding.c (decode_coding_utf_8): Add simple loop for fast
31 processing of ASCII characters.
32
332013-07-19 Paul Eggert <eggert@cs.ucla.edu>
34
35 * conf_post.h (RE_TRANSLATE_P) [emacs]: Remove obsolete optimization.
36
372013-07-19 Eli Zaretskii <eliz@gnu.org>
38
39 * keyboard.c (kbd_buffer_get_event): Use Display_Info instead of
40 unportable 'struct x_display_info'.
41 (DISPLAY_LIST_INFO): Delete macro: not needed, since Display_Info
42 is a portable type.
43
442013-07-19 Paul Eggert <eggert@cs.ucla.edu>
45
46 * sysdep.c [GNU_LINUX]: Fix fd and memory leaks and similar issues.
47 (procfs_ttyname): Don't use uninitialized storage if emacs_fopen
48 or fscanf fails.
49 (system_process_attributes): Prefer plain char to unsigned char
50 when either will do. Clean up properly if interrupted or if
51 memory allocations fail. Don't assume sscanf succeeds. Remove
52 no-longer-needed workaround to stop GCC from whining. Read
53 command-line once, instead of multiple times. Check read status a
54 bit more carefully.
55
56 Fix obscure porting bug with varargs functions.
57 The code assumed that int is treated like ptrdiff_t in a vararg
58 function, which is not a portable assumption. There was a similar
59 -- though these days less likely -- porting problem with various
60 assumptions that pointers of different types all smell the same as
61 far as vararg functions is conserved. To make this problem less
62 likely in the future, redo the API to use varargs functions.
63 * alloc.c (make_save_value): Remove this vararg function.
64 All uses changed to ...
65 (make_save_int_int_int, make_save_obj_obj_obj_obj)
66 (make_save_ptr_int, make_save_funcptr_ptr_obj, make_save_memory):
67 New functions.
68 (make_save_ptr): Rename from make_save_pointer, for consistency with
69 the above. Define only on platforms that need it. All uses changed.
70
712013-07-18 Paul Eggert <eggert@cs.ucla.edu>
72
73 * keyboard.c: Try to fix typos in previous change.
74 (DISPLAY_LIST_INFO): New macro.
75 (kbd_buffer_get_event): Do not access members that are not present
76 in X11. Revert inadvertent change of "!=" to "=".
77
782013-07-18 Juanma Barranquero <lekktu@gmail.com>
79
80 * keyboard.c (kbd_buffer_get_event):
81 * w32term.c (x_focus_changed): Port FOCUS_(IN|OUT)_EVENT changes to W32.
82 Followup to 2013-07-16T11:41:06Z!jan.h.d@swipnet.se.
83
62013-07-18 Paul Eggert <eggert@cs.ucla.edu> 842013-07-18 Paul Eggert <eggert@cs.ucla.edu>
7 85
8 * filelock.c: Fix unlikely file descriptor leaks. 86 * filelock.c: Fix unlikely file descriptor leaks.
diff --git a/src/alloc.c b/src/alloc.c
index 39f6a82b138..4c924f72384 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -341,7 +341,7 @@ struct gcpro *gcprolist;
341/* Addresses of staticpro'd variables. Initialize it to a nonzero 341/* Addresses of staticpro'd variables. Initialize it to a nonzero
342 value; otherwise some compilers put it into BSS. */ 342 value; otherwise some compilers put it into BSS. */
343 343
344#define NSTATICS 0x800 344enum { NSTATICS = 2048 };
345static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag}; 345static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag};
346 346
347/* Index of next unused slot in staticvec. */ 347/* Index of next unused slot in staticvec. */
@@ -3342,62 +3342,81 @@ verify (((SAVE_INTEGER | SAVE_POINTER | SAVE_FUNCPOINTER | SAVE_OBJECT)
3342 >> SAVE_SLOT_BITS) 3342 >> SAVE_SLOT_BITS)
3343 == 0); 3343 == 0);
3344 3344
3345/* Return a Lisp_Save_Value object with the data saved according to 3345/* Return Lisp_Save_Value objects for the various combinations
3346 DATA_TYPE. DATA_TYPE should be one of SAVE_TYPE_INT_INT, etc. */ 3346 that callers need. */
3347 3347
3348Lisp_Object 3348Lisp_Object
3349make_save_value (enum Lisp_Save_Type save_type, ...) 3349make_save_int_int_int (ptrdiff_t a, ptrdiff_t b, ptrdiff_t c)
3350{ 3350{
3351 va_list ap;
3352 int i;
3353 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); 3351 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3354 struct Lisp_Save_Value *p = XSAVE_VALUE (val); 3352 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3353 p->save_type = SAVE_TYPE_INT_INT_INT;
3354 p->data[0].integer = a;
3355 p->data[1].integer = b;
3356 p->data[2].integer = c;
3357 return val;
3358}
3355 3359
3356 eassert (0 < save_type 3360Lisp_Object
3357 && (save_type < 1 << (SAVE_TYPE_BITS - 1) 3361make_save_obj_obj_obj_obj (Lisp_Object a, Lisp_Object b, Lisp_Object c,
3358 || save_type == SAVE_TYPE_MEMORY)); 3362 Lisp_Object d)
3359 p->save_type = save_type; 3363{
3360 va_start (ap, save_type); 3364 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3361 save_type &= ~ (1 << (SAVE_TYPE_BITS - 1)); 3365 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3362 3366 p->save_type = SAVE_TYPE_OBJ_OBJ_OBJ_OBJ;
3363 for (i = 0; save_type; i++, save_type >>= SAVE_SLOT_BITS) 3367 p->data[0].object = a;
3364 switch (save_type & ((1 << SAVE_SLOT_BITS) - 1)) 3368 p->data[1].object = b;
3365 { 3369 p->data[2].object = c;
3366 case SAVE_POINTER: 3370 p->data[3].object = d;
3367 p->data[i].pointer = va_arg (ap, void *); 3371 return val;
3368 break; 3372}
3369
3370 case SAVE_FUNCPOINTER:
3371 p->data[i].funcpointer = va_arg (ap, voidfuncptr);
3372 break;
3373
3374 case SAVE_INTEGER:
3375 p->data[i].integer = va_arg (ap, ptrdiff_t);
3376 break;
3377 3373
3378 case SAVE_OBJECT: 3374#if defined HAVE_NS || defined DOS_NT
3379 p->data[i].object = va_arg (ap, Lisp_Object); 3375Lisp_Object
3380 break; 3376make_save_ptr (void *a)
3377{
3378 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3379 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3380 p->save_type = SAVE_POINTER;
3381 p->data[0].pointer = a;
3382 return val;
3383}
3384#endif
3381 3385
3382 default: 3386Lisp_Object
3383 emacs_abort (); 3387make_save_ptr_int (void *a, ptrdiff_t b)
3384 } 3388{
3389 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3390 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3391 p->save_type = SAVE_TYPE_PTR_INT;
3392 p->data[0].pointer = a;
3393 p->data[1].integer = b;
3394 return val;
3395}
3385 3396
3386 va_end (ap); 3397Lisp_Object
3398make_save_funcptr_ptr_obj (void (*a) (void), void *b, Lisp_Object c)
3399{
3400 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3401 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3402 p->save_type = SAVE_TYPE_FUNCPTR_PTR_OBJ;
3403 p->data[0].funcpointer = a;
3404 p->data[1].pointer = b;
3405 p->data[2].object = c;
3387 return val; 3406 return val;
3388} 3407}
3389 3408
3390/* Save just one C pointer. record_unwind_protect_ptr is simpler and 3409/* Return a Lisp_Save_Value object that represents an array A
3391 faster than combining this with record_unwind_protect, but 3410 of N Lisp objects. */
3392 occasionally this function is useful for other reasons. */
3393 3411
3394Lisp_Object 3412Lisp_Object
3395make_save_pointer (void *pointer) 3413make_save_memory (Lisp_Object *a, ptrdiff_t n)
3396{ 3414{
3397 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); 3415 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3398 struct Lisp_Save_Value *p = XSAVE_VALUE (val); 3416 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3399 p->save_type = SAVE_POINTER; 3417 p->save_type = SAVE_TYPE_MEMORY;
3400 p->data[0].pointer = pointer; 3418 p->data[0].pointer = a;
3419 p->data[1].integer = n;
3401 return val; 3420 return val;
3402} 3421}
3403 3422
@@ -5117,9 +5136,9 @@ Does not copy symbols. Copies strings without text properties. */)
5117void 5136void
5118staticpro (Lisp_Object *varaddress) 5137staticpro (Lisp_Object *varaddress)
5119{ 5138{
5120 staticvec[staticidx++] = varaddress;
5121 if (staticidx >= NSTATICS) 5139 if (staticidx >= NSTATICS)
5122 fatal ("NSTATICS too small; try increasing and recompiling Emacs."); 5140 fatal ("NSTATICS too small; try increasing and recompiling Emacs.");
5141 staticvec[staticidx++] = varaddress;
5123} 5142}
5124 5143
5125 5144
diff --git a/src/coding.c b/src/coding.c
index 3acbd090e13..0cdd8f9cd9e 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -1365,6 +1365,45 @@ decode_coding_utf_8 (struct coding_system *coding)
1365 break; 1365 break;
1366 } 1366 }
1367 1367
1368 /* In the simple case, rapidly handle ordinary characters */
1369 if (multibytep && ! eol_dos
1370 && charbuf < charbuf_end - 6 && src < src_end - 6)
1371 {
1372 while (charbuf < charbuf_end - 6 && src < src_end - 6)
1373 {
1374 c1 = *src;
1375 if (c1 & 0x80)
1376 break;
1377 src++;
1378 consumed_chars++;
1379 *charbuf++ = c1;
1380
1381 c1 = *src;
1382 if (c1 & 0x80)
1383 break;
1384 src++;
1385 consumed_chars++;
1386 *charbuf++ = c1;
1387
1388 c1 = *src;
1389 if (c1 & 0x80)
1390 break;
1391 src++;
1392 consumed_chars++;
1393 *charbuf++ = c1;
1394
1395 c1 = *src;
1396 if (c1 & 0x80)
1397 break;
1398 src++;
1399 consumed_chars++;
1400 *charbuf++ = c1;
1401 }
1402 /* If we handled at least one character, restart the main loop. */
1403 if (src != src_base)
1404 continue;
1405 }
1406
1368 if (byte_after_cr >= 0) 1407 if (byte_after_cr >= 0)
1369 c1 = byte_after_cr, byte_after_cr = -1; 1408 c1 = byte_after_cr, byte_after_cr = -1;
1370 else 1409 else
diff --git a/src/conf_post.h b/src/conf_post.h
index b19456749a2..16714076f6f 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -160,13 +160,7 @@ extern void _DebPrint (const char *fmt, ...);
160/* Tell regex.c to use a type compatible with Emacs. */ 160/* Tell regex.c to use a type compatible with Emacs. */
161#define RE_TRANSLATE_TYPE Lisp_Object 161#define RE_TRANSLATE_TYPE Lisp_Object
162#define RE_TRANSLATE(TBL, C) char_table_translate (TBL, C) 162#define RE_TRANSLATE(TBL, C) char_table_translate (TBL, C)
163#ifdef make_number
164/* If make_number is a macro, use it. */
165#define RE_TRANSLATE_P(TBL) (!EQ (TBL, make_number (0))) 163#define RE_TRANSLATE_P(TBL) (!EQ (TBL, make_number (0)))
166#else
167/* If make_number is a function, avoid it. */
168#define RE_TRANSLATE_P(TBL) (!(INTEGERP (TBL) && XINT (TBL) == 0))
169#endif
170#endif 164#endif
171 165
172#include <string.h> 166#include <string.h>
diff --git a/src/editfns.c b/src/editfns.c
index a4dea203a22..50bde90788d 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -838,9 +838,8 @@ This function does not move point. */)
838Lisp_Object 838Lisp_Object
839save_excursion_save (void) 839save_excursion_save (void)
840{ 840{
841 return make_save_value 841 return make_save_obj_obj_obj_obj
842 (SAVE_TYPE_OBJ_OBJ_OBJ_OBJ, 842 (Fpoint_marker (),
843 Fpoint_marker (),
844 /* Do not copy the mark if it points to nowhere. */ 843 /* Do not copy the mark if it points to nowhere. */
845 (XMARKER (BVAR (current_buffer, mark))->buffer 844 (XMARKER (BVAR (current_buffer, mark))->buffer
846 ? Fcopy_marker (BVAR (current_buffer, mark), Qnil) 845 ? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
diff --git a/src/fileio.c b/src/fileio.c
index 5fe359d58bb..a19fcd9f663 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -4215,8 +4215,7 @@ by calling `format-decode', which see. */)
4215 to be signaled after decoding the text we read. */ 4215 to be signaled after decoding the text we read. */
4216 nbytes = internal_condition_case_1 4216 nbytes = internal_condition_case_1
4217 (read_non_regular, 4217 (read_non_regular,
4218 make_save_value (SAVE_TYPE_INT_INT_INT, (ptrdiff_t) fd, 4218 make_save_int_int_int (fd, inserted, trytry),
4219 inserted, trytry),
4220 Qerror, read_non_regular_quit); 4219 Qerror, read_non_regular_quit);
4221 4220
4222 if (NILP (nbytes)) 4221 if (NILP (nbytes))
diff --git a/src/filelock.c b/src/filelock.c
index fefd14b3a92..b9c991e4baf 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -430,12 +430,14 @@ create_lock_file (char *lfname, char *lock_info_str, bool force)
430 else 430 else
431 { 431 {
432 ptrdiff_t lock_info_len; 432 ptrdiff_t lock_info_len;
433#if ! HAVE_MKOSTEMP 433#if ! (HAVE_MKOSTEMP && O_CLOEXEC)
434 fcntl (fd, F_SETFD, FD_CLOEXEC); 434 fcntl (fd, F_SETFD, FD_CLOEXEC);
435#endif 435#endif
436 lock_info_len = strlen (lock_info_str); 436 lock_info_len = strlen (lock_info_str);
437 err = 0; 437 err = 0;
438 if (emacs_write (fd, lock_info_str, lock_info_len) != lock_info_len 438 /* Use 'write', not 'emacs_write', as garbage collection
439 might signal an error, which would leak FD. */
440 if (write (fd, lock_info_str, lock_info_len) != lock_info_len
439 || fchmod (fd, S_IRUSR | S_IRGRP | S_IROTH) != 0) 441 || fchmod (fd, S_IRUSR | S_IRGRP | S_IROTH) != 0)
440 err = errno; 442 err = errno;
441 /* There is no need to call fsync here, as the contents of 443 /* There is no need to call fsync here, as the contents of
diff --git a/src/font.c b/src/font.c
index 80b4b76c4e4..124d5f9bd9e 100644
--- a/src/font.c
+++ b/src/font.c
@@ -1861,7 +1861,7 @@ otf_open (Lisp_Object file)
1861 else 1861 else
1862 { 1862 {
1863 otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL; 1863 otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL;
1864 val = make_save_pointer (otf); 1864 val = make_save_ptr (otf);
1865 otf_list = Fcons (Fcons (file, val), otf_list); 1865 otf_list = Fcons (Fcons (file, val), otf_list);
1866 } 1866 }
1867 return otf; 1867 return otf;
diff --git a/src/ftfont.c b/src/ftfont.c
index 7c9534d5ae7..10090cb3bda 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -393,7 +393,7 @@ ftfont_lookup_cache (Lisp_Object key, enum ftfont_cache_for cache_for)
393 cache_data = xmalloc (sizeof *cache_data); 393 cache_data = xmalloc (sizeof *cache_data);
394 cache_data->ft_face = NULL; 394 cache_data->ft_face = NULL;
395 cache_data->fc_charset = NULL; 395 cache_data->fc_charset = NULL;
396 val = make_save_value (SAVE_TYPE_PTR_INT, cache_data, 0); 396 val = make_save_ptr_int (cache_data, 0);
397 cache = Fcons (Qnil, val); 397 cache = Fcons (Qnil, val);
398 Fputhash (key, cache, ft_face_cache); 398 Fputhash (key, cache, ft_face_cache);
399 } 399 }
diff --git a/src/image.c b/src/image.c
index 95d385dc9e2..1e3944ac1a1 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2276,23 +2276,28 @@ slurp_file (char *file, ptrdiff_t *size)
2276 unsigned char *buf = NULL; 2276 unsigned char *buf = NULL;
2277 struct stat st; 2277 struct stat st;
2278 2278
2279 if (fp && fstat (fileno (fp), &st) == 0 2279 if (fp)
2280 && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX)
2281 && (buf = xmalloc (st.st_size),
2282 fread (buf, 1, st.st_size, fp) == st.st_size))
2283 {
2284 *size = st.st_size;
2285 fclose (fp);
2286 }
2287 else
2288 { 2280 {
2289 if (fp) 2281 ptrdiff_t count = SPECPDL_INDEX ();
2290 fclose (fp); 2282 record_unwind_protect_ptr (fclose_unwind, fp);
2291 if (buf) 2283
2284 if (fstat (fileno (fp), &st) == 0
2285 && 0 <= st.st_size && st.st_size < min (PTRDIFF_MAX, SIZE_MAX))
2292 { 2286 {
2293 xfree (buf); 2287 /* Report an error if we read past the purported EOF.
2294 buf = NULL; 2288 This can happen if the file grows as we read it. */
2289 ptrdiff_t buflen = st.st_size;
2290 buf = xmalloc (buflen + 1);
2291 if (fread (buf, 1, buflen + 1, fp) == buflen)
2292 *size = buflen;
2293 else
2294 {
2295 xfree (buf);
2296 buf = NULL;
2297 }
2295 } 2298 }
2299
2300 unbind_to (count, Qnil);
2296 } 2301 }
2297 2302
2298 return buf; 2303 return buf;
@@ -5732,8 +5737,8 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5732 if (fread (sig, 1, sizeof sig, fp) != sizeof sig 5737 if (fread (sig, 1, sizeof sig, fp) != sizeof sig
5733 || fn_png_sig_cmp (sig, 0, sizeof sig)) 5738 || fn_png_sig_cmp (sig, 0, sizeof sig))
5734 { 5739 {
5735 image_error ("Not a PNG file: `%s'", file, Qnil);
5736 fclose (fp); 5740 fclose (fp);
5741 image_error ("Not a PNG file: `%s'", file, Qnil);
5737 return 0; 5742 return 0;
5738 } 5743 }
5739 } 5744 }
diff --git a/src/keyboard.c b/src/keyboard.c
index 07dce85ff29..830f70bc1f5 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4066,21 +4066,19 @@ kbd_buffer_get_event (KBOARD **kbp,
4066 } 4066 }
4067 else if (event->kind == FOCUS_OUT_EVENT) 4067 else if (event->kind == FOCUS_OUT_EVENT)
4068 { 4068 {
4069#if defined(HAVE_NS) || defined (HAVE_X11) 4069#ifdef HAVE_WINDOW_SYSTEM
4070 4070
4071#ifdef HAVE_NS 4071 Display_Info *di;
4072 struct ns_display_info *di;
4073#else
4074 struct x_display_info *di;
4075#endif
4076 Lisp_Object frame = event->frame_or_window; 4072 Lisp_Object frame = event->frame_or_window;
4077 bool focused = false; 4073 bool focused = false;
4078 4074
4079 for (di = x_display_list; di && ! focused; di = di->next) 4075 for (di = x_display_list; di && ! focused; di = di->next)
4080 focused = di->x_highlight_frame != 0; 4076 focused = di->x_highlight_frame != 0;
4081 4077
4082 if (! focused) obj = make_lispy_focus_out (frame); 4078 if (!focused)
4083#endif /* HAVE_NS || HAVE_X11 */ 4079 obj = make_lispy_focus_out (frame);
4080
4081#endif /* HAVE_WINDOW_SYSTEM */
4084 4082
4085 kbd_fetch_ptr = event + 1; 4083 kbd_fetch_ptr = event + 1;
4086 } 4084 }
diff --git a/src/keymap.c b/src/keymap.c
index e1268c8a06c..d13a6274347 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -617,8 +617,8 @@ map_keymap_internal (Lisp_Object map,
617 } 617 }
618 else if (CHAR_TABLE_P (binding)) 618 else if (CHAR_TABLE_P (binding))
619 map_char_table (map_keymap_char_table_item, Qnil, binding, 619 map_char_table (map_keymap_char_table_item, Qnil, binding,
620 make_save_value (SAVE_TYPE_FUNCPTR_PTR_OBJ, 620 make_save_funcptr_ptr_obj ((voidfuncptr) fun, data,
621 (voidfuncptr) fun, data, args)); 621 args));
622 } 622 }
623 UNGCPRO; 623 UNGCPRO;
624 return tail; 624 return tail;
diff --git a/src/lisp.h b/src/lisp.h
index 518de9db0ff..254ead231b9 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -441,8 +441,7 @@ enum Lisp_Fwd_Type
441 displayed to users. These are Lisp_Save_Value, a Lisp_Misc 441 displayed to users. These are Lisp_Save_Value, a Lisp_Misc
442 subtype; and PVEC_OTHER, a kind of vectorlike object. The former 442 subtype; and PVEC_OTHER, a kind of vectorlike object. The former
443 is suitable for temporarily stashing away pointers and integers in 443 is suitable for temporarily stashing away pointers and integers in
444 a Lisp object (see the existing uses of make_save_value and 444 a Lisp object. The latter is useful for vector-like Lisp objects
445 XSAVE_VALUE). The latter is useful for vector-like Lisp objects
446 that need to be used as part of other objects, but which are never 445 that need to be used as part of other objects, but which are never
447 shown to users or Lisp code (search for PVEC_OTHER in xterm.c for 446 shown to users or Lisp code (search for PVEC_OTHER in xterm.c for
448 an example). 447 an example).
@@ -1815,30 +1814,26 @@ enum Lisp_Save_Type
1815 1814
1816 This is mostly used to package C integers and pointers to call 1815 This is mostly used to package C integers and pointers to call
1817 record_unwind_protect when two or more values need to be saved. 1816 record_unwind_protect when two or more values need to be saved.
1818 make_save_value lets you pack up to SAVE_VALUE_SLOTS integers, pointers, 1817 For example:
1819 function pointers or Lisp_Objects and conveniently get them back
1820 with XSAVE_INTEGER, XSAVE_POINTER, XSAVE_FUNCPOINTER, and
1821 XSAVE_OBJECT macros:
1822 1818
1823 ... 1819 ...
1824 struct my_data *md = get_my_data (); 1820 struct my_data *md = get_my_data ();
1825 Lisp_Object my_object = get_my_object (); 1821 ptrdiff_t mi = get_my_integer ();
1826 record_unwind_protect 1822 record_unwind_protect (my_unwind, make_save_ptr_int (md, mi));
1827 (my_unwind, make_save_value (SAVE_TYPE_PTR_OBJ, md, my_object));
1828 ... 1823 ...
1829 1824
1830 Lisp_Object my_unwind (Lisp_Object arg) 1825 Lisp_Object my_unwind (Lisp_Object arg)
1831 { 1826 {
1832 struct my_data *md = XSAVE_POINTER (arg, 0); 1827 struct my_data *md = XSAVE_POINTER (arg, 0);
1833 Lisp_Object my_object = XSAVE_OBJECT (arg, 1); 1828 ptrdiff_t mi = XSAVE_INTEGER (arg, 1);
1834 ... 1829 ...
1835 } 1830 }
1836 1831
1837 If ENABLE_CHECKING is in effect, XSAVE_xxx macros do type checking of the 1832 If ENABLE_CHECKING is in effect, XSAVE_xxx macros do type checking of the
1838 saved objects and raise eassert if type of the saved object doesn't match 1833 saved objects and raise eassert if type of the saved object doesn't match
1839 the type which is extracted. In the example above, XSAVE_INTEGER (arg, 2) 1834 the type which is extracted. In the example above, XSAVE_INTEGER (arg, 2)
1840 or XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and 1835 and XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and
1841 Lisp_Object was saved in slot 1 of ARG. */ 1836 slot 0 is a pointer. */
1842 1837
1843typedef void (*voidfuncptr) (void); 1838typedef void (*voidfuncptr) (void);
1844 1839
@@ -1848,12 +1843,13 @@ struct Lisp_Save_Value
1848 unsigned gcmarkbit : 1; 1843 unsigned gcmarkbit : 1;
1849 int spacer : 32 - (16 + 1 + SAVE_TYPE_BITS); 1844 int spacer : 32 - (16 + 1 + SAVE_TYPE_BITS);
1850 1845
1851 /* DATA[N] may hold up to SAVE_VALUE_SLOTS entries. The type of 1846 /* V->data may hold up to SAVE_VALUE_SLOTS entries. The type of
1852 V's Ith entry is given by save_type (V, I). E.g., if save_type 1847 V's data entries are determined by V->save_type. E.g., if
1853 (V, 3) == SAVE_INTEGER, V->data[3].integer is in use. 1848 V->save_type == SAVE_TYPE_PTR_OBJ, V->data[0] is a pointer,
1849 V->data[1] is an integer, and V's other data entries are unused.
1854 1850
1855 If SAVE_TYPE == SAVE_TYPE_MEMORY, DATA[0].pointer is the address of 1851 If V->save_type == SAVE_TYPE_MEMORY, V->data[0].pointer is the address of
1856 a memory area containing DATA[1].integer potential Lisp_Objects. */ 1852 a memory area containing V->data[1].integer potential Lisp_Objects. */
1857 ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS; 1853 ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS;
1858 union { 1854 union {
1859 void *pointer; 1855 void *pointer;
@@ -3580,8 +3576,15 @@ extern bool abort_on_gc;
3580extern Lisp_Object make_float (double); 3576extern Lisp_Object make_float (double);
3581extern void display_malloc_warning (void); 3577extern void display_malloc_warning (void);
3582extern ptrdiff_t inhibit_garbage_collection (void); 3578extern ptrdiff_t inhibit_garbage_collection (void);
3583extern Lisp_Object make_save_value (enum Lisp_Save_Type, ...); 3579extern Lisp_Object make_save_int_int_int (ptrdiff_t, ptrdiff_t, ptrdiff_t);
3584extern Lisp_Object make_save_pointer (void *); 3580extern Lisp_Object make_save_obj_obj_obj_obj (Lisp_Object, Lisp_Object,
3581 Lisp_Object, Lisp_Object);
3582extern Lisp_Object make_save_ptr (void *);
3583extern Lisp_Object make_save_ptr_int (void *, ptrdiff_t);
3584extern Lisp_Object make_save_ptr_ptr (void *, void *);
3585extern Lisp_Object make_save_funcptr_ptr_obj (void (*) (void), void *,
3586 Lisp_Object);
3587extern Lisp_Object make_save_memory (Lisp_Object *, ptrdiff_t);
3585extern void free_save_value (Lisp_Object); 3588extern void free_save_value (Lisp_Object);
3586extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); 3589extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
3587extern void free_marker (Lisp_Object); 3590extern void free_marker (Lisp_Object);
@@ -4314,7 +4317,7 @@ extern void *record_xmalloc (size_t);
4314 { \ 4317 { \
4315 Lisp_Object arg_; \ 4318 Lisp_Object arg_; \
4316 buf = xmalloc ((nelt) * word_size); \ 4319 buf = xmalloc ((nelt) * word_size); \
4317 arg_ = make_save_value (SAVE_TYPE_MEMORY, buf, nelt); \ 4320 arg_ = make_save_memory (buf, nelt); \
4318 sa_must_free = 1; \ 4321 sa_must_free = 1; \
4319 record_unwind_protect (free_save_value, arg_); \ 4322 record_unwind_protect (free_save_value, arg_); \
4320 } \ 4323 } \
diff --git a/src/lread.c b/src/lread.c
index 146543a99fd..e701338da31 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1044,7 +1044,7 @@ Return t if the file exists and loads successfully. */)
1044{ 1044{
1045 FILE *stream; 1045 FILE *stream;
1046 int fd; 1046 int fd;
1047 int fd_index; 1047 int fd_index = 0;
1048 ptrdiff_t count = SPECPDL_INDEX (); 1048 ptrdiff_t count = SPECPDL_INDEX ();
1049 struct gcpro gcpro1, gcpro2, gcpro3; 1049 struct gcpro gcpro1, gcpro2, gcpro3;
1050 Lisp_Object found, efound, hist_file_name; 1050 Lisp_Object found, efound, hist_file_name;
@@ -1175,7 +1175,7 @@ Return t if the file exists and loads successfully. */)
1175#endif 1175#endif
1176 } 1176 }
1177 1177
1178 if (0 <= fd) 1178 if (fd >= 0)
1179 { 1179 {
1180 fd_index = SPECPDL_INDEX (); 1180 fd_index = SPECPDL_INDEX ();
1181 record_unwind_protect_int (close_file_unwind, fd); 1181 record_unwind_protect_int (close_file_unwind, fd);
diff --git a/src/nsterm.m b/src/nsterm.m
index c91e68f37a9..f3c35e95bfe 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -3777,7 +3777,7 @@ ns_set_vertical_scroll_bar (struct window *window,
3777 } 3777 }
3778 3778
3779 bar = [[EmacsScroller alloc] initFrame: r window: win]; 3779 bar = [[EmacsScroller alloc] initFrame: r window: win];
3780 wset_vertical_scroll_bar (window, make_save_pointer (bar)); 3780 wset_vertical_scroll_bar (window, make_save_ptr (bar));
3781 } 3781 }
3782 else 3782 else
3783 { 3783 {
diff --git a/src/process.c b/src/process.c
index 7c63964aee6..f4ae662468b 100644
--- a/src/process.c
+++ b/src/process.c
@@ -3526,10 +3526,13 @@ format; see the description of ADDRESS in `make-network-process'. */)
3526 ptrdiff_t buf_size = 512; 3526 ptrdiff_t buf_size = 512;
3527 int s; 3527 int s;
3528 Lisp_Object res; 3528 Lisp_Object res;
3529 ptrdiff_t count;
3529 3530
3530 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); 3531 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
3531 if (s < 0) 3532 if (s < 0)
3532 return Qnil; 3533 return Qnil;
3534 count = SPECPDL_INDEX ();
3535 record_unwind_protect_int (close_file_unwind, s);
3533 3536
3534 do 3537 do
3535 { 3538 {
@@ -3545,9 +3548,7 @@ format; see the description of ADDRESS in `make-network-process'. */)
3545 } 3548 }
3546 while (ifconf.ifc_len == buf_size); 3549 while (ifconf.ifc_len == buf_size);
3547 3550
3548 emacs_close (s); 3551 res = unbind_to (count, Qnil);
3549
3550 res = Qnil;
3551 ifreq = ifconf.ifc_req; 3552 ifreq = ifconf.ifc_req;
3552 while ((char *) ifreq < (char *) ifconf.ifc_req + ifconf.ifc_len) 3553 while ((char *) ifreq < (char *) ifconf.ifc_req + ifconf.ifc_len)
3553 { 3554 {
@@ -3672,6 +3673,7 @@ FLAGS is the current flags of the interface. */)
3672 Lisp_Object elt; 3673 Lisp_Object elt;
3673 int s; 3674 int s;
3674 bool any = 0; 3675 bool any = 0;
3676 ptrdiff_t count;
3675#if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \ 3677#if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \
3676 && defined HAVE_GETIFADDRS && defined LLADDR) 3678 && defined HAVE_GETIFADDRS && defined LLADDR)
3677 struct ifaddrs *ifap; 3679 struct ifaddrs *ifap;
@@ -3686,6 +3688,8 @@ FLAGS is the current flags of the interface. */)
3686 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); 3688 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
3687 if (s < 0) 3689 if (s < 0)
3688 return Qnil; 3690 return Qnil;
3691 count = SPECPDL_INDEX ();
3692 record_unwind_protect_int (close_file_unwind, s);
3689 3693
3690 elt = Qnil; 3694 elt = Qnil;
3691#if defined (SIOCGIFFLAGS) && defined (HAVE_STRUCT_IFREQ_IFR_FLAGS) 3695#if defined (SIOCGIFFLAGS) && defined (HAVE_STRUCT_IFREQ_IFR_FLAGS)
@@ -3802,9 +3806,7 @@ FLAGS is the current flags of the interface. */)
3802#endif 3806#endif
3803 res = Fcons (elt, res); 3807 res = Fcons (elt, res);
3804 3808
3805 emacs_close (s); 3809 return unbind_to (count, any ? res : Qnil);
3806
3807 return any ? res : Qnil;
3808} 3810}
3809#endif 3811#endif
3810#endif /* defined (HAVE_NET_IF_H) */ 3812#endif /* defined (HAVE_NET_IF_H) */
@@ -3978,6 +3980,7 @@ server_accept_connection (Lisp_Object server, int channel)
3978#endif 3980#endif
3979 } saddr; 3981 } saddr;
3980 socklen_t len = sizeof saddr; 3982 socklen_t len = sizeof saddr;
3983 ptrdiff_t count;
3981 3984
3982 s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC); 3985 s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC);
3983 3986
@@ -4000,6 +4003,9 @@ server_accept_connection (Lisp_Object server, int channel)
4000 return; 4003 return;
4001 } 4004 }
4002 4005
4006 count = SPECPDL_INDEX ();
4007 record_unwind_protect_int (close_file_unwind, s);
4008
4003 connect_counter++; 4009 connect_counter++;
4004 4010
4005 /* Setup a new process to handle the connection. */ 4011 /* Setup a new process to handle the connection. */
@@ -4116,6 +4122,10 @@ server_accept_connection (Lisp_Object server, int channel)
4116 pset_filter (p, ps->filter); 4122 pset_filter (p, ps->filter);
4117 pset_command (p, Qnil); 4123 pset_command (p, Qnil);
4118 p->pid = 0; 4124 p->pid = 0;
4125
4126 /* Discard the unwind protect for closing S. */
4127 specpdl_ptr = specpdl + count;
4128
4119 p->infd = s; 4129 p->infd = s;
4120 p->outfd = s; 4130 p->outfd = s;
4121 pset_status (p, Qrun); 4131 pset_status (p, Qrun);
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}
diff --git a/src/w32fns.c b/src/w32fns.c
index 5d9200bdd7b..675b716f3b0 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -4916,7 +4916,7 @@ w32_monitor_enum (HMONITOR monitor, HDC hdc, RECT *rcMonitor, LPARAM dwData)
4916{ 4916{
4917 Lisp_Object *monitor_list = (Lisp_Object *) dwData; 4917 Lisp_Object *monitor_list = (Lisp_Object *) dwData;
4918 4918
4919 *monitor_list = Fcons (make_save_pointer (monitor), *monitor_list); 4919 *monitor_list = Fcons (make_save_ptr (monitor), *monitor_list);
4920 4920
4921 return TRUE; 4921 return TRUE;
4922} 4922}
diff --git a/src/w32term.c b/src/w32term.c
index 732a4f4bfef..2fe3fe07462 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -2912,9 +2912,15 @@ x_focus_changed (int type, int state, struct w32_display_info *dpyinfo,
2912 && CONSP (Vframe_list) 2912 && CONSP (Vframe_list)
2913 && !NILP (XCDR (Vframe_list))) 2913 && !NILP (XCDR (Vframe_list)))
2914 { 2914 {
2915 bufp->kind = FOCUS_IN_EVENT; 2915 bufp->arg = Qt;
2916 XSETFRAME (bufp->frame_or_window, frame);
2917 } 2916 }
2917 else
2918 {
2919 bufp->arg = Qnil;
2920 }
2921
2922 bufp->kind = FOCUS_IN_EVENT;
2923 XSETFRAME (bufp->frame_or_window, frame);
2918 } 2924 }
2919 2925
2920 frame->output_data.x->focus_state |= state; 2926 frame->output_data.x->focus_state |= state;
@@ -2929,7 +2935,10 @@ x_focus_changed (int type, int state, struct w32_display_info *dpyinfo,
2929 { 2935 {
2930 dpyinfo->w32_focus_event_frame = 0; 2936 dpyinfo->w32_focus_event_frame = 0;
2931 x_new_focus_frame (dpyinfo, 0); 2937 x_new_focus_frame (dpyinfo, 0);
2932 } 2938
2939 bufp->kind = FOCUS_OUT_EVENT;
2940 XSETFRAME (bufp->frame_or_window, frame);
2941 }
2933 2942
2934 /* TODO: IME focus? */ 2943 /* TODO: IME focus? */
2935 } 2944 }
diff --git a/src/xfaces.c b/src/xfaces.c
index d35851220b0..f647ff2e209 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -6283,6 +6283,7 @@ where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */)
6283 CHECK_STRING (filename); 6283 CHECK_STRING (filename);
6284 abspath = Fexpand_file_name (filename, Qnil); 6284 abspath = Fexpand_file_name (filename, Qnil);
6285 6285
6286 block_input ();
6286 fp = emacs_fopen (SSDATA (abspath), "rt"); 6287 fp = emacs_fopen (SSDATA (abspath), "rt");
6287 if (fp) 6288 if (fp)
6288 { 6289 {
@@ -6290,29 +6291,24 @@ where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */)
6290 int red, green, blue; 6291 int red, green, blue;
6291 int num; 6292 int num;
6292 6293
6293 block_input ();
6294
6295 while (fgets (buf, sizeof (buf), fp) != NULL) { 6294 while (fgets (buf, sizeof (buf), fp) != NULL) {
6296 if (sscanf (buf, "%u %u %u %n", &red, &green, &blue, &num) == 3) 6295 if (sscanf (buf, "%u %u %u %n", &red, &green, &blue, &num) == 3)
6297 { 6296 {
6298 char *name = buf + num;
6299 num = strlen (name) - 1;
6300 if (num >= 0 && name[num] == '\n')
6301 name[num] = 0;
6302 cmap = Fcons (Fcons (build_string (name),
6303#ifdef HAVE_NTGUI 6297#ifdef HAVE_NTGUI
6304 make_number (RGB (red, green, blue))), 6298 int color = RGB (red, green, blue);
6305#else 6299#else
6306 make_number ((red << 16) | (green << 8) | blue)), 6300 int color = (red << 16) | (green << 8) | blue;
6307#endif 6301#endif
6302 char *name = buf + num;
6303 ptrdiff_t len = strlen (name);
6304 len -= 0 < len && name[len - 1] == '\n';
6305 cmap = Fcons (Fcons (make_string (name, len), make_number (color)),
6308 cmap); 6306 cmap);
6309 } 6307 }
6310 } 6308 }
6311 fclose (fp); 6309 fclose (fp);
6312
6313 unblock_input ();
6314 } 6310 }
6315 6311 unblock_input ();
6316 return cmap; 6312 return cmap;
6317} 6313}
6318#endif 6314#endif
diff --git a/src/xmenu.c b/src/xmenu.c
index 1151dea440e..6c0e3dd78a6 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -2465,8 +2465,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
2465 XMenuActivateSetWaitFunction (x_menu_wait_for_event, FRAME_X_DISPLAY (f)); 2465 XMenuActivateSetWaitFunction (x_menu_wait_for_event, FRAME_X_DISPLAY (f));
2466#endif 2466#endif
2467 2467
2468 record_unwind_protect (pop_down_menu, 2468 record_unwind_protect (pop_down_menu, make_save_ptr_ptr (f, menu));
2469 make_save_value (SAVE_TYPE_PTR_PTR, f, menu));
2470 2469
2471 /* Help display under X won't work because XMenuActivate contains 2470 /* Help display under X won't work because XMenuActivate contains
2472 a loop that doesn't give Emacs a chance to process it. */ 2471 a loop that doesn't give Emacs a chance to process it. */