summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2013-08-25 14:25:59 -0600
committerTom Tromey <tromey@redhat.com>2013-08-25 14:25:59 -0600
commit793ea5055aea85ff9227e1bf0c84ab37edba7201 (patch)
treec9799eebe2b797a55fcbfcbd3710c9b5aa70051d /src
parent1ce4c6398ea453a66f6943552b0ec866a690e9b1 (diff)
parente687aa335a21662f67d2d73063272504a171ffab (diff)
merge from trunk
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog121
-rw-r--r--src/alloc.c12
-rw-r--r--src/callproc.c104
-rw-r--r--src/character.c14
-rw-r--r--src/dispextern.h63
-rw-r--r--src/dispnew.c58
-rw-r--r--src/fileio.c118
-rw-r--r--src/frame.h10
-rw-r--r--src/gtkutil.c11
-rw-r--r--src/lisp.h1
-rw-r--r--src/nsterm.m8
-rw-r--r--src/process.c72
-rw-r--r--src/process.h1
-rw-r--r--src/sysdep.c113
-rw-r--r--src/w32.c29
-rw-r--r--src/w32term.c9
-rw-r--r--src/window.c2
-rw-r--r--src/xdisp.c38
-rw-r--r--src/xterm.c9
19 files changed, 466 insertions, 327 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index e21d82bdc09..70d722a02a4 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,124 @@
+2013-08-24 Eli Zaretskii <eliz@gnu.org>
+
+ * xdisp.c (get_next_display_element): Don't apply to characters
+ from a display vector the logic of setting it->end_of_box_run_p
+ suitable for characters from a buffer. (Bug#15175)
+
+ * w32.c (fdutimens): Call 'utime', which is implemented on w32.c
+ to handle directories, rather than '_utime' which doesn't.
+ (Bug#15176)
+
+2013-08-24 Jan Djärv <jan.h.d@swipnet.se>
+
+ * gtkutil.c (x_wm_set_size_hint): Don't set hints when maximized
+ or fullscreen (Bug#14627).
+
+2013-08-24 Paul Eggert <eggert@cs.ucla.edu>
+
+ System-dependent integer overflow fixes.
+ * process.c (Fset_process_window_size): Signal an error if
+ the window size is outside the range supported by the lower level.
+ * sysdep.c (set_window_size): Return negative on error,
+ nonnegative on success, rather than -1, 0, 1 on not in system,
+ failure, success. This is simpler. Caller changed.
+ (serial_configure): Remove unnecessary initialization of local.
+ (procfs_get_total_memory) [GNU_LINUX]: Don't assume system memory
+ size fits in unsigned long; this isn't true on some 32-bit hosts.
+ Avoid buffer overrun if some future version of /proc/meminfo has a
+ variable name longer than 20 bytes.
+ (system_process_attributes) [__FreeBSD__]:
+ Don't assume hw.availpages fits in 'int'.
+
+2013-08-23 Paul Eggert <eggert@cs.ucla.edu>
+
+ Don't let very long directory names overrun the stack.
+ Fix some related minor problems involving "//", vfork.
+ * callproc.c (encode_current_directory): New function.
+ (call_process): Don't append "/"; not needed.
+ * fileio.c (file_name_as_directory_slop): New constant.
+ (file_name_as_directory): Allow SRC to be longer than SRCLEN;
+ this can save the caller having to alloca.
+ (Ffile_name_as_directory, Fdirectory_file_name, Fexpand_file_name):
+ Use SAFE_ALLOCA, not alloca.
+ (directory_file_name, Fexpand_file_name): Leave leading "//"
+ alone, since it can be special even on POSIX platforms.
+ * callproc.c (call_process):
+ * process.c (Fformat_network_address):
+ * sysdep.c (sys_subshell):
+ Use encode_current_directory rather than rolling our own.
+ (create_process): No need to encode directory; caller does that now.
+ * process.h (encode_current_directory): New decl.
+ * sysdep.c (sys_subshell): Work even if vfork trashes saved_handlers.
+ Rework to avoid 'goto xyzzy;'.
+
+2013-08-23 Eli Zaretskii <eliz@gnu.org>
+
+ * xdisp.c (handle_face_prop): If the default face was remapped use
+ the remapped face for strings from prefix properties. (Bug#15155)
+
+2013-08-23 Dmitry Antipov <dmantipov@yandex.ru>
+
+ Minor cleanup for redisplay interface and few related functions.
+ * frame.h (enum text_cursor_kinds): Move from here...
+ * dispextern.h (enum text_cursor_kinds): ...to here.
+ (toplevel): Drop unnecessary declarations.
+ (struct redisplay_interface): Use bool and enum text_cursor_kinds
+ in update_window_end_hook and draw_window_cursor functions.
+ (display_and_set_cursor, x_update_cursor): Adjust prototypes.
+ * nsterm.m (ns_update_window_end, ns_draw_window_cursor):
+ * w32term.c (x_update_window_end,w32_draw_window_cursor):
+ * xterm.c (x_update_window_end, x_draw_window_cursor):
+ * xdisp.c (display_and_set_cursor, update_window_cursor)
+ (update_cursor_in_window_tree, x_update_cursor): Use bool and
+ enum text_cursor_kinds where appropriate.
+
+2013-08-23 Dmitry Antipov <dmantipov@yandex.ru>
+
+ Redesign redisplay interface to drop updated_row and updated_area.
+ * dispextern.h (updated_row, updated_area): Remove declaration.
+ (struct redisplay_interface): Pass glyph row and row area parameters
+ to write_glyphs, insert_glyphs and clear_end_of_line functions.
+ (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line):
+ Adjust prototypes.
+ * dispnew.c (updated_row, updated_area): Remove.
+ (redraw_overlapped_rows, update_window_line): Adjust user.
+ (update_marginal_area, update_text_area): Likewise. Pass updated row
+ as a parameter. Prefer enum glyph_row_area to int where appropriate.
+ * xdisp.c (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line):
+ Adjust users.
+
+2013-08-22 Paul Eggert <eggert@cs.ucla.edu>
+
+ * process.c (flush_pending_output): Remove stub.
+ All uses removed.
+
+2013-08-21 Paul Eggert <eggert@cs.ucla.edu>
+
+ * callproc.c: Fix race that killed background processes (Bug#15144).
+ (call_process): New arg TEMPFILE_INDEX. Callers changed.
+ Record deleted process-id in critical section, not afterwards.
+ Don't mistakenly kill process created by a call-process invocation
+ that discards output and does not wait.
+
+2013-08-21 Dmitry Antipov <dmantipov@yandex.ru>
+
+ Fix compilation with GC_MARK_STACK == GC_USE_GCPROS_AS_BEFORE
+ and GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES.
+ * alloc.c (toplevel): Remove unnecessary nested #if...#endif.
+ (mark_maybe_object) [!GC_MARK_STACK]: Define to emacs_abort
+ to shut up compiler in mark_object.
+ (dump_zombies): Convert to global and add EXTERNALLY_VISIBLE.
+
+2013-08-21 Paul Eggert <eggert@cs.ucla.edu>
+
+ * process.c (allocate_pty) [PTY_OPEN]: Set fd's FD_CLOEXEC flag.
+ We can't portably rely on PTY_OPEN doing that, even if
+ it calls posix_openpt with O_CLOEXEC.
+
+2013-08-20 Kenichi Handa <handa@gnu.org>
+
+ * character.c (string_char): Improve commentary.
+
2013-08-20 Paul Eggert <eggert@cs.ucla.edu>
* image.c (SIGNATURE_DIGESTSIZE): Remove.
diff --git a/src/alloc.c b/src/alloc.c
index 4cc9b3e1a13..9b5f2955aa5 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -314,7 +314,6 @@ static void *min_heap_address, *max_heap_address;
static struct mem_node mem_z;
#define MEM_NIL &mem_z
-#if GC_MARK_STACK || defined GC_MALLOC_CHECK
static struct mem_node *mem_insert (void *, void *, enum mem_type);
static void mem_insert_fixup (struct mem_node *);
static void mem_rotate_left (struct mem_node *);
@@ -322,7 +321,6 @@ static void mem_rotate_right (struct mem_node *);
static void mem_delete (struct mem_node *);
static void mem_delete_fixup (struct mem_node *);
static struct mem_node *mem_find (void *);
-#endif
#endif /* GC_MARK_STACK || GC_MALLOC_CHECK */
@@ -4237,6 +4235,10 @@ live_buffer_p (struct mem_node *m, void *p)
#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
+/* Currently not used, but may be called from gdb. */
+
+void dump_zombies (void) EXTERNALLY_VISIBLE;
+
/* Array of objects that are kept alive because the C stack contains
a pattern that looks like a reference to them . */
@@ -4619,7 +4621,7 @@ check_gcpros (void)
#elif GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
-static void
+void
dump_zombies (void)
{
int i;
@@ -4766,6 +4768,10 @@ flush_stack_call_func (void (*func) (void *arg), void *arg)
eassert (current_thread == self);
}
+#else /* GC_MARK_STACK == 0 */
+
+#define mark_maybe_object(obj) emacs_abort ()
+
#endif /* GC_MARK_STACK != 0 */
diff --git a/src/callproc.c b/src/callproc.c
index 2a9162cb5cc..d4b4a26ec3a 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -102,7 +102,7 @@ enum
CALLPROC_FDS
};
-static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int);
+static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int, ptrdiff_t);
/* Block SIGCHLD. */
@@ -123,6 +123,37 @@ unblock_child_signal (void)
pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
}
+/* Return the current buffer's working directory, or the home
+ directory if it's unreachable, as a string suitable for a system call.
+ Signal an error if the result would not be an accessible directory. */
+
+Lisp_Object
+encode_current_directory (void)
+{
+ Lisp_Object dir;
+ struct gcpro gcpro1;
+
+ dir = BVAR (current_buffer, directory);
+ GCPRO1 (dir);
+
+ dir = Funhandled_file_name_directory (dir);
+
+ /* If the file name handler says that dir is unreachable, use
+ a sensible default. */
+ if (NILP (dir))
+ dir = build_string ("~");
+
+ dir = expand_and_dir_to_file (dir, Qnil);
+
+ if (STRING_MULTIBYTE (dir))
+ dir = ENCODE_FILE (dir);
+ if (! file_accessible_directory_p (SSDATA (dir)))
+ report_file_error ("Setting current directory",
+ BVAR (current_buffer, directory));
+
+ RETURN_UNGCPRO (dir);
+}
+
/* If P is reapable, record it as a deleted process and kill it.
Do this in a critical section. Unless PID is wedged it will be
reaped on receipt of the first SIGCHLD after the critical section. */
@@ -248,14 +279,20 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
report_file_error ("Opening process input file", infile);
record_unwind_protect_int (close_file_unwind, filefd);
UNGCPRO;
- return unbind_to (count, call_process (nargs, args, filefd));
+ return unbind_to (count, call_process (nargs, args, filefd, -1));
}
/* Like Fcall_process (NARGS, ARGS), except use FILEFD as the input file.
+
+ If TEMPFILE_INDEX is nonnegative, it is the specpdl index of an
+ unwinder that is intended to remove the input temporary file; in
+ this case NARGS must be at least 2 and ARGS[1] is the file's name.
+
At entry, the specpdl stack top entry must be close_file_unwind (FILEFD). */
static Lisp_Object
-call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd)
+call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
+ ptrdiff_t tempfile_index)
{
Lisp_Object buffer, current_dir, path;
bool display_p;
@@ -402,24 +439,10 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd)
{
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
- current_dir = BVAR (current_buffer, directory);
+ current_dir = encode_current_directory ();
GCPRO4 (buffer, current_dir, error_file, output_file);
- current_dir = Funhandled_file_name_directory (current_dir);
- if (NILP (current_dir))
- /* If the file name handler says that current_dir is unreachable, use
- a sensible default. */
- current_dir = build_string ("~/");
- current_dir = expand_and_dir_to_file (current_dir, Qnil);
- current_dir = Ffile_name_as_directory (current_dir);
-
- if (NILP (Ffile_accessible_directory_p (current_dir)))
- report_file_error ("Setting current directory",
- BVAR (current_buffer, directory));
-
- if (STRING_MULTIBYTE (current_dir))
- current_dir = ENCODE_FILE (current_dir);
if (STRINGP (error_file) && STRING_MULTIBYTE (error_file))
error_file = ENCODE_FILE (error_file);
if (STRINGP (output_file) && STRING_MULTIBYTE (output_file))
@@ -661,7 +684,22 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd)
child_errno = errno;
if (pid > 0)
- synch_process_pid = pid;
+ {
+ synch_process_pid = pid;
+
+ if (INTEGERP (buffer))
+ {
+ if (tempfile_index < 0)
+ record_deleted_pid (pid, Qnil);
+ else
+ {
+ eassert (1 < nargs);
+ record_deleted_pid (pid, args[1]);
+ clear_unwind_protect (tempfile_index);
+ }
+ synch_process_pid = 0;
+ }
+ }
unblock_child_signal ();
unblock_input ();
@@ -1030,7 +1068,7 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.
usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS) */)
(ptrdiff_t nargs, Lisp_Object *args)
{
- struct gcpro gcpro1, gcpro2;
+ struct gcpro gcpro1;
Lisp_Object infile, val;
ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object start = args[0];
@@ -1061,8 +1099,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
record_unwind_protect_int (close_file_unwind, fd);
}
- val = infile;
- GCPRO2 (infile, val);
+ GCPRO1 (infile);
if (nargs > 3 && !NILP (args[3]))
Fdelete_region (start, end);
@@ -1079,16 +1116,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
}
args[1] = infile;
- val = call_process (nargs, args, fd);
-
- if (!empty_input && 4 < nargs
- && (INTEGERP (CONSP (args[4]) ? XCAR (args[4]) : args[4])))
- {
- record_deleted_pid (synch_process_pid, infile);
- synch_process_pid = 0;
- clear_unwind_protect (count);
- }
-
+ val = call_process (nargs, args, fd, empty_input ? -1 : count);
RETURN_UNGCPRO (unbind_to (count, val));
}
@@ -1165,23 +1193,21 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
static variables as if the superior had done alloca and will be
cleaned up in the usual way. */
{
- register char *temp;
- size_t i; /* size_t, because ptrdiff_t might overflow here! */
+ char *temp;
+ ptrdiff_t i;
i = SBYTES (current_dir);
#ifdef MSDOS
/* MSDOS must have all environment variables malloc'ed, because
low-level libc functions that launch subsidiary processes rely
on that. */
- pwd_var = xmalloc (i + 6);
+ pwd_var = xmalloc (i + 5);
#else
- pwd_var = alloca (i + 6);
+ pwd_var = alloca (i + 5);
#endif
temp = pwd_var + 4;
memcpy (pwd_var, "PWD=", 4);
- memcpy (temp, SDATA (current_dir), i);
- if (!IS_DIRECTORY_SEP (temp[i - 1])) temp[i++] = DIRECTORY_SEP;
- temp[i] = 0;
+ strcpy (temp, SSDATA (current_dir));
#ifndef DOS_NT
/* We can't signal an Elisp error here; we're in a vfork. Since
diff --git a/src/character.c b/src/character.c
index b2caaa290af..1bde2364e37 100644
--- a/src/character.c
+++ b/src/character.c
@@ -174,11 +174,14 @@ string_char (const unsigned char *p, const unsigned char **advanced, int *len)
if (*p < 0x80 || ! (*p & 0x20) || ! (*p & 0x10))
{
+ /* 1-, 2-, and 3-byte sequences can be handled by the macro. */
c = STRING_CHAR_ADVANCE (p);
}
else if (! (*p & 0x08))
{
- c = ((((p)[0] & 0xF) << 18)
+ /* A 4-byte sequence of this form:
+ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
+ c = ((((p)[0] & 0x7) << 18)
| (((p)[1] & 0x3F) << 12)
| (((p)[2] & 0x3F) << 6)
| ((p)[3] & 0x3F));
@@ -186,7 +189,14 @@ string_char (const unsigned char *p, const unsigned char **advanced, int *len)
}
else
{
- c = ((((p)[1] & 0x3F) << 18)
+ /* A 5-byte sequence of this form:
+
+ 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+
+ Note that the top 4 `x's are always 0, so shifting p[1] can
+ never exceed the maximum valid character codepoint. */
+ c = (/* (((p)[0] & 0x3) << 24) ... always 0, so no need to shift. */
+ (((p)[1] & 0x3F) << 18)
| (((p)[2] & 0x3F) << 12)
| (((p)[3] & 0x3F) << 6)
| ((p)[4] & 0x3F));
diff --git a/src/dispextern.h b/src/dispextern.h
index 7a4fa2ea774..6e1d85de924 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -95,18 +95,17 @@ typedef int Cursor;
#define NativeRectangle int
#endif
-/* Structure forward declarations. Some are here because function
- prototypes below reference structure types before their definition
- in this file. Some are here because not every file including
- dispextern.h also includes frame.h and windows.h. */
-
-struct glyph;
-struct glyph_row;
-struct glyph_matrix;
-struct glyph_pool;
-struct frame;
-struct window;
+/* Text cursor types. */
+enum text_cursor_kinds
+{
+ DEFAULT_CURSOR = -2,
+ NO_CURSOR = -1,
+ FILLED_BOX_CURSOR,
+ HOLLOW_BOX_CURSOR,
+ BAR_CURSOR,
+ HBAR_CURSOR
+};
/* Values returned from coordinates_in_window. */
@@ -1197,11 +1196,6 @@ extern bool fonts_changed_p;
extern struct glyph space_glyph;
-/* Glyph row and area updated by update_window_line. */
-
-extern struct glyph_row *updated_row;
-extern int updated_area;
-
/* Non-zero means last display completed. Zero means it was
preempted. */
@@ -2713,12 +2707,17 @@ struct redisplay_interface
/* Write or insert LEN glyphs from STRING at the nominal output
position. */
- void (*write_glyphs) (struct window *w, struct glyph *string, int len);
- void (*insert_glyphs) (struct window *w, struct glyph *start, int len);
+ void (*write_glyphs) (struct window *w, struct glyph_row *row,
+ struct glyph *string, enum glyph_row_area area,
+ int len);
+ void (*insert_glyphs) (struct window *w, struct glyph_row *row,
+ struct glyph *start, enum glyph_row_area area,
+ int len);
/* Clear from nominal output position to X. X < 0 means clear
to right end of display. */
- void (*clear_end_of_line) (struct window *w, int x);
+ void (*clear_end_of_line) (struct window *w, struct glyph_row *row,
+ enum glyph_row_area area, int x);
/* Function to call to scroll the display as described by RUN on
window W. */
@@ -2739,8 +2738,8 @@ struct redisplay_interface
MOUSE_FACE_OVERWRITTEN_P non-zero means that some lines in W
that contained glyphs in mouse-face were overwritten, so we
have to update the mouse highlight. */
- void (*update_window_end_hook) (struct window *w, int cursor_on_p,
- int mouse_face_overwritten_p);
+ void (*update_window_end_hook) (struct window *w, bool cursor_on_p,
+ bool mouse_face_overwritten_p);
/* Move cursor to row/column position VPOS/HPOS, pixel coordinates
Y/X. HPOS/VPOS are window-relative row and column numbers and X/Y
@@ -2799,10 +2798,10 @@ struct redisplay_interface
0, don't draw cursor. If ACTIVE_P is 1, system caret
should track this cursor (when applicable). */
void (*draw_window_cursor) (struct window *w,
- struct glyph_row *glyph_row,
- int x, int y,
- int cursor_type, int cursor_width,
- int on_p, int active_p);
+ struct glyph_row *glyph_row,
+ int x, int y,
+ enum text_cursor_kinds cursor_type,
+ int cursor_width, bool on_p, bool active_p);
/* Draw vertical border for window W from (X,Y_0) to (X,Y_1). */
void (*draw_vertical_window_border) (struct window *w,
@@ -3178,9 +3177,12 @@ extern void x_get_glyph_overhangs (struct glyph *, struct frame *,
int *, int *);
extern void x_produce_glyphs (struct it *);
-extern void x_write_glyphs (struct window *, struct glyph *, int);
-extern void x_insert_glyphs (struct window *, struct glyph *, int len);
-extern void x_clear_end_of_line (struct window *, int);
+extern void x_write_glyphs (struct window *, struct glyph_row *,
+ struct glyph *, enum glyph_row_area, int);
+extern void x_insert_glyphs (struct window *, struct glyph_row *,
+ struct glyph *, enum glyph_row_area, int);
+extern void x_clear_end_of_line (struct window *, struct glyph_row *,
+ enum glyph_row_area, int);
extern struct cursor_pos output_cursor;
@@ -3192,13 +3194,12 @@ extern void draw_phys_cursor_glyph (struct window *,
extern void get_phys_cursor_geometry (struct window *, struct glyph_row *,
struct glyph *, int *, int *, int *);
extern void erase_phys_cursor (struct window *);
-extern void display_and_set_cursor (struct window *,
- int, int, int, int, int);
+extern void display_and_set_cursor (struct window *, bool, int, int, int, int);
extern void set_output_cursor (struct cursor_pos *);
extern void x_cursor_to (struct window *, int, int, int, int);
-extern void x_update_cursor (struct frame *, int);
+extern void x_update_cursor (struct frame *, bool);
extern void x_clear_cursor (struct window *);
extern void x_draw_vertical_border (struct window *w);
diff --git a/src/dispnew.c b/src/dispnew.c
index b7e44e425bf..3c6b89bde68 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -135,11 +135,6 @@ struct frame *last_nonminibuf_frame;
static bool delayed_size_change;
-/* Glyph row updated in update_window_line, and area that is updated. */
-
-struct glyph_row *updated_row;
-int updated_area;
-
/* A glyph for a space. */
struct glyph space_glyph;
@@ -3230,14 +3225,12 @@ redraw_overlapped_rows (struct window *w, int yb)
for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
{
- updated_row = row;
- updated_area = area;
FRAME_RIF (f)->cursor_to (w, i, 0, row->y,
area == TEXT_AREA ? row->x : 0);
if (row->used[area])
- FRAME_RIF (f)->write_glyphs (w, row->glyphs[area],
- row->used[area]);
- FRAME_RIF (f)->clear_end_of_line (w, -1);
+ FRAME_RIF (f)->write_glyphs (w, row, row->glyphs[area],
+ area, row->used[area]);
+ FRAME_RIF (f)->clear_end_of_line (w, row, area, -1);
}
row->overlapped_p = 0;
@@ -3511,22 +3504,20 @@ update_window (struct window *w, bool force_p)
AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA. */
static void
-update_marginal_area (struct window *w, int area, int vpos)
+update_marginal_area (struct window *w, struct glyph_row *updated_row,
+ enum glyph_row_area area, int vpos)
{
struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
- /* Let functions in xterm.c know what area subsequent X positions
- will be relative to. */
- updated_area = area;
-
/* Set cursor to start of glyphs, write them, and clear to the end
of the area. I don't think that something more sophisticated is
necessary here, since marginal areas will not be the default. */
rif->cursor_to (w, vpos, 0, desired_row->y, 0);
if (desired_row->used[area])
- rif->write_glyphs (w, desired_row->glyphs[area], desired_row->used[area]);
- rif->clear_end_of_line (w, -1);
+ rif->write_glyphs (w, updated_row, desired_row->glyphs[area],
+ area, desired_row->used[area]);
+ rif->clear_end_of_line (w, updated_row, area, -1);
}
@@ -3534,17 +3525,13 @@ update_marginal_area (struct window *w, int area, int vpos)
Value is true if display has changed. */
static bool
-update_text_area (struct window *w, int vpos)
+update_text_area (struct window *w, struct glyph_row *updated_row, int vpos)
{
struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
bool changed_p = 0;
- /* Let functions in xterm.c know what area subsequent X positions
- will be relative to. */
- updated_area = TEXT_AREA;
-
/* If rows are at different X or Y, or rows have different height,
or the current row is marked invalid, write the entire line. */
if (!current_row->enabled_p
@@ -3567,11 +3554,11 @@ update_text_area (struct window *w, int vpos)
rif->cursor_to (w, vpos, 0, desired_row->y, desired_row->x);
if (desired_row->used[TEXT_AREA])
- rif->write_glyphs (w, desired_row->glyphs[TEXT_AREA],
- desired_row->used[TEXT_AREA]);
+ rif->write_glyphs (w, updated_row, desired_row->glyphs[TEXT_AREA],
+ TEXT_AREA, desired_row->used[TEXT_AREA]);
/* Clear to end of window. */
- rif->clear_end_of_line (w, -1);
+ rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
changed_p = 1;
/* This erases the cursor. We do this here because
@@ -3708,7 +3695,8 @@ update_text_area (struct window *w, int vpos)
}
rif->cursor_to (w, vpos, start_hpos, desired_row->y, start_x);
- rif->write_glyphs (w, start, i - start_hpos);
+ rif->write_glyphs (w, updated_row, start,
+ TEXT_AREA, i - start_hpos);
changed_p = 1;
}
}
@@ -3717,7 +3705,8 @@ update_text_area (struct window *w, int vpos)
if (i < desired_row->used[TEXT_AREA])
{
rif->cursor_to (w, vpos, i, desired_row->y, x);
- rif->write_glyphs (w, desired_glyph, desired_row->used[TEXT_AREA] - i);
+ rif->write_glyphs (w, updated_row, desired_glyph,
+ TEXT_AREA, desired_row->used[TEXT_AREA] - i);
changed_p = 1;
}
@@ -3739,7 +3728,7 @@ update_text_area (struct window *w, int vpos)
if (i >= desired_row->used[TEXT_AREA])
rif->cursor_to (w, vpos, i, desired_row->y,
desired_row->pixel_width);
- rif->clear_end_of_line (w, -1);
+ rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
changed_p = 1;
}
else if (desired_row->pixel_width < current_row->pixel_width)
@@ -3767,7 +3756,7 @@ update_text_area (struct window *w, int vpos)
}
else
xlim = current_row->pixel_width;
- rif->clear_end_of_line (w, xlim);
+ rif->clear_end_of_line (w, updated_row, TEXT_AREA, xlim);
changed_p = 1;
}
}
@@ -3786,10 +3775,6 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
bool changed_p = 0;
- /* Set the row being updated. This is important to let xterm.c
- know what line height values are in effect. */
- updated_row = desired_row;
-
/* A row can be completely invisible in case a desired matrix was
built with a vscroll and then make_cursor_line_fully_visible shifts
the matrix. Make sure to make such rows current anyway, since
@@ -3803,7 +3788,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
if (!desired_row->full_width_p && w->left_margin_cols > 0)
{
changed_p = 1;
- update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
+ update_marginal_area (w, desired_row, LEFT_MARGIN_AREA, vpos);
/* Setting this flag will ensure the vertical border, if
any, between this window and the one on its left will be
redrawn. This is necessary because updating the left
@@ -3812,7 +3797,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
}
/* Update the display of the text area. */
- if (update_text_area (w, vpos))
+ if (update_text_area (w, desired_row, vpos))
{
changed_p = 1;
if (current_row->mouse_face_p)
@@ -3823,7 +3808,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
if (!desired_row->full_width_p && w->right_margin_cols > 0)
{
changed_p = 1;
- update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
+ update_marginal_area (w, desired_row, RIGHT_MARGIN_AREA, vpos);
}
/* Draw truncation marks etc. */
@@ -3842,7 +3827,6 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
/* Update current_row from desired_row. */
make_current (w->desired_matrix, w->current_matrix, vpos);
- updated_row = NULL;
return changed_p;
}
diff --git a/src/fileio.c b/src/fileio.c
index 08caf102266..7cad8d29da2 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -504,6 +504,10 @@ get a current directory to run processes in. */)
return Ffile_name_directory (filename);
}
+/* Maximum number of bytes that DST will be longer than SRC
+ in file_name_as_directory. This occurs when SRCLEN == 0. */
+enum { file_name_as_directory_slop = 2 };
+
/* Convert from file name SRC of length SRCLEN to directory name in
DST. MULTIBYTE non-zero means the file name in SRC is a multibyte
string. On UNIX, just make sure there is a terminating /. Return
@@ -521,14 +525,10 @@ file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen,
return 2;
}
- strcpy (dst, src);
-
+ memcpy (dst, src, srclen);
if (!IS_DIRECTORY_SEP (dst[srclen - 1]))
- {
- dst[srclen] = DIRECTORY_SEP;
- dst[srclen + 1] = '\0';
- srclen++;
- }
+ dst[srclen++] = DIRECTORY_SEP;
+ dst[srclen] = 0;
#ifdef DOS_NT
dostounix_filename (dst, multibyte);
#endif
@@ -547,7 +547,8 @@ For a Unix-syntax file name, just appends a slash. */)
{
char *buf;
ptrdiff_t length;
- Lisp_Object handler;
+ Lisp_Object handler, val;
+ USE_SAFE_ALLOCA;
CHECK_STRING (file);
if (NILP (file))
@@ -569,10 +570,12 @@ For a Unix-syntax file name, just appends a slash. */)
if (!NILP (Vw32_downcase_file_names))
file = Fdowncase (file);
#endif
- buf = alloca (SBYTES (file) + 10);
+ buf = SAFE_ALLOCA (SBYTES (file) + file_name_as_directory_slop + 1);
length = file_name_as_directory (buf, SSDATA (file), SBYTES (file),
STRING_MULTIBYTE (file));
- return make_specified_string (buf, -1, length, STRING_MULTIBYTE (file));
+ val = make_specified_string (buf, -1, length, STRING_MULTIBYTE (file));
+ SAFE_FREE ();
+ return val;
}
/* Convert from directory name SRC of length SRCLEN to file name in
@@ -584,18 +587,17 @@ static ptrdiff_t
directory_file_name (char *dst, char *src, ptrdiff_t srclen, bool multibyte)
{
/* Process as Unix format: just remove any final slash.
- But leave "/" unchanged; do not change it to "". */
- strcpy (dst, src);
- if (srclen > 1
- && IS_DIRECTORY_SEP (dst[srclen - 1])
+ But leave "/" and "//" unchanged. */
+ while (srclen > 1
#ifdef DOS_NT
- && !IS_ANY_SEP (dst[srclen - 2])
+ && !IS_ANY_SEP (src[srclen - 2])
#endif
- )
- {
- dst[srclen - 1] = 0;
- srclen--;
- }
+ && IS_DIRECTORY_SEP (src[srclen - 1])
+ && ! (srclen == 2 && IS_DIRECTORY_SEP (src[0])))
+ srclen--;
+
+ memcpy (dst, src, srclen);
+ dst[srclen] = 0;
#ifdef DOS_NT
dostounix_filename (dst, multibyte);
#endif
@@ -613,7 +615,8 @@ In Unix-syntax, this function just removes the final slash. */)
{
char *buf;
ptrdiff_t length;
- Lisp_Object handler;
+ Lisp_Object handler, val;
+ USE_SAFE_ALLOCA;
CHECK_STRING (directory);
@@ -636,10 +639,12 @@ In Unix-syntax, this function just removes the final slash. */)
if (!NILP (Vw32_downcase_file_names))
directory = Fdowncase (directory);
#endif
- buf = alloca (SBYTES (directory) + 20);
+ buf = SAFE_ALLOCA (SBYTES (directory) + 1);
length = directory_file_name (buf, SSDATA (directory), SBYTES (directory),
STRING_MULTIBYTE (directory));
- return make_specified_string (buf, -1, length, STRING_MULTIBYTE (directory));
+ val = make_specified_string (buf, -1, length, STRING_MULTIBYTE (directory));
+ SAFE_FREE ();
+ return val;
}
static const char make_temp_name_tbl[64] =
@@ -837,6 +842,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
Lisp_Object handler, result, handled_name;
bool multibyte;
Lisp_Object hdir;
+ USE_SAFE_ALLOCA;
CHECK_STRING (name);
@@ -1011,11 +1017,11 @@ filesystem tree, not (expand-file-name ".." dirname). */)
|| (p[2] == '.' && (IS_DIRECTORY_SEP (p[3])
|| p[3] == 0))))
lose = 1;
- /* We want to replace multiple `/' in a row with a single
- slash. */
- else if (p > nm
- && IS_DIRECTORY_SEP (p[0])
- && IS_DIRECTORY_SEP (p[1]))
+ /* Replace multiple slashes with a single one, except
+ leave leading "//" alone. */
+ else if (IS_DIRECTORY_SEP (p[0])
+ && IS_DIRECTORY_SEP (p[1])
+ && (p != nm || IS_DIRECTORY_SEP (p[2])))
lose = 1;
p++;
}
@@ -1098,10 +1104,11 @@ filesystem tree, not (expand-file-name ".." dirname). */)
else /* ~user/filename */
{
char *o, *p;
- for (p = nm; *p && (!IS_DIRECTORY_SEP (*p)); p++);
- o = alloca (p - nm + 1);
+ for (p = nm; *p && !IS_DIRECTORY_SEP (*p); p++)
+ continue;
+ o = SAFE_ALLOCA (p - nm + 1);
memcpy (o, nm, p - nm);
- o [p - nm] = 0;
+ o[p - nm] = 0;
block_input ();
pw = getpwnam (o + 1);
@@ -1217,7 +1224,8 @@ filesystem tree, not (expand-file-name ".." dirname). */)
if (!IS_DIRECTORY_SEP (nm[0]))
{
ptrdiff_t newlen = strlen (newdir);
- char *tmp = alloca (newlen + strlen (nm) + 2);
+ char *tmp = alloca (newlen + file_name_as_directory_slop
+ + strlen (nm) + 1);
file_name_as_directory (tmp, newdir, newlen, multibyte);
strcat (tmp, nm);
nm = tmp;
@@ -1271,31 +1279,18 @@ filesystem tree, not (expand-file-name ".." dirname). */)
if (newdir)
{
- /* Get rid of any slash at the end of newdir, unless newdir is
- just / or // (an incomplete UNC name). */
+ /* Ignore any slash at the end of newdir, unless newdir is
+ just "/" or "//". */
length = strlen (newdir);
- tlen = length + 1;
- if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1])
-#ifdef WINDOWSNT
- && !(length == 2 && IS_DIRECTORY_SEP (newdir[0]))
-#endif
- )
- {
- char *temp = alloca (length);
- memcpy (temp, newdir, length - 1);
- temp[length - 1] = 0;
- length--;
- newdir = temp;
- }
+ while (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1])
+ && ! (length == 2 && IS_DIRECTORY_SEP (newdir[0])))
+ length--;
}
else
- {
- length = 0;
- tlen = 0;
- }
+ length = 0;
/* Now concatenate the directory and name to new space in the stack frame. */
- tlen += strlen (nm) + 1;
+ tlen = length + file_name_as_directory_slop + strlen (nm) + 1;
#ifdef DOS_NT
/* Reserve space for drive specifier and escape prefix, since either
or both may need to be inserted. (The Microsoft x86 compiler
@@ -1303,7 +1298,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
target = alloca (tlen + 4);
target += 4;
#else /* not DOS_NT */
- target = alloca (tlen);
+ target = SAFE_ALLOCA (tlen);
#endif /* not DOS_NT */
*target = 0;
@@ -1320,7 +1315,10 @@ filesystem tree, not (expand-file-name ".." dirname). */)
if (!(drive && nm[0] && IS_DIRECTORY_SEP (newdir[0])
&& newdir[1] == '\0'))
#endif
- strcpy (target, newdir);
+ {
+ memcpy (target, newdir, length);
+ target[length] = 0;
+ }
}
else
file_name_as_directory (target, newdir, length, multibyte);
@@ -1380,8 +1378,9 @@ filesystem tree, not (expand-file-name ".." dirname). */)
++o;
p += 3;
}
- else if (p > target && IS_DIRECTORY_SEP (p[1]))
- /* Collapse multiple `/' in a row. */
+ else if (IS_DIRECTORY_SEP (p[1])
+ && (p != target || IS_DIRECTORY_SEP (p[2])))
+ /* Collapse multiple "/", except leave leading "//" alone. */
p++;
else
{
@@ -1429,11 +1428,12 @@ filesystem tree, not (expand-file-name ".." dirname). */)
{
handled_name = call3 (handler, Qexpand_file_name,
result, default_directory);
- if (STRINGP (handled_name))
- return handled_name;
- error ("Invalid handler in `file-name-handler-alist'");
+ if (! STRINGP (handled_name))
+ error ("Invalid handler in `file-name-handler-alist'");
+ result = handled_name;
}
+ SAFE_FREE ();
return result;
}
diff --git a/src/frame.h b/src/frame.h
index e44003b15ca..2dcb7562524 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -56,16 +56,6 @@ enum vertical_scroll_bar_type
vertical_scroll_bar_right
};
-enum text_cursor_kinds
-{
- DEFAULT_CURSOR = -2,
- NO_CURSOR = -1,
- FILLED_BOX_CURSOR,
- HOLLOW_BOX_CURSOR,
- BAR_CURSOR,
- HBAR_CURSOR
-};
-
enum fullscreen_type
{
FULLSCREEN_NONE,
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 7e304d417d8..8e255ac4bfb 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1341,6 +1341,7 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
int base_width, base_height;
int min_rows = 0, min_cols = 0;
int win_gravity = f->win_gravity;
+ Lisp_Object fs_state, frame;
/* Don't set size hints during initialization; that apparently leads
to a race condition. See the thread at
@@ -1348,6 +1349,16 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
if (NILP (Vafter_init_time) || !FRAME_GTK_OUTER_WIDGET (f))
return;
+ XSETFRAME (frame, f);
+ fs_state = Fframe_parameter (frame, Qfullscreen);
+ if (EQ (fs_state, Qmaximized) || EQ (fs_state, Qfullboth))
+ {
+ /* Don't set hints when maximized or fullscreen. Apparently KWin and
+ Gtk3 don't get along and the frame shrinks (!).
+ */
+ return;
+ }
+
if (flags)
{
memset (&size_hints, 0, sizeof (size_hints));
diff --git a/src/lisp.h b/src/lisp.h
index 60a553cc7d1..51c09e0abb3 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4177,7 +4177,6 @@ extern void init_sys_modes (struct tty_display_info *);
extern void reset_sys_modes (struct tty_display_info *);
extern void init_all_sys_modes (void);
extern void reset_all_sys_modes (void);
-extern void flush_pending_output (int) ATTRIBUTE_CONST;
extern void child_setup_tty (int);
extern void setup_pty (int);
extern int set_window_size (int, int, int);
diff --git a/src/nsterm.m b/src/nsterm.m
index f374bfd90c6..287c119ba73 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -742,8 +742,8 @@ ns_update_window_begin (struct window *w)
static void
-ns_update_window_end (struct window *w, int cursor_on_p,
- int mouse_face_overwritten_p)
+ns_update_window_end (struct window *w, bool cursor_on_p,
+ bool mouse_face_overwritten_p)
/* --------------------------------------------------------------------------
Finished a grouped sequence of drawing calls
external (RIF) call; for one window called before update_end
@@ -2341,8 +2341,8 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
static void
ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
- int x, int y, int cursor_type, int cursor_width,
- int on_p, int active_p)
+ int x, int y, enum text_cursor_kinds cursor_type,
+ int cursor_width, bool on_p, bool active_p)
/* --------------------------------------------------------------------------
External call (RIF): draw cursor.
Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
diff --git a/src/process.c b/src/process.c
index 1d1741d8b7e..3edc3b4f061 100644
--- a/src/process.c
+++ b/src/process.c
@@ -826,6 +826,15 @@ allocate_pty (char pty_name[PTY_NAME_SIZE])
if (fd >= 0)
{
+#ifdef PTY_OPEN
+ /* Set FD's close-on-exec flag. This is needed even if
+ PT_OPEN calls posix_openpt with O_CLOEXEC, since POSIX
+ doesn't require support for that combination.
+ Multithreaded platforms where posix_openpt ignores
+ O_CLOEXEC (or where PTY_OPEN doesn't call posix_openpt)
+ have a race condition between the PTY_OPEN and here. */
+ fcntl (fd, F_SETFD, FD_CLOEXEC);
+#endif
/* check to make certain that both sides are available
this avoids a nasty yet stupid bug in rlogins */
#ifdef PTY_TTY_NAME_SPRINTF
@@ -1322,15 +1331,18 @@ DEFUN ("process-thread", Fprocess_thread, Sprocess_thread,
DEFUN ("set-process-window-size", Fset_process_window_size,
Sset_process_window_size, 3, 3, 0,
doc: /* Tell PROCESS that it has logical window size HEIGHT and WIDTH. */)
- (register Lisp_Object process, Lisp_Object height, Lisp_Object width)
+ (Lisp_Object process, Lisp_Object height, Lisp_Object width)
{
CHECK_PROCESS (process);
- CHECK_RANGED_INTEGER (height, 0, INT_MAX);
- CHECK_RANGED_INTEGER (width, 0, INT_MAX);
+
+ /* All known platforms store window sizes as 'unsigned short'. */
+ CHECK_RANGED_INTEGER (height, 0, USHRT_MAX);
+ CHECK_RANGED_INTEGER (width, 0, USHRT_MAX);
if (XPROCESS (process)->infd < 0
- || set_window_size (XPROCESS (process)->infd,
- XINT (height), XINT (width)) <= 0)
+ || (set_window_size (XPROCESS (process)->infd,
+ XINT (height), XINT (width))
+ < 0))
return Qnil;
else
return Qt;
@@ -1590,22 +1602,9 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
function. The argument list is protected by the caller, so all
we really have to worry about is buffer. */
{
- struct gcpro gcpro1, gcpro2;
-
- current_dir = BVAR (current_buffer, directory);
-
- GCPRO2 (buffer, current_dir);
-
- current_dir = Funhandled_file_name_directory (current_dir);
- if (NILP (current_dir))
- /* If the file name handler says that current_dir is unreachable, use
- a sensible default. */
- current_dir = build_string ("~/");
- current_dir = expand_and_dir_to_file (current_dir, Qnil);
- if (NILP (Ffile_accessible_directory_p (current_dir)))
- report_file_error ("Setting current directory",
- BVAR (current_buffer, directory));
-
+ struct gcpro gcpro1;
+ GCPRO1 (buffer);
+ current_dir = encode_current_directory ();
UNGCPRO;
}
@@ -1852,7 +1851,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
bool pty_flag = 0;
char pty_name[PTY_NAME_SIZE];
Lisp_Object lisp_pty_name = Qnil;
- Lisp_Object encoded_current_dir;
inchannel = outchannel = -1;
@@ -1914,15 +1912,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
/* This may signal an error. */
setup_process_coding_systems (process);
- encoded_current_dir = ENCODE_FILE (current_dir);
-
block_input ();
block_child_signal ();
#ifndef WINDOWSNT
/* vfork, and prevent local vars from being clobbered by the vfork. */
{
- Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir;
+ Lisp_Object volatile current_dir_volatile = current_dir;
Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name;
char **volatile new_argv_volatile = new_argv;
int volatile forkin_volatile = forkin;
@@ -1931,7 +1927,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
pid = vfork ();
- encoded_current_dir = encoded_current_dir_volatile;
+ current_dir = current_dir_volatile;
lisp_pty_name = lisp_pty_name_volatile;
new_argv = new_argv_volatile;
forkin = forkin_volatile;
@@ -2043,11 +2039,9 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
if (pty_flag)
child_setup_tty (xforkout);
#ifdef WINDOWSNT
- pid = child_setup (xforkin, xforkout, xforkout,
- new_argv, 1, encoded_current_dir);
+ pid = child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir);
#else /* not WINDOWSNT */
- child_setup (xforkin, xforkout, xforkout,
- new_argv, 1, encoded_current_dir);
+ child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir);
#endif /* not WINDOWSNT */
}
@@ -4012,15 +4006,12 @@ deactivate_process (Lisp_Object proc)
}
#endif
- inchannel = p->infd;
-
/* Beware SIGCHLD hereabouts. */
- if (inchannel >= 0)
- flush_pending_output (inchannel);
for (i = 0; i < PROCESS_OPEN_FDS; i++)
close_process_fd (&p->open_fd[i]);
+ inchannel = p->infd;
if (inchannel >= 0)
{
p->infd = -1;
@@ -5928,10 +5919,9 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group,
return;
}
- switch (signo)
- {
#ifdef SIGCONT
- case SIGCONT:
+ if (signo == SIGCONT)
+ {
p->raw_status_new = 0;
pset_status (p, Qrun);
p->tick = ++process_tick;
@@ -5940,14 +5930,8 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group,
status_notify (NULL);
redisplay_preserve_echo_area (13);
}
- break;
-#endif /* ! defined (SIGCONT) */
- case SIGINT:
- case SIGQUIT:
- case SIGKILL:
- flush_pending_output (p->infd);
- break;
}
+#endif
/* If we don't have process groups, send the signal to the immediate
subprocess. That isn't really right, but it's better than any
diff --git a/src/process.h b/src/process.h
index 95881d10f58..e8bafe689b1 100644
--- a/src/process.h
+++ b/src/process.h
@@ -221,6 +221,7 @@ enum
extern void block_child_signal (void);
extern void unblock_child_signal (void);
+extern Lisp_Object encode_current_directory (void);
extern void record_kill_process (struct Lisp_Process *, Lisp_Object);
/* Defined in sysdep.c. */
diff --git a/src/sysdep.c b/src/sysdep.c
index 201ba9d104d..0d732526528 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -337,16 +337,6 @@ child_status_changed (pid_t child, int *status, int options)
return get_child_status (child, status, WNOHANG | options, 0);
}
-/*
- * flush any pending output
- * (may flush input as well; it does not matter the way we use it)
- */
-
-void
-flush_pending_output (int channel)
-{
- /* FIXME: maybe this function should be removed */
-}
/* Set up the terminal at the other end of a pseudo-terminal that
we will be controlling an inferior through.
@@ -481,10 +471,20 @@ sys_subshell (void)
pid_t pid;
int status;
struct save_signal saved_handlers[5];
- Lisp_Object dir;
- unsigned char *volatile str_volatile = 0;
- unsigned char *str;
- int len;
+ char *str = SSDATA (encode_current_directory ());
+
+#ifdef DOS_NT
+ pid = 0;
+#else
+ {
+ char *volatile str_volatile = str;
+ pid = vfork ();
+ str = str_volatile;
+ }
+#endif
+
+ if (pid < 0)
+ error ("Can't spawn subshell");
saved_handlers[0].code = SIGINT;
saved_handlers[1].code = SIGQUIT;
@@ -496,31 +496,8 @@ sys_subshell (void)
saved_handlers[3].code = 0;
#endif
- /* Mentioning current_buffer->buffer would mean including buffer.h,
- which somehow wedges the hp compiler. So instead... */
-
- dir = intern ("default-directory");
- if (NILP (Fboundp (dir)))
- goto xyzzy;
- dir = Fsymbol_value (dir);
- if (!STRINGP (dir))
- goto xyzzy;
-
- dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
- str_volatile = str = alloca (SCHARS (dir) + 2);
- len = SCHARS (dir);
- memcpy (str, SDATA (dir), len);
- if (str[len - 1] != '/') str[len++] = '/';
- str[len] = 0;
- xyzzy:
-
#ifdef DOS_NT
- pid = 0;
save_signal_handlers (saved_handlers);
-#else
- pid = vfork ();
- if (pid == -1)
- error ("Can't spawn subshell");
#endif
if (pid == 0)
@@ -538,11 +515,10 @@ sys_subshell (void)
sh = "sh";
/* Use our buffer's default directory for the subshell. */
- str = str_volatile;
- if (str && chdir ((char *) str) != 0)
+ if (chdir (str) != 0)
{
#ifndef DOS_NT
- emacs_perror ((char *) str);
+ emacs_perror (str);
_exit (EXIT_CANCELED);
#endif
}
@@ -556,8 +532,6 @@ sys_subshell (void)
if (epwd)
{
strcpy (old_pwd, epwd);
- if (str[len - 1] == '/')
- str[len - 1] = '\0';
setenv ("PWD", str, 1);
}
st = system (sh);
@@ -1196,7 +1170,8 @@ get_tty_size (int fd, int *widthp, int *heightp)
}
/* Set the logical window size associated with descriptor FD
- to HEIGHT and WIDTH. This is used mainly with ptys. */
+ to HEIGHT and WIDTH. This is used mainly with ptys.
+ Return a negative value on failure. */
int
set_window_size (int fd, int height, int width)
@@ -1208,10 +1183,7 @@ set_window_size (int fd, int height, int width)
size.ws_row = height;
size.ws_col = width;
- if (ioctl (fd, TIOCSWINSZ, &size) == -1)
- return 0; /* error */
- else
- return 1;
+ return ioctl (fd, TIOCSWINSZ, &size);
#else
#ifdef TIOCSSIZE
@@ -1221,10 +1193,7 @@ set_window_size (int fd, int height, int width)
size.ts_lines = height;
size.ts_cols = width;
- if (ioctl (fd, TIOCGSIZE, &size) == -1)
- return 0;
- else
- return 1;
+ return ioctl (fd, TIOCGSIZE, &size);
#else
return -1;
#endif /* not SunOS-style */
@@ -2485,7 +2454,7 @@ serial_configure (struct Lisp_Process *p,
Lisp_Object childp2 = Qnil;
Lisp_Object tem = Qnil;
struct termios attr;
- int err = -1;
+ int err;
char summary[4] = "???"; /* This usually becomes "8N1". */
childp2 = Fcopy_sequence (p->childp);
@@ -2852,29 +2821,41 @@ procfs_ttyname (int rdev)
return build_string (name);
}
-static unsigned long
+static uintmax_t
procfs_get_total_memory (void)
{
FILE *fmem;
- unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */
+ uintmax_t retval = 2 * 1024 * 1024; /* default: 2 GiB */
+ int c;
block_input ();
fmem = emacs_fopen ("/proc/meminfo", "r");
if (fmem)
{
- unsigned long entry_value;
- char entry_name[20]; /* the longest I saw is 13+1 */
+ uintmax_t entry_value;
+ bool done;
+
+ do
+ switch (fscanf (fmem, "MemTotal: %"SCNuMAX, &entry_value))
+ {
+ case 1:
+ retval = entry_value;
+ done = 1;
+ break;
+
+ case 0:
+ while ((c = getc (fmem)) != EOF && c != '\n')
+ continue;
+ done = c == EOF;
+ break;
+
+ default:
+ done = 1;
+ break;
+ }
+ while (!done);
- while (!feof (fmem) && !ferror (fmem))
- {
- if (fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value) >= 2
- && strcmp (entry_name, "MemTotal:") == 0)
- {
- retval = entry_value;
- break;
- }
- }
fclose (fmem);
}
unblock_input ();
@@ -3275,7 +3256,7 @@ system_process_attributes (Lisp_Object pid)
{
int proc_id;
int pagesize = getpagesize ();
- int npages;
+ unsigned long npages;
int fscale;
struct passwd *pw;
struct group *gr;
diff --git a/src/w32.c b/src/w32.c
index 21dbf49ed7c..7f9b96a77a5 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -2503,8 +2503,6 @@ gettimeofday (struct timeval *__restrict tv, struct timezone *__restrict tz)
int
fdutimens (int fd, char const *file, struct timespec const timespec[2])
{
- struct _utimbuf ut;
-
if (!timespec)
{
errno = ENOSYS;
@@ -2515,12 +2513,28 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2])
errno = EBADF;
return -1;
}
- ut.actime = timespec[0].tv_sec;
- ut.modtime = timespec[1].tv_sec;
+ /* _futime's prototype defines 2nd arg as having the type 'struct
+ _utimbuf', while utime needs to accept 'struct utimbuf' for
+ compatibility with Posix. So we need to use 2 different (but
+ equivalent) types to avoid compiler warnings, sigh. */
if (fd >= 0)
- return _futime (fd, &ut);
+ {
+ struct _utimbuf _ut;
+
+ _ut.actime = timespec[0].tv_sec;
+ _ut.modtime = timespec[1].tv_sec;
+ return _futime (fd, &_ut);
+ }
else
- return _utime (file, &ut);
+ {
+ struct utimbuf ut;
+
+ ut.actime = timespec[0].tv_sec;
+ ut.modtime = timespec[1].tv_sec;
+ /* Call 'utime', which is implemented below, not the MS library
+ function, which fails on directories. */
+ return utime (file, &ut);
+ }
}
@@ -4501,6 +4515,9 @@ fstat (int desc, struct stat * buf)
return 0;
}
+/* A version of 'utime' which handles directories as well as
+ files. */
+
int
utime (const char *name, struct utimbuf *times)
{
diff --git a/src/w32term.c b/src/w32term.c
index 7d51850559b..7a15323551b 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -210,7 +210,6 @@ static int volatile input_signal_count;
int w32_message_fd = -1;
#endif /* CYGWIN */
-static void x_update_window_end (struct window *, int, int);
static void w32_handle_tool_bar_click (struct frame *,
struct input_event *);
static void w32_define_cursor (Window, Cursor);
@@ -676,8 +675,8 @@ w32_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
here. */
static void
-x_update_window_end (struct window *w, int cursor_on_p,
- int mouse_face_overwritten_p)
+x_update_window_end (struct window *w, bool cursor_on_p,
+ bool mouse_face_overwritten_p)
{
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
@@ -5300,8 +5299,8 @@ w32_clear_frame_area (struct frame *f, int x, int y, int width, int height)
static void
w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
- int x, int y, int cursor_type, int cursor_width,
- int on_p, int active_p)
+ int x, int y, enum text_cursor_kinds cursor_type,
+ int cursor_width, bool on_p, bool active_p)
{
if (on_p)
{
diff --git a/src/window.c b/src/window.c
index a1a069e0e7d..b02b30cd0b2 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5408,7 +5408,7 @@ struct save_window_data
Lisp_Object saved_windows;
/* All fields above are traced by the GC.
- From `fame-cols' down, the fields are ignored by the GC. */
+ From `frame-cols' down, the fields are ignored by the GC. */
int frame_cols, frame_lines, frame_menu_bar_lines;
int frame_tool_bar_lines;
diff --git a/src/xdisp.c b/src/xdisp.c
index ea1cd7dd2bc..3ff4603b727 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -3912,10 +3912,14 @@ handle_face_prop (struct it *it)
/* For strings from a `display' property, use the face at
IT's current buffer position as the base face to merge
with, so that overlay strings appear in the same face as
- surrounding text, unless they specify their own
- faces. */
+ surrounding text, unless they specify their own faces.
+ For strings from wrap-prefix and line-prefix properties,
+ use the default face, possibly remapped via
+ Vface_remapping_alist. */
base_face_id = it->string_from_prefix_prop_p
- ? DEFAULT_FACE_ID
+ ? (!NILP (Vface_remapping_alist)
+ ? lookup_basic_face (it->f, DEFAULT_FACE_ID)
+ : DEFAULT_FACE_ID)
: underlying_face_id (it);
}
@@ -7046,7 +7050,9 @@ get_next_display_element (struct it *it)
}
}
}
- else
+ /* next_element_from_display_vector sets this flag according to
+ faces of the display vector glyphs, see there. */
+ else if (it->method != GET_FROM_DISPLAY_VECTOR)
{
int face_id = face_after_it_pos (it);
it->end_of_box_run_p
@@ -25763,12 +25769,12 @@ x_produce_glyphs (struct it *it)
/* EXPORT for RIF:
Output LEN glyphs starting at START at the nominal cursor position.
- Advance the nominal cursor over the text. The global variable
- updated_row is the glyph row being updated, and updated_area is the
- area of that row being updated. */
+ Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
+ being updated, and UPDATED_AREA is the area of that row being updated. */
void
-x_write_glyphs (struct window *w, struct glyph *start, int len)
+x_write_glyphs (struct window *w, struct glyph_row *updated_row,
+ struct glyph *start, enum glyph_row_area updated_area, int len)
{
int x, hpos, chpos = w->phys_cursor.hpos;
@@ -25811,7 +25817,8 @@ x_write_glyphs (struct window *w, struct glyph *start, int len)
Insert LEN glyphs from START at the nominal cursor position. */
void
-x_insert_glyphs (struct window *w, struct glyph *start, int len)
+x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
+ struct glyph *start, enum glyph_row_area updated_area, int len)
{
struct frame *f;
int line_height, shift_by_width, shifted_region_width;
@@ -25863,11 +25870,12 @@ x_insert_glyphs (struct window *w, struct glyph *start, int len)
(inclusive) to pixel column TO_X (exclusive). The idea is that
everything from TO_X onward is already erased.
- TO_X is a pixel position relative to updated_area of currently
+ TO_X is a pixel position relative to UPDATED_AREA of currently
updated window W. TO_X == -1 means clear to the end of this area. */
void
-x_clear_end_of_line (struct window *w, int to_x)
+x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
+ enum glyph_row_area updated_area, int to_x)
{
struct frame *f;
int max_x, min_y, max_y;
@@ -26463,7 +26471,7 @@ erase_phys_cursor (struct window *w)
where to put the cursor is specified by HPOS, VPOS, X and Y. */
void
-display_and_set_cursor (struct window *w, int on,
+display_and_set_cursor (struct window *w, bool on,
int hpos, int vpos, int x, int y)
{
struct frame *f = XFRAME (w->frame);
@@ -26547,7 +26555,7 @@ display_and_set_cursor (struct window *w, int on,
of ON. */
static void
-update_window_cursor (struct window *w, int on)
+update_window_cursor (struct window *w, bool on)
{
/* Don't update cursor in windows whose frame is in the process
of being deleted. */
@@ -26583,7 +26591,7 @@ update_window_cursor (struct window *w, int on)
in the window tree rooted at W. */
static void
-update_cursor_in_window_tree (struct window *w, int on_p)
+update_cursor_in_window_tree (struct window *w, bool on_p)
{
while (w)
{
@@ -26602,7 +26610,7 @@ update_cursor_in_window_tree (struct window *w, int on_p)
Don't change the cursor's position. */
void
-x_update_cursor (struct frame *f, int on_p)
+x_update_cursor (struct frame *f, bool on_p)
{
update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
}
diff --git a/src/xterm.c b/src/xterm.c
index b5c5a5cb584..cea952f44d2 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -292,8 +292,6 @@ static void x_set_window_size_1 (struct frame *, int, int, int);
static void x_raise_frame (struct frame *);
static void x_lower_frame (struct frame *);
static const XColor *x_color_cells (Display *, int *);
-static void x_update_window_end (struct window *, int, int);
-
static int x_io_error_quitter (Display *);
static struct terminal *x_create_terminal (struct x_display_info *);
void x_delete_terminal (struct terminal *);
@@ -612,7 +610,8 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
here. */
static void
-x_update_window_end (struct window *w, int cursor_on_p, int mouse_face_overwritten_p)
+x_update_window_end (struct window *w, bool cursor_on_p,
+ bool mouse_face_overwritten_p)
{
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
@@ -7372,7 +7371,9 @@ x_clear_frame_area (struct frame *f, int x, int y, int width, int height)
/* RIF: Draw cursor on window W. */
static void
-x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x, int y, int cursor_type, int cursor_width, int on_p, int active_p)
+x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x,
+ int y, enum text_cursor_kinds cursor_type,
+ int cursor_width, bool on_p, bool active_p)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));