From e1bf05c1fbf63087801c242208212df133921ed1 Mon Sep 17 00:00:00 2001 From: Kenichi Handa Date: Tue, 13 Nov 2012 21:06:44 +0900 Subject: font.c (font_unparse_xlfd): Exclude special characters from the generating XLFD name. --- src/ChangeLog | 5 +++++ src/font.c | 17 +++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 1daeb7bc0b6..efe5e59cb73 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2012-11-13 Kenichi Handa + + * font.c (font_unparse_xlfd): Exclude special characters from the + generating XLFD name. + 2012-11-06 Dmitry Antipov * window.c (quad): New function. diff --git a/src/font.c b/src/font.c index e960f9b3d13..1ec5929506e 100644 --- a/src/font.c +++ b/src/font.c @@ -1185,7 +1185,7 @@ ptrdiff_t font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes) { char *p; - const char *f[XLFD_REGISTRY_INDEX + 1]; + char *f[XLFD_REGISTRY_INDEX + 1]; Lisp_Object val; int i, j, len; @@ -1234,8 +1234,21 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes) f[j] = "*"; else { + int c, k, l; + ptrdiff_t alloc; + val = SYMBOL_NAME (val); - f[j] = SSDATA (val); + alloc = SBYTES (val) + 1; + if (nbytes <= alloc) + return -1; + f[j] = alloca (alloc); + /* Copy the name while excluding '-', '?', ',', and '"'. */ + for (k = l = 0; k < alloc; k++) + { + c = SREF (val, k); + if (c != '-' && c != '?' && c != ',' && c != '"') + f[j][l++] = c; + } } } -- cgit v1.2.1 From 86dcf21c0749f699678e42a605044d99de36dd28 Mon Sep 17 00:00:00 2001 From: enami tsugutomo Date: Fri, 16 Nov 2012 13:41:00 -0500 Subject: * src/unexelf.c (ELFSIZE) [__NetBSD__ && _LP64]: Set to 64 Needed following 2012-10-20 change. Fixes: debbugs:12902 --- src/ChangeLog | 5 +++++ src/unexelf.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index b218e42b3f2..64adec7491a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2012-11-16 enami tsugutomo + + * unexelf.c (ELFSIZE) [__NetBSD__ && _LP64]: Set to 64. + Needed following 2012-10-20 change. (Bug#12902) + 2012-11-16 Glenn Morris * editfns.c (Fmessage): Mention message-log-max. (Bug#12849) diff --git a/src/unexelf.c b/src/unexelf.c index 121e6042fc9..b9f8e05e959 100644 --- a/src/unexelf.c +++ b/src/unexelf.c @@ -461,7 +461,7 @@ typedef struct { /* * NetBSD does not have normal-looking user-land ELF support. */ -# if defined __alpha__ || defined __sparc_v9__ +# if defined __alpha__ || defined __sparc_v9__ || defined _LP64 # define ELFSIZE 64 # else # define ELFSIZE 32 -- cgit v1.2.1 From 7436fc63c0c24eb7fee800176c387db87f51de50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Dj=C3=A4rv?= Date: Sat, 17 Nov 2012 16:28:56 +0100 Subject: * nsterm.m (hold_event): Set send_appdefined to YES. (ns_select): Return at once if events are held (Bug#12834). --- src/ChangeLog | 5 +++++ src/nsterm.m | 9 +++++++++ 2 files changed, 14 insertions(+) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 64adec7491a..d88e43b2b7f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2012-11-17 Jan Djärv + + * nsterm.m (hold_event): Set send_appdefined to YES (Bug#12834). + (ns_select): Return at once if events are held (Bug#12834). + 2012-11-16 enami tsugutomo * unexelf.c (ELFSIZE) [__NetBSD__ && _LP64]: Set to 64. diff --git a/src/nsterm.m b/src/nsterm.m index f4982e0a7cb..9d52bd7f52b 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -314,6 +314,7 @@ hold_event (struct input_event *event) hold_event_q.q[hold_event_q.nr++] = *event; /* Make sure ns_read_socket is called, i.e. we have input. */ kill (0, SIGIO); + send_appdefined = YES; } static Lisp_Object @@ -3445,6 +3446,14 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds, /* NSTRACE (ns_select); */ + if (hold_event_q.nr > 0) + { + /* We already have events pending. */ + kill (0, SIGIO); + errno = EINTR; + return -1; + } + for (k = 0; k < nfds+1; k++) { if (readfds && FD_ISSET(k, readfds)) ++nr; -- cgit v1.2.1 From 9fa3ccd98a740d51556ea0b94cb42cda6349159a Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 17 Nov 2012 10:30:16 -0800 Subject: Update comment to match recent change. --- src/process.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/process.c b/src/process.c index 5fe6a6540f3..51648187aff 100644 --- a/src/process.c +++ b/src/process.c @@ -6283,8 +6283,8 @@ record_child_status_change (pid_t pid, int w) { #ifdef SIGCHLD - /* On POSIXish hosts, record at most one child only if we already - know one child that has exited. */ + /* Record at most one child only if we already know one child that + has exited. */ bool record_at_most_one_child = 0 <= pid; Lisp_Object tail; -- cgit v1.2.1 From d8715cdf90538fa8abd3e2c23ed2efd23c4253c1 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 17 Nov 2012 20:51:06 +0200 Subject: Fix bug #12878 with compilation failure with Visual C++ 11.0. src/w32select.c: Include w32common.h before w32term.h, so that windows.h gets included before w32term.h uses some of its features, see below. src/w32term.h (LOCALE_ENUMPROCA, LOCALE_ENUMPROCW) [_MSC_VER]: New typedefs. (EnumSystemLocalesA, EnumSystemLocalesW) [_MSC_VER]: New prototypes. (EnumSystemLocales) [_MSC_VER]: Define if undefined. --- src/ChangeLog | 12 ++++++++++++ src/w32select.c | 2 +- src/w32term.h | 15 +++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index d88e43b2b7f..c12eff19ddd 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2012-11-17 Eli Zaretskii + + * w32select.c: Include w32common.h before w32term.h, so that + windows.h gets included before w32term.h uses some of its + features, see below. + + * w32term.h (LOCALE_ENUMPROCA, LOCALE_ENUMPROCW) [_MSC_VER]: New + typedefs. + (EnumSystemLocalesA, EnumSystemLocalesW) [_MSC_VER]: New + prototypes. + (EnumSystemLocales) [_MSC_VER]: Define if undefined. (Bug#12878) + 2012-11-17 Jan Djärv * nsterm.m (hold_event): Set send_appdefined to YES (Bug#12834). diff --git a/src/w32select.c b/src/w32select.c index 1b10c74cfe9..6a2a840f914 100644 --- a/src/w32select.c +++ b/src/w32select.c @@ -74,8 +74,8 @@ along with GNU Emacs. If not, see . */ #include #include "lisp.h" -#include "w32term.h" /* for all of the w32 includes */ #include "w32common.h" /* os_subtype */ +#include "w32term.h" /* for all of the w32 includes */ #include "keyboard.h" #include "blockinput.h" #include "charset.h" diff --git a/src/w32term.h b/src/w32term.h index af5b37a1171..6e30d374c82 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -752,6 +752,21 @@ extern int w32_system_caret_height; extern int w32_system_caret_x; extern int w32_system_caret_y; +#ifdef _MSC_VER +#ifndef EnumSystemLocales +/* MSVC headers define these only for _WIN32_WINNT >= 0x0500. */ +typedef BOOL (CALLBACK *LOCALE_ENUMPROCA)(LPSTR); +typedef BOOL (CALLBACK *LOCALE_ENUMPROCW)(LPWSTR); +BOOL WINAPI EnumSystemLocalesA(LOCALE_ENUMPROCA,DWORD); +BOOL WINAPI EnumSystemLocalesW(LOCALE_ENUMPROCW,DWORD) +#ifdef UNICODE +#define EnumSystemLocales EnumSystemLocalesW +#else +#define EnumSystemLocales EnumSystemLocalesA +#endif +#endif +#endif + #if EMACSDEBUG extern const char* w32_name_of_message (UINT msg); -- cgit v1.2.1 From 49cdacdad393e2b9282a19a963030dfbe1a738ab Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 17 Nov 2012 14:12:47 -0800 Subject: Assume POSIX 1003.1-1988 or later for fcntl.h. * admin/CPP-DEFINES (O_RDONLY, O_RDWR, HAVE_FCNTL_H): Remove. * admin/merge-gnulib (GNULIB_MODULES): Add fcntl-h. * configure.ac: Do not check for fcntl.h. * lib/gnulib.mk: Regenerate. * lib-src/movemail.c, lib-src/update-game-score.c: Assume exists. * nt/inc/sys/socket.h (O_NONBLOCK): Rename from O_NDELAY, since the POSIX name for this flag is O_NONBLOCK. All uses changed. * nt/inc/unistd.h (O_RDWR, O_NOCTTY): New macros. Like AT_FDCWD etc. these really should be moved to a replacement if and when that gets implemented. In the meantime, include to make sure we don't override its definitions. * src/callproc.c (relocate_fd): Assume F_DUPFD. * src/emacs.c, src/term.c (O_RDWR): Remove. * src/keyboard.c (tty_read_avail_input): Use O_NONBLOCK rather than O_NDELAY, since O_NONBLOCK is the standard name for this flag. * src/nsterm.m: Assume exists. * src/process.c (NON_BLOCKING_CONNECT, allocate_pty, create_process) (create_pty, Fmake_network_process, server_accept_connection) (wait_reading_process_output, init_process_emacs): Assume O_NONBLOCK. (wait_reading_process_output): Put in a special case for WINDOWSNT to mimick the older behavior where it had O_NDELAY but not O_NONBLOCK. It's not clear this is needed, but it's a more-conservative change. (create_process): Assume FD_CLOEXEC. (create_process, create_pty): Assume O_NOCTTY. * src/sysdep.c (init_sys_modes, reset_sys_modes): Assume F_SETFL. (reset_sys_modes): Use O_NONBLOCK rather than O_NDELAY. Omit if not DOS_NT, since F_GETFL is not defined there. (serial_open): Assume O_NONBLOCK and O_NOCTTY. * src/term.c: Include , for flags like O_NOCTTY. (O_NOCTTY): Remove. (init_tty): Assume O_IGNORE_CTTY is defined to 0 on platforms that lack it, since gnulib guarantees this. * src/w32.c (fcntl): Test for O_NONBLOCK rather than O_NDELAY. Fixes: debbugs:12881 --- src/ChangeLog | 27 +++++++++++++++++++++ src/callproc.c | 11 +-------- src/emacs.c | 4 ---- src/keyboard.c | 4 ++-- src/nsterm.m | 5 +--- src/process.c | 74 ++++++---------------------------------------------------- src/sysdep.c | 26 ++++----------------- src/term.c | 39 +++++++++++-------------------- src/w32.c | 2 +- 9 files changed, 57 insertions(+), 135 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index df8bf602afe..a847a3913dd 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,30 @@ +2012-11-17 Paul Eggert + + Assume POSIX 1003.1-1988 or later for fcntl.h (Bug#12881). + * callproc.c (relocate_fd): Assume F_DUPFD. + * emacs.c, term.c (O_RDWR): Remove. + * keyboard.c (tty_read_avail_input): Use O_NONBLOCK rather than + O_NDELAY, since O_NONBLOCK is the standard name for this flag. + * nsterm.m: Assume exists. + * process.c (NON_BLOCKING_CONNECT, allocate_pty, create_process) + (create_pty, Fmake_network_process, server_accept_connection) + (wait_reading_process_output, init_process_emacs): + Assume O_NONBLOCK. + (wait_reading_process_output): Put in a special case for WINDOWSNT + to mimick the older behavior where it had O_NDELAY but not O_NONBLOCK. + It's not clear this is needed, but it's a more-conservative change. + (create_process): Assume FD_CLOEXEC. + (create_process, create_pty): Assume O_NOCTTY. + * sysdep.c (init_sys_modes, reset_sys_modes): Assume F_SETFL. + (reset_sys_modes): Use O_NONBLOCK rather than O_NDELAY. + Omit if not DOS_NT, since F_GETFL is not defined there. + (serial_open): Assume O_NONBLOCK and O_NOCTTY. + * term.c: Include , for flags like O_NOCTTY. + (O_NOCTTY): Remove. + (init_tty): Assume O_IGNORE_CTTY is defined to 0 on platforms that + lack it, since gnulib guarantees this. + * w32.c (fcntl): Test for O_NONBLOCK rather than O_NDELAY. + 2012-11-17 Eli Zaretskii * w32.c (faccessat): Pretend that directories have the execute bit diff --git a/src/callproc.c b/src/callproc.c index 8ecaba2b408..c9a504746b3 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -1317,16 +1317,7 @@ relocate_fd (int fd, int minfd) return fd; else { - int new; -#ifdef F_DUPFD - new = fcntl (fd, F_DUPFD, minfd); -#else - new = dup (fd); - if (new != -1) - /* Note that we hold the original FD open while we recurse, - to guarantee we'll get a new FD if we need it. */ - new = relocate_fd (new, minfd); -#endif + int new = fcntl (fd, F_DUPFD, minfd); if (new == -1) { const char *message_1 = "Error while setting up child: "; diff --git a/src/emacs.c b/src/emacs.c index fee9c332c55..d69dbfda7bf 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -95,10 +95,6 @@ extern void moncontrol (int mode); #include #endif -#ifndef O_RDWR -#define O_RDWR 2 -#endif - static const char emacs_version[] = VERSION; static const char emacs_copyright[] = COPYRIGHT; diff --git a/src/keyboard.c b/src/keyboard.c index 8f3a206139d..951d4ad79dc 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -6948,7 +6948,7 @@ tty_read_avail_input (struct terminal *terminal, #elif defined USG || defined CYGWIN /* Read some input if available, but don't wait. */ n_to_read = sizeof cbuf; - fcntl (fileno (tty->input), F_SETFL, O_NDELAY); + fcntl (fileno (tty->input), F_SETFL, O_NONBLOCK); #else # error "Cannot read without possibly delaying" #endif @@ -6982,7 +6982,7 @@ tty_read_avail_input (struct terminal *terminal, } while ( /* We used to retry the read if it was interrupted. - But this does the wrong thing when O_NDELAY causes + But this does the wrong thing when O_NONBLOCK causes an EAGAIN error. Does anybody know of a situation where a retry is actually needed? */ #if 0 diff --git a/src/nsterm.m b/src/nsterm.m index 3640ac0c5e8..8773c6faf9f 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -30,6 +30,7 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu) interpretation of even the system includes. */ #include +#include #include #include #include @@ -41,10 +42,6 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu) #include #include -#ifdef HAVE_FCNTL_H -#include -#endif - #include "lisp.h" #include "blockinput.h" #include "sysselect.h" diff --git a/src/process.c b/src/process.c index 51648187aff..0036ce595f5 100644 --- a/src/process.c +++ b/src/process.c @@ -196,11 +196,9 @@ static EMACS_INT update_tick; #ifndef NON_BLOCKING_CONNECT #ifdef HAVE_SELECT #if defined (HAVE_GETPEERNAME) || defined (GNU_LINUX) -#if O_NONBLOCK || O_NDELAY #if defined (EWOULDBLOCK) || defined (EINPROGRESS) #define NON_BLOCKING_CONNECT #endif /* EWOULDBLOCK || EINPROGRESS */ -#endif /* O_NONBLOCK || O_NDELAY */ #endif /* HAVE_GETPEERNAME || GNU_LINUX */ #endif /* HAVE_SELECT */ #endif /* NON_BLOCKING_CONNECT */ @@ -639,13 +637,7 @@ allocate_pty (void) #ifdef PTY_OPEN PTY_OPEN; #else /* no PTY_OPEN */ - { -# if O_NONBLOCK - fd = emacs_open (pty_name, O_RDWR | O_NONBLOCK, 0); -# else - fd = emacs_open (pty_name, O_RDWR | O_NDELAY, 0); -# endif - } + fd = emacs_open (pty_name, O_RDWR | O_NONBLOCK, 0); #endif /* no PTY_OPEN */ if (fd >= 0) @@ -1583,7 +1575,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) int inchannel, outchannel; pid_t pid; int sv[2]; -#if !defined (WINDOWSNT) && defined (FD_CLOEXEC) +#ifndef WINDOWSNT int wait_child_setup[2]; #endif #ifdef SIGCHLD @@ -1609,13 +1601,9 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) #if ! defined (USG) || defined (USG_SUBTTY_WORKS) /* On most USG systems it does not work to open the pty's tty here, then close it and reopen it in the child. */ -#if O_NOCTTY /* Don't let this terminal become our controlling terminal (in case we don't have one). */ forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); -#else - forkout = forkin = emacs_open (pty_name, O_RDWR, 0); -#endif if (forkin < 0) report_file_error ("Opening pty", Qnil); #else @@ -1644,7 +1632,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) forkin = sv[0]; } -#if !defined (WINDOWSNT) && defined (FD_CLOEXEC) +#ifndef WINDOWSNT { int tem; @@ -1663,15 +1651,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) } #endif -#if O_NONBLOCK fcntl (inchannel, F_SETFL, O_NONBLOCK); fcntl (outchannel, F_SETFL, O_NONBLOCK); -#else -#if O_NDELAY - fcntl (inchannel, F_SETFL, O_NDELAY); - fcntl (outchannel, F_SETFL, O_NDELAY); -#endif -#endif /* Record this as an active process, with its channels. As a result, child_setup will close Emacs's side of the pipes. */ @@ -1830,9 +1811,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) pid = child_setup (xforkin, xforkout, xforkout, new_argv, 1, encoded_current_dir); #else /* not WINDOWSNT */ -#ifdef FD_CLOEXEC emacs_close (wait_child_setup[0]); -#endif child_setup (xforkin, xforkout, xforkout, new_argv, 1, encoded_current_dir); #endif /* not WINDOWSNT */ @@ -1891,7 +1870,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) pset_tty_name (XPROCESS (process), lisp_pty_name); -#if !defined (WINDOWSNT) && defined (FD_CLOEXEC) +#ifndef WINDOWSNT /* Wait for child_setup to complete in case that vfork is actually defined as fork. The descriptor wait_child_setup[1] of a pipe is closed at the child side either by close-on-exec @@ -1928,13 +1907,9 @@ create_pty (Lisp_Object process) #if ! defined (USG) || defined (USG_SUBTTY_WORKS) /* On most USG systems it does not work to open the pty's tty here, then close it and reopen it in the child. */ -#if O_NOCTTY /* Don't let this terminal become our controlling terminal (in case we don't have one). */ int forkout = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); -#else - int forkout = emacs_open (pty_name, O_RDWR, 0); -#endif if (forkout < 0) report_file_error ("Opening pty", Qnil); #if defined (DONT_REOPEN_PTY) @@ -1948,15 +1923,8 @@ create_pty (Lisp_Object process) } #endif /* HAVE_PTYS */ -#if O_NONBLOCK fcntl (inchannel, F_SETFL, O_NONBLOCK); fcntl (outchannel, F_SETFL, O_NONBLOCK); -#else -#if O_NDELAY - fcntl (inchannel, F_SETFL, O_NDELAY); - fcntl (outchannel, F_SETFL, O_NDELAY); -#endif -#endif /* Record this as an active process, with its channels. As a result, child_setup will close Emacs's side of the pipes. */ @@ -2912,13 +2880,9 @@ usage: (make-network-process &rest ARGS) */) { /* Don't support network sockets when non-blocking mode is not available, since a blocked Emacs is not useful. */ -#if !O_NONBLOCK && !O_NDELAY - error ("Network servers not supported"); -#else is_server = 1; if (TYPE_RANGED_INTEGERP (int, tem)) backlog = XINT (tem); -#endif } /* Make QCaddress an alias for :local (server) or :remote (client). */ @@ -3178,11 +3142,7 @@ usage: (make-network-process &rest ARGS) */) #ifdef NON_BLOCKING_CONNECT if (is_non_blocking_client) { -#if O_NONBLOCK ret = fcntl (s, F_SETFL, O_NONBLOCK); -#else - ret = fcntl (s, F_SETFL, O_NDELAY); -#endif if (ret < 0) { xerrno = errno; @@ -3395,13 +3355,7 @@ usage: (make-network-process &rest ARGS) */) chan_process[inch] = proc; -#if O_NONBLOCK fcntl (inch, F_SETFL, O_NONBLOCK); -#else -#if O_NDELAY - fcntl (inch, F_SETFL, O_NDELAY); -#endif -#endif p = XPROCESS (proc); @@ -4130,13 +4084,7 @@ server_accept_connection (Lisp_Object server, int channel) chan_process[s] = proc; -#if O_NONBLOCK fcntl (s, F_SETFL, O_NONBLOCK); -#else -#if O_NDELAY - fcntl (s, F_SETFL, O_NDELAY); -#endif -#endif p = XPROCESS (proc); @@ -4832,23 +4780,17 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, else if (nread == -1 && errno == EWOULDBLOCK) ; #endif - /* ISC 4.1 defines both EWOULDBLOCK and O_NONBLOCK, - and Emacs uses O_NONBLOCK, so what we get is EAGAIN. */ -#if O_NONBLOCK - else if (nread == -1 && errno == EAGAIN) - ; -#else -#if O_NDELAY else if (nread == -1 && errno == EAGAIN) ; +#ifdef WINDOWSNT + /* FIXME: Is this special case still needed? */ /* Note that we cannot distinguish between no input available now and a closed pipe. With luck, a closed pipe will be accompanied by subprocess termination and SIGCHLD. */ else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc)) ; -#endif /* O_NDELAY */ -#endif /* O_NONBLOCK */ +#endif #ifdef HAVE_PTYS /* On some OSs with ptys, when the process on one end of a pty exits, the other end gets an error reading with @@ -7312,9 +7254,7 @@ init_process_emacs (void) #ifdef HAVE_GETSOCKNAME ADD_SUBFEATURE (QCservice, Qt); #endif -#if O_NONBLOCK || O_NDELAY ADD_SUBFEATURE (QCserver, Qt); -#endif for (sopt = socket_options; sopt->name; sopt++) subfeatures = pure_cons (intern_c_string (sopt->name), subfeatures); diff --git a/src/sysdep.c b/src/sysdep.c index 06dc41b511e..7c5c144fa8c 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -1036,8 +1036,7 @@ init_sys_modes (struct tty_display_info *tty_out) #endif #endif -#ifdef F_SETFL -#ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */ +#ifdef F_GETOWN if (interrupt_input) { old_fcntl_owner[fileno (tty_out->input)] = @@ -1055,7 +1054,6 @@ init_sys_modes (struct tty_display_info *tty_out) #endif /* HAVE_GPM */ } #endif /* F_GETOWN */ -#endif /* F_SETFL */ #ifdef _IOFBF /* This symbol is defined on recent USG systems. @@ -1275,8 +1273,8 @@ reset_sys_modes (struct tty_display_info *tty_out) fsync (fileno (tty_out->output)); #endif -#ifdef F_SETFL -#ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */ +#ifndef DOS_NT +#ifdef F_SETOWN if (interrupt_input) { reset_sigio (fileno (tty_out->input)); @@ -1284,11 +1282,9 @@ reset_sys_modes (struct tty_display_info *tty_out) old_fcntl_owner[fileno (tty_out->input)]); } #endif /* F_SETOWN */ -#if O_NDELAY fcntl (fileno (tty_out->input), F_SETFL, - fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NDELAY); + fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NONBLOCK); #endif -#endif /* F_SETFL */ if (tty_out->old_tty) while (emacs_set_tty (fileno (tty_out->input), @@ -2377,19 +2373,7 @@ safe_strsignal (int code) int serial_open (char *port) { - int fd = -1; - - fd = emacs_open ((char*) port, - O_RDWR -#if O_NONBLOCK - | O_NONBLOCK -#else - | O_NDELAY -#endif -#if O_NOCTTY - | O_NOCTTY -#endif - , 0); + int fd = emacs_open (port, O_RDWR | O_NOCTTY | O_NONBLOCK, 0); if (fd < 0) { error ("Could not open %s: %s", diff --git a/src/term.c b/src/term.c index 96549290da5..481a3423989 100644 --- a/src/term.c +++ b/src/term.c @@ -20,8 +20,9 @@ along with GNU Emacs. If not, see . */ /* New redisplay, TTY faces by Gerd Moellmann . */ #include -#include #include +#include +#include #include #include #include @@ -55,14 +56,6 @@ static int been_here = -1; #include "xterm.h" #endif -#ifndef O_RDWR -#define O_RDWR 2 -#endif - -#ifndef O_NOCTTY -#define O_NOCTTY 0 -#endif - /* The name of the default console device. */ #ifdef WINDOWSNT #define DEV_TTY "CONOUT$" @@ -2989,22 +2982,18 @@ init_tty (const char *name, const char *terminal_type, int must_succeed) set_tty_hooks (terminal); { - int fd; + /* Open the terminal device. */ FILE *file; -#if O_IGNORE_CTTY - if (!ctty) - /* Open the terminal device. Don't recognize it as our - controlling terminal, and don't make it the controlling tty - if we don't have one at the moment. */ - fd = emacs_open (name, O_RDWR | O_IGNORE_CTTY | O_NOCTTY, 0); - else -#endif /* O_IGNORE_CTTY */ - /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only - defined on Hurd. On other systems, we need to explicitly - dissociate ourselves from the controlling tty when we want to - open a frame on the same terminal. */ - fd = emacs_open (name, O_RDWR | O_NOCTTY, 0); + /* If !ctty, don't recognize it as our controlling terminal, and + don't make it the controlling tty if we don't have one now. + + Alas, O_IGNORE_CTTY is a GNU extension that seems to be only + defined on Hurd. On other systems, we need to explicitly + dissociate ourselves from the controlling tty when we want to + open a frame on the same terminal. */ + int flags = O_RDWR | O_NOCTTY | (ctty ? 0 : O_IGNORE_CTTY); + int fd = emacs_open (name, flags, 0); tty->name = xstrdup (name); terminal->name = xstrdup (name); @@ -3023,10 +3012,8 @@ init_tty (const char *name, const char *terminal_type, int must_succeed) name); } -#if !O_IGNORE_CTTY - if (!ctty) + if (!O_IGNORE_CTTY && !ctty) dissociate_if_controlling_tty (fd); -#endif file = fdopen (fd, "w+"); tty->input = file; diff --git a/src/w32.c b/src/w32.c index 46433626802..94cf472a4ae 100644 --- a/src/w32.c +++ b/src/w32.c @@ -5854,7 +5854,7 @@ fcntl (int s, int cmd, int options) check_errno (); if (fd_info[s].flags & FILE_SOCKET) { - if (cmd == F_SETFL && options == O_NDELAY) + if (cmd == F_SETFL && options == O_NONBLOCK) { unsigned long nblock = 1; int rc = pfn_ioctlsocket (SOCK_HANDLE (s), FIONBIO, &nblock); -- cgit v1.2.1 From a75ce9d3fd54377fa67bdfb94f46dbe1f1e59450 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Sun, 18 Nov 2012 00:16:24 +0100 Subject: lib-src/makefile.w32-in, src/makefile.w32-in: Update dependencies. * lib-src/makefile.w32-in (SYSWAIT_H): New macro. ($(BLD)/movemail.$(O)): Update dependencies. * src/makefile.w32-in (SYSWAIT_H): New macro. ($(BLD)/callproc.$(O), $(BLD)/w32proc.$(O), $(BLD)/process.$(O)) ($(BLD)/sysdep.$(O)): Update dependencies. --- src/ChangeLog | 6 ++++++ src/makefile.w32-in | 10 ++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index a847a3913dd..c7fb6170d27 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2012-11-17 Juanma Barranquero + + * makefile.w32-in (SYSWAIT_H): New macro. + ($(BLD)/callproc.$(O), $(BLD)/w32proc.$(O), $(BLD)/process.$(O)) + ($(BLD)/sysdep.$(O)): Update dependencies. + 2012-11-17 Paul Eggert Assume POSIX 1003.1-1988 or later for fcntl.h (Bug#12881). diff --git a/src/makefile.w32-in b/src/makefile.w32-in index 69fd6857f86..9778e955677 100644 --- a/src/makefile.w32-in +++ b/src/makefile.w32-in @@ -472,6 +472,8 @@ SYSSIGNAL_H = $(SRC)/syssignal.h \ SYSTTY_H = $(SRC)/systty.h \ $(NT_INC)/sys/ioctl.h \ $(NT_INC)/unistd.h +SYSWAIT_H = $(SRC)/syswait.h \ + $(NT_INC)/sys/wait.h TERMHOOKS_H = $(SRC)/termhooks.h \ $(SYSTIME_H) W32FONT_H = $(SRC)/w32font.h \ @@ -566,7 +568,6 @@ $(BLD)/callproc.$(O) : \ $(SRC)/commands.h \ $(SRC)/composite.h \ $(SRC)/epaths.h \ - $(SRC)/syswait.h \ $(SRC)/w32.h \ $(NT_INC)/sys/file.h \ $(NT_INC)/unistd.h \ @@ -580,6 +581,7 @@ $(BLD)/callproc.$(O) : \ $(PROCESS_H) \ $(SYSSIGNAL_H) \ $(SYSTTY_H) \ + $(SYSWAIT_H) \ $(TERMHOOKS_H) $(BLD)/casefiddle.$(O) : \ @@ -1216,7 +1218,6 @@ $(BLD)/w32inevt.$(O) : \ $(BLD)/w32proc.$(O) : \ $(SRC)/w32proc.c \ - $(SRC)/syswait.h \ $(SRC)/w32.h \ $(SRC)/w32common.h \ $(SRC)/w32heap.h \ @@ -1230,6 +1231,7 @@ $(BLD)/w32proc.$(O) : \ $(PROCESS_H) \ $(SYSSIGNAL_H) \ $(SYSTIME_H) \ + $(SYSWAIT_H) \ $(W32TERM_H) $(BLD)/w32console.$(O) : \ @@ -1274,7 +1276,6 @@ $(BLD)/process.$(O) : \ $(SRC)/composite.h \ $(SRC)/gnutls.h \ $(SRC)/sysselect.h \ - $(SRC)/syswait.h \ $(SRC)/termopts.h \ $(NT_INC)/arpa/inet.h \ $(NT_INC)/netdb.h \ @@ -1297,6 +1298,7 @@ $(BLD)/process.$(O) : \ $(SYSSIGNAL_H) \ $(SYSTIME_H) \ $(SYSTTY_H) \ + $(SYSWAIT_H) \ $(TERMHOOKS_H) \ $(W32TERM_H) \ $(WINDOW_H) @@ -1380,7 +1382,6 @@ $(BLD)/sysdep.$(O) : \ $(SRC)/blockinput.h \ $(SRC)/cm.h \ $(SRC)/sysselect.h \ - $(SRC)/syswait.h \ $(SRC)/termchar.h \ $(SRC)/termopts.h \ $(NT_INC)/netdb.h \ @@ -1405,6 +1406,7 @@ $(BLD)/sysdep.$(O) : \ $(SYSSIGNAL_H) \ $(SYSTIME_H) \ $(SYSTTY_H) \ + $(SYSWAIT_H) \ $(TERMHOOKS_H) \ $(WINDOW_H) -- cgit v1.2.1 From c1f7ba3a74da20e7a20f3f521d6f6b7550cd5d56 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Sun, 18 Nov 2012 02:12:17 +0100 Subject: src/w32proc.c (waitpid): Remove unused label get_result. --- src/ChangeLog | 4 ++++ src/w32proc.c | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index c7fb6170d27..752207a8d9a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2012-11-18 Juanma Barranquero + + * w32proc.c (waitpid): Remove unused label get_result. + 2012-11-17 Juanma Barranquero * makefile.w32-in (SYSWAIT_H): New macro. diff --git a/src/w32proc.c b/src/w32proc.c index fd6a498290a..9b111b40e36 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -1240,7 +1240,6 @@ waitpid (pid_t pid, int *status, int options) else emacs_abort (); -get_result: if (!GetExitCodeProcess (wait_hnd[active], &retval)) { DebPrint (("Wait.GetExitCodeProcess failed with %lu\n", -- cgit v1.2.1 From 552a1590c6bcb0cb5d2be38c2f5ae47d9e6bf1ae Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 17 Nov 2012 18:29:09 -0800 Subject: * nsterm.m (ns_select): Send SIGIO only to self, not to process group. --- src/ChangeLog | 4 ++++ src/nsterm.m | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index b467a35de5f..2a0c0e6822d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2012-11-18 Paul Eggert + + * nsterm.m (ns_select): Send SIGIO only to self, not to process group. + 2012-11-18 Eli Zaretskii * w32select.c: Include w32common.h before w32term.h, so that diff --git a/src/nsterm.m b/src/nsterm.m index 2f400b95c58..57d32ee0528 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3462,10 +3462,10 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds, /* NSTRACE (ns_select); */ - if (hold_event_q.nr > 0) + if (hold_event_q.nr > 0) { /* We already have events pending. */ - kill (0, SIGIO); + raise (SIGIO); errno = EINTR; return -1; } -- cgit v1.2.1 From 00dc3ead070e2e8017629f4d60d8366ac00c32cb Mon Sep 17 00:00:00 2001 From: Kenichi Handa Date: Sun, 18 Nov 2012 20:29:06 +0900 Subject: font.c (font_unparse_xlfd): Fix previous change. Keep "const" for the variable "f". --- src/ChangeLog | 5 +++++ src/font.c | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index ba476cdacba..d7699def9a5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2012-11-18 Kenichi Handa + + * font.c (font_unparse_xlfd): Fix previous change. Keep "const" + for the variable "f". + 2012-11-13 Kenichi Handa * font.c (font_unparse_xlfd): Exclude special characters from the diff --git a/src/font.c b/src/font.c index c57ca3ccec4..f6b6fa026c0 100644 --- a/src/font.c +++ b/src/font.c @@ -1185,7 +1185,7 @@ ptrdiff_t font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes) { char *p; - char *f[XLFD_REGISTRY_INDEX + 1]; + const char *f[XLFD_REGISTRY_INDEX + 1]; Lisp_Object val; int i, j, len; @@ -1241,13 +1241,13 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes) alloc = SBYTES (val) + 1; if (nbytes <= alloc) return -1; - f[j] = alloca (alloc); + f[j] = p = alloca (alloc); /* Copy the name while excluding '-', '?', ',', and '"'. */ for (k = l = 0; k < alloc; k++) { c = SREF (val, k); if (c != '-' && c != '?' && c != ',' && c != '"') - f[j][l++] = c; + p[l++] = c; } } } -- cgit v1.2.1 From 273ac8d1ef96529d010975b59caa99489cbc51b4 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sun, 18 Nov 2012 18:43:36 +0200 Subject: Prevent crashes on MS-Windows when w32-downcase-file-names is non-nil. src/fileio.c (Fsubstitute_in_file_name, Ffile_name_directory) (Fexpand_file_name) [DOS_NT]: Pass encoded file name to dostounix_filename. Prevents crashes down the road, because dostounix_filename assumes it gets a unibyte string. Reported by Michel de Ruiter , see http://lists.gnu.org/archive/html/help-emacs-windows/2012-11/msg00017.html --- src/ChangeLog | 9 +++++++++ src/fileio.c | 46 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index c12eff19ddd..c4f1ee60d84 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2012-11-18 Eli Zaretskii + + * fileio.c (Fsubstitute_in_file_name, Ffile_name_directory) + (Fexpand_file_name) [DOS_NT]: Pass encoded file name to + dostounix_filename. Prevents crashes down the road, because + dostounix_filename assumes it gets a unibyte string. Reported by + Michel de Ruiter , see + http://lists.gnu.org/archive/html/help-emacs-windows/2012-11/msg00017.html + 2012-11-17 Eli Zaretskii * w32select.c: Include w32common.h before w32term.h, so that diff --git a/src/fileio.c b/src/fileio.c index d47d7dd9e0b..a04eb8ecea1 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -315,6 +315,7 @@ Given a Unix syntax file name, returns a string ending in slash. */) register const char *beg; #else register char *beg; + Lisp_Object tem_fn; #endif register const char *p; Lisp_Object handler; @@ -374,10 +375,13 @@ Given a Unix syntax file name, returns a string ending in slash. */) p = beg + strlen (beg); } } - dostounix_filename (beg); -#endif /* DOS_NT */ - + tem_fn = ENCODE_FILE (make_specified_string (beg, -1, p - beg, + STRING_MULTIBYTE (filename))); + dostounix_filename (SSDATA (tem_fn)); + return DECODE_FILE (tem_fn); +#else /* DOS_NT */ return make_specified_string (beg, -1, p - beg, STRING_MULTIBYTE (filename)); +#endif /* DOS_NT */ } DEFUN ("file-name-nondirectory", Ffile_name_nondirectory, @@ -951,7 +955,18 @@ filesystem tree, not (expand-file-name ".." dirname). */) #ifdef DOS_NT /* Make sure directories are all separated with /, but avoid allocation of a new string when not required. */ - dostounix_filename (nm); + if (multibyte) + { + Lisp_Object tem_name = make_specified_string (nm, -1, strlen (nm), + multibyte); + + tem_name = ENCODE_FILE (tem_name); + dostounix_filename (SSDATA (tem_name)); + tem_name = DECODE_FILE (tem_name); + memcpy (nm, SSDATA (tem_name), SBYTES (tem_name) + 1); + } + else + dostounix_filename (nm); #ifdef WINDOWSNT if (IS_DIRECTORY_SEP (nm[1])) { @@ -1305,10 +1320,13 @@ filesystem tree, not (expand-file-name ".." dirname). */) target[0] = '/'; target[1] = ':'; } - dostounix_filename (target); -#endif /* DOS_NT */ - result = make_specified_string (target, -1, o - target, multibyte); + result = ENCODE_FILE (result); + dostounix_filename (SSDATA (result)); + result = DECODE_FILE (result); +#else /* !DOS_NT */ + result = make_specified_string (target, -1, o - target, multibyte); +#endif /* !DOS_NT */ } /* Again look to see if the file name has special constructs in it @@ -1587,8 +1605,18 @@ those `/' is discarded. */) memcpy (nm, SDATA (filename), SBYTES (filename) + 1); #ifdef DOS_NT - dostounix_filename (nm); - substituted = (strcmp (nm, SDATA (filename)) != 0); + { + Lisp_Object encoded_filename = ENCODE_FILE (filename); + Lisp_Object tem_fn; + + dostounix_filename (SDATA (encoded_filename)); + tem_fn = DECODE_FILE (encoded_filename); + nm = alloca (SBYTES (tem_fn) + 1); + memcpy (nm, SDATA (tem_fn), SBYTES (tem_fn) + 1); + substituted = (memcmp (nm, SDATA (filename), SBYTES (filename)) != 0); + if (substituted) + filename = tem_fn; + } #endif endp = nm + SBYTES (filename); -- cgit v1.2.1 From 6e9f7997b36d21004794fa2b8a550729cbabd81a Mon Sep 17 00:00:00 2001 From: Daniel Colascione Date: Sun, 18 Nov 2012 17:39:37 -0800 Subject: Rename cygwin_convert_path* to cygwin_convert_file_name* --- src/ChangeLog | 9 +++++++++ src/cygw32.c | 20 +++++++++++--------- src/w32fns.c | 6 +++--- 3 files changed, 23 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 2a0c0e6822d..89c4e273715 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2012-11-19 Daniel Colascione + + * w32fns.c (Fx_file_dialog): + (Fx_file_dialog): Accomodate rename of cygwin_convert_path* to + cygwin_convert_file_name*. + + * cygw32.c (Fcygwin_convert_path_to_windows, syms_of_cygw32): + Rename cygwin_convert_path* to cygwin_convert_file_name*. + 2012-11-18 Paul Eggert * nsterm.m (ns_select): Send SIGIO only to self, not to process group. diff --git a/src/cygw32.c b/src/cygw32.c index 54f2076a891..d9777d5e22e 100644 --- a/src/cygw32.c +++ b/src/cygw32.c @@ -106,22 +106,24 @@ conv_filename_from_w32_unicode (const wchar_t* in, int absolute_p) return unbind_to (count, DECODE_FILE (converted)); } -DEFUN ("cygwin-convert-path-to-windows", - Fcygwin_convert_path_to_windows, Scygwin_convert_path_to_windows, +DEFUN ("cygwin-convert-file-name-to-windows", + Fcygwin_convert_file_name_to_windows, + Scygwin_convert_file_name_to_windows, 1, 2, 0, - doc: /* Convert PATH to a Windows path. If ABSOLUTE-P if - non-nil, return an absolute path.*/) + doc: /* Convert PATH to a Windows path. If ABSOLUTE-P is +non-nil, return an absolute path.*/) (Lisp_Object path, Lisp_Object absolute_p) { return from_unicode ( conv_filename_to_w32_unicode (path, EQ (absolute_p, Qnil) ? 0 : 1)); } -DEFUN ("cygwin-convert-path-from-windows", - Fcygwin_convert_path_from_windows, Scygwin_convert_path_from_windows, +DEFUN ("cygwin-convert-file-name-from-windows", + Fcygwin_convert_file_name_from_windows, + Scygwin_convert_file_name_from_windows, 1, 2, 0, doc: /* Convert a Windows path to a Cygwin path. If ABSOLUTE-P - if non-nil, return an absolute path.*/) +is non-nil, return an absolute path.*/) (Lisp_Object path, Lisp_Object absolute_p) { return conv_filename_from_w32_unicode (to_unicode (path, &path), @@ -131,6 +133,6 @@ DEFUN ("cygwin-convert-path-from-windows", void syms_of_cygw32 (void) { - defsubr (&Scygwin_convert_path_from_windows); - defsubr (&Scygwin_convert_path_to_windows); + defsubr (&Scygwin_convert_file_name_from_windows); + defsubr (&Scygwin_convert_file_name_to_windows); } diff --git a/src/w32fns.c b/src/w32fns.c index ed5625e802c..90f5b1695ea 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -6167,9 +6167,9 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) filename = empty_unibyte_string; #ifdef CYGWIN - dir = Fcygwin_convert_path_to_windows (dir, Qt); + dir = Fcygwin_convert_file_name_to_windows (dir, Qt); if (SCHARS (filename) > 0) - filename = Fcygwin_convert_path_to_windows (filename, Qnil); + filename = Fcygwin_convert_file_name_to_windows (filename, Qnil); #endif CHECK_STRING (dir); @@ -6270,7 +6270,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) #endif /* NTGUI_UNICODE */ #ifdef CYGWIN - filename = Fcygwin_convert_path_from_windows (filename, Qt); + filename = Fcygwin_convert_file_name_from_windows (filename, Qt); #endif /* CYGWIN */ /* Strip the dummy filename off the end of the string if we -- cgit v1.2.1 From 88c4a13c3b573e0fa844c88ab89765ef308c267e Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 19 Nov 2012 19:34:21 +0200 Subject: More fixes for bug #12878 with MS-Windows MSVC build. src/xdisp.c (start_hourglass) [HAVE_NTGUI]: Don't mix declaration of w32_note_current_window with code. (Backport from trunk.) src/w32.c (FILE_DEVICE_FILE_SYSTEM, METHOD_BUFFERED) (FILE_ANY_ACCESS, CTL_CODE, FSCTL_GET_REPARSE_POINT) [_MSC_VER]: Define for the MSVC compiler. src/w32term.h (EnumSystemLocalesW) [_MSC_VER]: Add a missing semi-colon. nt/inc/stdint.h (PTRDIFF_MIN) [!__GNUC__]: Define for MSVC. --- src/ChangeLog | 12 ++++++++++++ src/w32.c | 13 ++++++++++--- src/w32term.h | 2 +- src/xdisp.c | 6 ++++-- 4 files changed, 27 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index c4f1ee60d84..da5a9607903 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2012-11-19 Eli Zaretskii + + * xdisp.c (start_hourglass) [HAVE_NTGUI]: Don't mix declaration of + w32_note_current_window with code. (Backport from trunk.) + + * w32.c (FILE_DEVICE_FILE_SYSTEM, METHOD_BUFFERED) + (FILE_ANY_ACCESS, CTL_CODE, FSCTL_GET_REPARSE_POINT) [_MSC_VER]: + Define for the MSVC compiler. + + * w32term.h (EnumSystemLocalesW) [_MSC_VER]: Add a missing + semi-colon. + 2012-11-18 Eli Zaretskii * fileio.c (Fsubstitute_in_file_name, Ffile_name_directory) diff --git a/src/w32.c b/src/w32.c index 5ac1bc3eb7c..1c3331516d4 100644 --- a/src/w32.c +++ b/src/w32.c @@ -119,9 +119,10 @@ typedef struct _PROCESS_MEMORY_COUNTERS_EX { #include #ifdef _MSC_VER -/* MSVC doesn't provide the definition of REPARSE_DATA_BUFFER, except - on ntifs.h, which cannot be included because it triggers conflicts - with other Windows API headers. So we define it here by hand. */ +/* MSVC doesn't provide the definition of REPARSE_DATA_BUFFER and the + associated macros, except on ntifs.h, which cannot be included + because it triggers conflicts with other Windows API headers. So + we define it here by hand. */ typedef struct _REPARSE_DATA_BUFFER { ULONG ReparseTag; @@ -149,6 +150,12 @@ typedef struct _REPARSE_DATA_BUFFER { } DUMMYUNIONNAME; } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; +#define FILE_DEVICE_FILE_SYSTEM 9 +#define METHOD_BUFFERED 0 +#define FILE_ANY_ACCESS 0x00000000 +#define CTL_CODE(t,f,m,a) (((t)<<16)|((a)<<14)|((f)<<2)|(m)) +#define FSCTL_GET_REPARSE_POINT \ + CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) #endif /* TCP connection support. */ diff --git a/src/w32term.h b/src/w32term.h index 6e30d374c82..9b5a4a0189a 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -758,7 +758,7 @@ extern int w32_system_caret_y; typedef BOOL (CALLBACK *LOCALE_ENUMPROCA)(LPSTR); typedef BOOL (CALLBACK *LOCALE_ENUMPROCW)(LPWSTR); BOOL WINAPI EnumSystemLocalesA(LOCALE_ENUMPROCA,DWORD); -BOOL WINAPI EnumSystemLocalesW(LOCALE_ENUMPROCW,DWORD) +BOOL WINAPI EnumSystemLocalesW(LOCALE_ENUMPROCW,DWORD); #ifdef UNICODE #define EnumSystemLocales EnumSystemLocalesW #else diff --git a/src/xdisp.c b/src/xdisp.c index 290c3a07fe9..85fe9a00f60 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -29433,8 +29433,10 @@ start_hourglass (void) delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0); #ifdef HAVE_NTGUI - extern void w32_note_current_window (void); - w32_note_current_window (); + { + extern void w32_note_current_window (void); + w32_note_current_window (); + } #endif /* HAVE_NTGUI */ hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay, -- cgit v1.2.1 From 23ba2705e22b89154ef7cbb0595419732080b94c Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Mon, 19 Nov 2012 23:24:09 -0500 Subject: Make called-interactively-p work for edebug or advised code. * lisp/subr.el (called-interactively-p-functions): New var. (internal--called-interactively-p--get-frame): New macro. (called-interactively-p, interactive-p): Rewrite in Lisp. * lisp/emacs-lisp/nadvice.el (advice--called-interactively-skip): New fun. (called-interactively-p-functions): Use it. * lisp/emacs-lisp/edebug.el (edebug--called-interactively-skip): New fun. (called-interactively-p-functions): Use it. * lisp/allout.el (allout-called-interactively-p): Don't assume called-interactively-p is a subr. * src/eval.c (Finteractive_p, Fcalled_interactively_p, interactive_p): Remove. (syms_of_eval): Remove corresponding defsubr. * src/bytecode.c (exec_byte_code): `interactive-p' is now a Lisp function. * test/automated/advice-tests.el (advice-tests--data): Remove. (advice-tests): Move the tests directly here instead. Add called-interactively-p tests. --- src/ChangeLog | 18 ++++++---- src/bytecode.c | 4 ++- src/eval.c | 107 +++------------------------------------------------------ 3 files changed, 20 insertions(+), 109 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 89c4e273715..9e83129e585 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2012-11-20 Stefan Monnier + + * eval.c (Finteractive_p, Fcalled_interactively_p, interactive_p): Remove. + (syms_of_eval): Remove corresponding defsubr. + * bytecode.c (exec_byte_code): `interactive-p' is now a Lisp function. + 2012-11-19 Daniel Colascione * w32fns.c (Fx_file_dialog): @@ -17,10 +23,10 @@ windows.h gets included before w32term.h uses some of its features, see below. - * w32term.h (LOCALE_ENUMPROCA, LOCALE_ENUMPROCW) [_MSC_VER]: New - typedefs. - (EnumSystemLocalesA, EnumSystemLocalesW) [_MSC_VER]: New - prototypes. + * w32term.h (LOCALE_ENUMPROCA, LOCALE_ENUMPROCW) [_MSC_VER]: + New typedefs. + (EnumSystemLocalesA, EnumSystemLocalesW) [_MSC_VER]: + New prototypes. (EnumSystemLocales) [_MSC_VER]: Define if undefined. (Bug#12878) 2012-11-18 Jan Djärv @@ -312,8 +318,8 @@ * xdisp.c (try_scrolling): Fix correction of aggressive-scroll amount when the scroll margins are too large. When scrolling backwards in the buffer, give up if cannot reach point or the - scroll margin within a reasonable number of screen lines. Fixes - point position in window under scroll-up/down-aggressively when + scroll margin within a reasonable number of screen lines. + Fixes point position in window under scroll-up/down-aggressively when point is positioned many lines beyond the window top/bottom. (Bug#12811) diff --git a/src/bytecode.c b/src/bytecode.c index 648813aed86..3267c7c8c76 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -1579,7 +1579,9 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, NEXT; CASE (Binteractive_p): /* Obsolete since 24.1. */ - PUSH (Finteractive_p ()); + BEFORE_POTENTIAL_GC (); + PUSH (call0 (intern ("interactive-p"))); + AFTER_POTENTIAL_GC (); NEXT; CASE (Bforward_char): diff --git a/src/eval.c b/src/eval.c index f8a76646352..459fb762c6e 100644 --- a/src/eval.c +++ b/src/eval.c @@ -489,102 +489,6 @@ usage: (function ARG) */) } -DEFUN ("interactive-p", Finteractive_p, Sinteractive_p, 0, 0, 0, - doc: /* Return t if the containing function was run directly by user input. -This means that the function was called with `call-interactively' -\(which includes being called as the binding of a key) -and input is currently coming from the keyboard (not a keyboard macro), -and Emacs is not running in batch mode (`noninteractive' is nil). - -The only known proper use of `interactive-p' is in deciding whether to -display a helpful message, or how to display it. If you're thinking -of using it for any other purpose, it is quite likely that you're -making a mistake. Think: what do you want to do when the command is -called from a keyboard macro? - -To test whether your function was called with `call-interactively', -either (i) add an extra optional argument and give it an `interactive' -spec that specifies non-nil unconditionally (such as \"p\"); or (ii) -use `called-interactively-p'. */) - (void) -{ - return (INTERACTIVE && interactive_p ()) ? Qt : Qnil; -} - - -DEFUN ("called-interactively-p", Fcalled_interactively_p, Scalled_interactively_p, 0, 1, 0, - doc: /* Return t if the containing function was called by `call-interactively'. -If KIND is `interactive', then only return t if the call was made -interactively by the user, i.e. not in `noninteractive' mode nor -when `executing-kbd-macro'. -If KIND is `any', on the other hand, it will return t for any kind of -interactive call, including being called as the binding of a key, or -from a keyboard macro, or in `noninteractive' mode. - -The only known proper use of `interactive' for KIND is in deciding -whether to display a helpful message, or how to display it. If you're -thinking of using it for any other purpose, it is quite likely that -you're making a mistake. Think: what do you want to do when the -command is called from a keyboard macro? - -Instead of using this function, it is sometimes cleaner to give your -function an extra optional argument whose `interactive' spec specifies -non-nil unconditionally (\"p\" is a good way to do this), or via -\(not (or executing-kbd-macro noninteractive)). */) - (Lisp_Object kind) -{ - return (((INTERACTIVE || !EQ (kind, intern ("interactive"))) - && interactive_p ()) - ? Qt : Qnil); -} - - -/* Return true if function in which this appears was called using - call-interactively and is not a built-in. */ - -static bool -interactive_p (void) -{ - struct backtrace *btp; - Lisp_Object fun; - - btp = backtrace_list; - - /* If this isn't a byte-compiled function, there may be a frame at - the top for Finteractive_p. If so, skip it. */ - fun = Findirect_function (btp->function, Qnil); - if (SUBRP (fun) && (XSUBR (fun) == &Sinteractive_p - || XSUBR (fun) == &Scalled_interactively_p)) - btp = btp->next; - - /* If we're running an Emacs 18-style byte-compiled function, there - may be a frame for Fbytecode at the top level. In any version of - Emacs there can be Fbytecode frames for subexpressions evaluated - inside catch and condition-case. Skip past them. - - If this isn't a byte-compiled function, then we may now be - looking at several frames for special forms. Skip past them. */ - while (btp - && (EQ (btp->function, Qbytecode) - || btp->nargs == UNEVALLED)) - btp = btp->next; - - /* `btp' now points at the frame of the innermost function that isn't - a special form, ignoring frames for Finteractive_p and/or - Fbytecode at the top. If this frame is for a built-in function - (such as load or eval-region) return false. */ - fun = Findirect_function (btp->function, Qnil); - if (SUBRP (fun)) - return 0; - - /* `btp' points to the frame of a Lisp function that called interactive-p. - Return t if that function was called interactively. */ - if (btp && btp->next && EQ (btp->next->function, Qcall_interactively)) - return 1; - return 0; -} - - DEFUN ("defvaralias", Fdefvaralias, Sdefvaralias, 2, 3, 0, doc: /* Make NEW-ALIAS a variable alias for symbol BASE-VARIABLE. Aliased variables always have the same value; setting one sets the other. @@ -696,8 +600,9 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) if (EQ ((--pdl)->symbol, sym) && !pdl->func && EQ (pdl->old_value, Qunbound)) { - message_with_string ("Warning: defvar ignored because %s is let-bound", - SYMBOL_NAME (sym), 1); + message_with_string + ("Warning: defvar ignored because %s is let-bound", + SYMBOL_NAME (sym), 1); break; } } @@ -717,8 +622,8 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) /* A simple (defvar foo) with lexical scoping does "nothing" except declare that var to be dynamically scoped *locally* (i.e. within the current file or let-block). */ - Vinternal_interpreter_environment = - Fcons (sym, Vinternal_interpreter_environment); + Vinternal_interpreter_environment + = Fcons (sym, Vinternal_interpreter_environment); else { /* Simple (defvar ) should not count as a definition at all. @@ -3551,8 +3456,6 @@ alist of active lexical bindings. */); defsubr (&Sunwind_protect); defsubr (&Scondition_case); defsubr (&Ssignal); - defsubr (&Sinteractive_p); - defsubr (&Scalled_interactively_p); defsubr (&Scommandp); defsubr (&Sautoload); defsubr (&Sautoload_do_load); -- cgit v1.2.1 From 952580c5fd273ff9d8f095ab8edb6b116d07eb56 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 20 Nov 2012 11:53:04 +0400 Subject: * xdisp.c (buffer_shared): Adjust comment. (buffer_shared_and_changed): New function. (prepare_menu_bars, redisplay_internal): Use it to decide whether all windows or frames should be updated. --- src/ChangeLog | 7 +++++++ src/xdisp.c | 23 +++++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 9e83129e585..c749b12cae8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2012-11-20 Dmitry Antipov + + * xdisp.c (buffer_shared): Adjust comment. + (buffer_shared_and_changed): New function. + (prepare_menu_bars, redisplay_internal): Use it to + decide whether all windows or frames should be updated. + 2012-11-20 Stefan Monnier * eval.c (Finteractive_p, Fcalled_interactively_p, interactive_p): Remove. diff --git a/src/xdisp.c b/src/xdisp.c index 27d9fff0b7d..618f4dfc585 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -515,9 +515,8 @@ Lisp_Object Qmenu_bar_update_hook; static int overlay_arrow_seen; -/* Number of windows showing the buffer of the selected window (or - another buffer with the same base buffer). keyboard.c refers to - this. */ +/* Number of windows showing the buffer of the selected + window (or another buffer with the same base buffer). */ int buffer_shared; @@ -10889,8 +10888,15 @@ echo_area_display (int update_frame_p) return window_height_changed_p; } +/* True if the current buffer is shown in more than + one window and was modified since last display. */ + +static int +buffer_shared_and_changed (void) +{ + return (buffer_shared > 1 && UNCHANGED_MODIFIED < MODIFF); +} - /*********************************************************************** Mode Lines and Frame Titles ***********************************************************************/ @@ -11196,7 +11202,7 @@ prepare_menu_bars (void) /* Update the menu bar item lists, if appropriate. This has to be done before any actual redisplay or generation of display lines. */ all_windows = (update_mode_lines - || buffer_shared > 1 + || buffer_shared_and_changed () || windows_or_buffers_changed); if (all_windows) { @@ -13116,7 +13122,7 @@ redisplay_internal (void) if ((SAVE_MODIFF < MODIFF) != w->last_had_star) { w->update_mode_line = 1; - if (buffer_shared > 1) + if (buffer_shared_and_changed ()) update_mode_lines++; } @@ -13141,7 +13147,8 @@ redisplay_internal (void) /* The variable buffer_shared is set in redisplay_window and indicates that we redisplay a buffer in different windows. See there. */ - consider_all_windows_p = (update_mode_lines || buffer_shared > 1 + consider_all_windows_p = (update_mode_lines + || buffer_shared_and_changed () || cursor_type_changed); /* If specs for an arrow have changed, do thorough redisplay @@ -13433,7 +13440,7 @@ redisplay_internal (void) } CHARPOS (this_line_start_pos) = 0; - consider_all_windows_p |= buffer_shared > 1; + consider_all_windows_p |= buffer_shared_and_changed (); ++clear_face_cache_count; #ifdef HAVE_WINDOW_SYSTEM ++clear_image_cache_count; -- cgit v1.2.1 From b83fdfa997d54f8b41f23de23103ceda36eca02c Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 20 Nov 2012 00:32:19 -0800 Subject: * eval.c (interactive_p): Remove no-longer-used decl. --- src/ChangeLog | 4 ++++ src/eval.c | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index c749b12cae8..c69452a1f1b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2012-11-20 Paul Eggert + + * eval.c (interactive_p): Remove no-longer-used decl. + 2012-11-20 Dmitry Antipov * xdisp.c (buffer_shared): Adjust comment. diff --git a/src/eval.c b/src/eval.c index 459fb762c6e..053b1a7f097 100644 --- a/src/eval.c +++ b/src/eval.c @@ -114,7 +114,6 @@ Lisp_Object Vsignaling_function; Lisp_Object inhibit_lisp_code; static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *); -static bool interactive_p (void); static Lisp_Object apply_lambda (Lisp_Object fun, Lisp_Object args); /* Functions to set Lisp_Object slots of struct specbinding. */ -- cgit v1.2.1 From ea6de9b1f867a49a1ad062ca54e461cd3b1e003f Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 20 Nov 2012 15:41:57 +0400 Subject: Tiny adjustment around the previous redisplay change. * xdisp.c (window_outdated): New function. (text_outside_line_unchanged_p, redisplay_window): Use it. (redisplay_internal): Likewise. Fix indentation. --- src/ChangeLog | 3 +++ src/xdisp.c | 49 ++++++++++++++++++++++++------------------------- 2 files changed, 27 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index c69452a1f1b..9a2cec8a7fc 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -8,6 +8,9 @@ (buffer_shared_and_changed): New function. (prepare_menu_bars, redisplay_internal): Use it to decide whether all windows or frames should be updated. + (window_outdated): New function. + (text_outside_line_unchanged_p, redisplay_window): Use it. + (redisplay_internal): Likewise. Fix indentation. 2012-11-20 Stefan Monnier diff --git a/src/xdisp.c b/src/xdisp.c index 618f4dfc585..4d359593c75 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10888,7 +10888,7 @@ echo_area_display (int update_frame_p) return window_height_changed_p; } -/* True if the current buffer is shown in more than +/* Nonzero if the current buffer is shown in more than one window and was modified since last display. */ static int @@ -10897,6 +10897,17 @@ buffer_shared_and_changed (void) return (buffer_shared > 1 && UNCHANGED_MODIFIED < MODIFF); } +/* Nonzero if W doesn't reflect the actual state of + current buffer due to its text or overlays change. */ + +static int +window_outdated (struct window *w) +{ + eassert (XBUFFER (w->buffer) == current_buffer); + return (w->last_modified < MODIFF + || w->last_overlay_modified < OVERLAY_MODIFF); +} + /*********************************************************************** Mode Lines and Frame Titles ***********************************************************************/ @@ -12622,8 +12633,7 @@ text_outside_line_unchanged_p (struct window *w, int unchanged_p = 1; /* If text or overlays have changed, see where. */ - if (w->last_modified < MODIFF - || w->last_overlay_modified < OVERLAY_MODIFF) + if (window_outdated (w)) { /* Gap in the line? */ if (GPT < start || Z - GPT < end) @@ -13134,9 +13144,7 @@ redisplay_internal (void) if (!NILP (w->column_number_displayed) /* This alternative quickly identifies a common case where no change is needed. */ - && !(PT == w->last_point - && w->last_modified >= MODIFF - && w->last_overlay_modified >= OVERLAY_MODIFF) + && !(PT == w->last_point && !window_outdated (w)) && (XFASTINT (w->column_number_displayed) != current_column ())) w->update_mode_line = 1; @@ -13198,18 +13206,16 @@ redisplay_internal (void) } } else if (EQ (selected_window, minibuf_window) - && (current_buffer->clip_changed - || w->last_modified < MODIFF - || w->last_overlay_modified < OVERLAY_MODIFF) + && (current_buffer->clip_changed || window_outdated (w)) && resize_mini_window (w, 0)) { /* Resized active mini-window to fit the size of what it is showing if its contents might have changed. */ must_finish = 1; -/* FIXME: this causes all frames to be updated, which seems unnecessary - since only the current frame needs to be considered. This function needs - to be rewritten with two variables, consider_all_windows and - consider_all_frames. */ + /* FIXME: this causes all frames to be updated, which seems unnecessary + since only the current frame needs to be considered. This function + needs to be rewritten with two variables, consider_all_windows and + consider_all_frames. */ consider_all_windows_p = 1; ++windows_or_buffers_changed; ++update_mode_lines; @@ -13264,9 +13270,7 @@ redisplay_internal (void) || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n')) /* Former continuation line has disappeared by becoming empty. */ goto cancel; - else if (w->last_modified < MODIFF - || w->last_overlay_modified < OVERLAY_MODIFF - || MINI_WINDOW_P (w)) + else if (window_outdated (w) || MINI_WINDOW_P (w)) { /* We have to handle the case of continuation around a wide-column character (see the comment in indent.c around @@ -15517,8 +15521,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) = (!NILP (w->window_end_valid) && !current_buffer->clip_changed && !current_buffer->prevent_redisplay_optimizations_p - && w->last_modified >= MODIFF - && w->last_overlay_modified >= OVERLAY_MODIFF); + && !window_outdated (w)); /* Run the window-bottom-change-functions if it is possible that the text on the screen has changed @@ -15540,8 +15543,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) buffer_unchanged_p = (!NILP (w->window_end_valid) && !current_buffer->clip_changed - && w->last_modified >= MODIFF - && w->last_overlay_modified >= OVERLAY_MODIFF); + && !window_outdated (w)); /* When windows_or_buffers_changed is non-zero, we can't rely on the window end being valid, so set it to nil there. */ @@ -15566,9 +15568,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) if (!NILP (w->column_number_displayed) /* This alternative quickly identifies a common case where no change is needed. */ - && !(PT == w->last_point - && w->last_modified >= MODIFF - && w->last_overlay_modified >= OVERLAY_MODIFF) + && !(PT == w->last_point && !window_outdated (w)) && (XFASTINT (w->column_number_displayed) != current_column ())) update_mode_line = 1; @@ -15810,8 +15810,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) && (CHARPOS (startp) < ZV /* Avoid starting at end of buffer. */ || CHARPOS (startp) == BEGV - || (w->last_modified >= MODIFF - && w->last_overlay_modified >= OVERLAY_MODIFF))) + || !window_outdated (w))) { int d1, d2, d3, d4, d5, d6; -- cgit v1.2.1 From 4ffea4478002db1df699a563477ec06000628e77 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Tue, 20 Nov 2012 08:26:40 -0500 Subject: Fix non-GTK builds on Cygwin * src/emacs.c (main): Set the G_SLICE environment variable for all Cygwin builds, not just GTK builds. See https://lists.gnu.org/archive/html/emacs-devel/2012-11/msg00368.html. --- src/ChangeLog | 6 ++++++ src/emacs.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index da5a9607903..3836e32fdbc 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2012-11-20 Ken Brown + + * emacs.c (main): Set the G_SLICE environment variable for all + Cygwin builds, not just GTK builds. See + https://lists.gnu.org/archive/html/emacs-devel/2012-11/msg00368.html. + 2012-11-19 Eli Zaretskii * xdisp.c (start_hourglass) [HAVE_NTGUI]: Don't mix declaration of diff --git a/src/emacs.c b/src/emacs.c index 98e3f11f0cb..f533c3ae983 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -702,7 +702,7 @@ main (int argc, char **argv) stack_base = &dummy; #endif -#if defined (USE_GTK) && defined (G_SLICE_ALWAYS_MALLOC) +#ifdef G_SLICE_ALWAYS_MALLOC /* This is used by the Cygwin build. */ setenv ("G_SLICE", "always-malloc", 1); #endif -- cgit v1.2.1 From a16ac13f6299d2610284a6b3fb4231c3279d2e9c Mon Sep 17 00:00:00 2001 From: Daniel Colascione Date: Tue, 20 Nov 2012 11:28:53 -0800 Subject: Backport: Rename cygwin_convert_path* to cygwin_convert_file_name* --- src/ChangeLog | 9 +++++++++ src/cygw32.c | 20 +++++++++++--------- src/w32fns.c | 6 +++--- 3 files changed, 23 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 3836e32fdbc..f7cb0fe850f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2012-11-20 Daniel Colascione + + * w32fns.c (Fx_file_dialog): + (Fx_file_dialog): Accomodate rename of cygwin_convert_path* to + cygwin_convert_file_name*. + + * cygw32.c (Fcygwin_convert_path_to_windows, syms_of_cygw32): + Rename cygwin_convert_path* to cygwin_convert_file_name*. + 2012-11-20 Ken Brown * emacs.c (main): Set the G_SLICE environment variable for all diff --git a/src/cygw32.c b/src/cygw32.c index 54f2076a891..d9777d5e22e 100644 --- a/src/cygw32.c +++ b/src/cygw32.c @@ -106,22 +106,24 @@ conv_filename_from_w32_unicode (const wchar_t* in, int absolute_p) return unbind_to (count, DECODE_FILE (converted)); } -DEFUN ("cygwin-convert-path-to-windows", - Fcygwin_convert_path_to_windows, Scygwin_convert_path_to_windows, +DEFUN ("cygwin-convert-file-name-to-windows", + Fcygwin_convert_file_name_to_windows, + Scygwin_convert_file_name_to_windows, 1, 2, 0, - doc: /* Convert PATH to a Windows path. If ABSOLUTE-P if - non-nil, return an absolute path.*/) + doc: /* Convert PATH to a Windows path. If ABSOLUTE-P is +non-nil, return an absolute path.*/) (Lisp_Object path, Lisp_Object absolute_p) { return from_unicode ( conv_filename_to_w32_unicode (path, EQ (absolute_p, Qnil) ? 0 : 1)); } -DEFUN ("cygwin-convert-path-from-windows", - Fcygwin_convert_path_from_windows, Scygwin_convert_path_from_windows, +DEFUN ("cygwin-convert-file-name-from-windows", + Fcygwin_convert_file_name_from_windows, + Scygwin_convert_file_name_from_windows, 1, 2, 0, doc: /* Convert a Windows path to a Cygwin path. If ABSOLUTE-P - if non-nil, return an absolute path.*/) +is non-nil, return an absolute path.*/) (Lisp_Object path, Lisp_Object absolute_p) { return conv_filename_from_w32_unicode (to_unicode (path, &path), @@ -131,6 +133,6 @@ DEFUN ("cygwin-convert-path-from-windows", void syms_of_cygw32 (void) { - defsubr (&Scygwin_convert_path_from_windows); - defsubr (&Scygwin_convert_path_to_windows); + defsubr (&Scygwin_convert_file_name_from_windows); + defsubr (&Scygwin_convert_file_name_to_windows); } diff --git a/src/w32fns.c b/src/w32fns.c index aa120d59ce5..d598d66b3a5 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -6151,9 +6151,9 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) filename = empty_unibyte_string; #ifdef CYGWIN - dir = Fcygwin_convert_path_to_windows (dir, Qt); + dir = Fcygwin_convert_file_name_to_windows (dir, Qt); if (SCHARS (filename) > 0) - filename = Fcygwin_convert_path_to_windows (filename, Qnil); + filename = Fcygwin_convert_file_name_to_windows (filename, Qnil); #endif CHECK_STRING (dir); @@ -6254,7 +6254,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) #endif /* NTGUI_UNICODE */ #ifdef CYGWIN - filename = Fcygwin_convert_path_from_windows (filename, Qt); + filename = Fcygwin_convert_file_name_from_windows (filename, Qt); #endif /* CYGWIN */ /* Strip the dummy filename off the end of the string if we -- cgit v1.2.1 From eadf1faa3cb5eea8c25a5166a9a97ebd63525c56 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Tue, 20 Nov 2012 15:06:17 -0500 Subject: Conflate Qnil and Qunbound for `symbol-function'. * src/alloc.c (Fmake_symbol): Initialize `function' to Qnil. * src/lread.c (init_obarray): Set `function' fields to Qnil. * src/eval.c (Fcommandp): Ignore Qunbound. (Fautoload, eval_sub, Fapply, Ffuncall, Fmacroexpand): * src/data.c (Ffset, Ffboundp, indirect_function, Findirect_function): Test NILP rather than Qunbound. (Ffmakunbound): Set to Qnil. (Fsymbol_function): Never signal an error. (Finteractive_form): Ignore Qunbound. --- src/ChangeLog | 13 +++++++++++++ src/alloc.c | 4 ++-- src/data.c | 21 ++++++++++----------- src/eval.c | 24 ++++++++++++------------ src/lisp.h | 2 +- src/lread.c | 3 ++- 6 files changed, 40 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 9a2cec8a7fc..332656fcf00 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2012-11-20 Stefan Monnier + + Conflate Qnil and Qunbound for `symbol-function'. + * alloc.c (Fmake_symbol): Initialize `function' to Qnil. + * lread.c (init_obarray): Set `function' fields to Qnil. + * eval.c (Fcommandp): Ignore Qunbound. + (Fautoload, eval_sub, Fapply, Ffuncall, Fmacroexpand): + * data.c (Ffset, Ffboundp, indirect_function, Findirect_function): + Test NILP rather than Qunbound. + (Ffmakunbound): Set to Qnil. + (Fsymbol_function): Never signal an error. + (Finteractive_form): Ignore Qunbound. + 2012-11-20 Paul Eggert * eval.c (interactive_p): Remove no-longer-used decl. diff --git a/src/alloc.c b/src/alloc.c index a66a752f5dc..22e3db3cc77 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -3212,7 +3212,7 @@ static struct Lisp_Symbol *symbol_free_list; DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, doc: /* Return a newly allocated uninterned symbol whose name is NAME. -Its value and function definition are void, and its property list is nil. */) +Its value is void, and its function definition and property list are nil. */) (Lisp_Object name) { register Lisp_Object val; @@ -3249,7 +3249,7 @@ Its value and function definition are void, and its property list is nil. */) set_symbol_plist (val, Qnil); p->redirect = SYMBOL_PLAINVAL; SET_SYMBOL_VAL (p, Qunbound); - set_symbol_function (val, Qunbound); + set_symbol_function (val, Qnil); set_symbol_next (val, NULL); p->gcmarkbit = 0; p->interned = SYMBOL_UNINTERNED; diff --git a/src/data.c b/src/data.c index 09899400b68..5fc6afaaa03 100644 --- a/src/data.c +++ b/src/data.c @@ -543,12 +543,13 @@ DEFUN ("boundp", Fboundp, Sboundp, 1, 1, 0, return (EQ (valcontents, Qunbound) ? Qnil : Qt); } +/* FIXME: Make it an alias for function-symbol! */ DEFUN ("fboundp", Ffboundp, Sfboundp, 1, 1, 0, doc: /* Return t if SYMBOL's function definition is not void. */) (register Lisp_Object symbol) { CHECK_SYMBOL (symbol); - return EQ (XSYMBOL (symbol)->function, Qunbound) ? Qnil : Qt; + return NILP (XSYMBOL (symbol)->function) ? Qnil : Qt; } DEFUN ("makunbound", Fmakunbound, Smakunbound, 1, 1, 0, @@ -564,14 +565,14 @@ Return SYMBOL. */) } DEFUN ("fmakunbound", Ffmakunbound, Sfmakunbound, 1, 1, 0, - doc: /* Make SYMBOL's function definition be void. + doc: /* Make SYMBOL's function definition be nil. Return SYMBOL. */) (register Lisp_Object symbol) { CHECK_SYMBOL (symbol); if (NILP (symbol) || EQ (symbol, Qt)) xsignal1 (Qsetting_constant, symbol); - set_symbol_function (symbol, Qunbound); + set_symbol_function (symbol, Qnil); return symbol; } @@ -580,9 +581,7 @@ DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0, (register Lisp_Object symbol) { CHECK_SYMBOL (symbol); - if (!EQ (XSYMBOL (symbol)->function, Qunbound)) return XSYMBOL (symbol)->function; - xsignal1 (Qvoid_function, symbol); } DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0, @@ -613,7 +612,7 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0, function = XSYMBOL (symbol)->function; - if (!NILP (Vautoload_queue) && !EQ (function, Qunbound)) + if (!NILP (Vautoload_queue) && !NILP (function)) Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue); if (AUTOLOADP (function)) @@ -714,7 +713,7 @@ Value, if non-nil, is a list \(interactive SPEC). */) { Lisp_Object fun = indirect_function (cmd); /* Check cycles. */ - if (NILP (fun) || EQ (fun, Qunbound)) + if (NILP (fun)) return Qnil; /* Use an `interactive-form' property if present, analogous to the @@ -2008,10 +2007,10 @@ indirect_function (register Lisp_Object object) for (;;) { - if (!SYMBOLP (hare) || EQ (hare, Qunbound)) + if (!SYMBOLP (hare) || NILP (hare)) break; hare = XSYMBOL (hare)->function; - if (!SYMBOLP (hare) || EQ (hare, Qunbound)) + if (!SYMBOLP (hare) || NILP (hare)) break; hare = XSYMBOL (hare)->function; @@ -2038,10 +2037,10 @@ function chain of symbols. */) /* Optimize for no indirection. */ result = object; - if (SYMBOLP (result) && !EQ (result, Qunbound) + if (SYMBOLP (result) && !NILP (result) && (result = XSYMBOL (result)->function, SYMBOLP (result))) result = indirect_function (result); - if (!EQ (result, Qunbound)) + if (!NILP (result)) return result; if (NILP (noerror)) diff --git a/src/eval.c b/src/eval.c index 053b1a7f097..34b20f6fc8e 100644 --- a/src/eval.c +++ b/src/eval.c @@ -875,7 +875,7 @@ definitions to shadow the loaded ones for use in file byte-compilation. */) if (NILP (tem)) { def = XSYMBOL (sym)->function; - if (!EQ (def, Qunbound)) + if (!NILP (def)) continue; } break; @@ -890,7 +890,7 @@ definitions to shadow the loaded ones for use in file byte-compilation. */) GCPRO1 (form); def = Fautoload_do_load (def, sym, Qmacro); UNGCPRO; - if (EQ (def, Qunbound) || !CONSP (def)) + if (!CONSP (def)) /* Not defined or definition not suitable. */ break; if (!EQ (XCAR (def), Qmacro)) @@ -1715,12 +1715,12 @@ then strings and vectors are not accepted. */) fun = function; - fun = indirect_function (fun); /* Check cycles. */ - if (NILP (fun) || EQ (fun, Qunbound)) + fun = indirect_function (fun); /* Check cycles. */ + if (NILP (fun)) return Qnil; /* Check an `interactive-form' property if present, analogous to the - function-documentation property. */ + function-documentation property. */ fun = function; while (SYMBOLP (fun)) { @@ -1780,7 +1780,7 @@ this does nothing and returns nil. */) CHECK_STRING (file); /* If function is defined and not as an autoload, don't override. */ - if (!EQ (XSYMBOL (function)->function, Qunbound) + if (!NILP (XSYMBOL (function)->function) && !AUTOLOADP (XSYMBOL (function)->function)) return Qnil; @@ -1959,7 +1959,7 @@ eval_sub (Lisp_Object form) /* Optimize for no indirection. */ fun = original_fun; - if (SYMBOLP (fun) && !EQ (fun, Qunbound) + if (SYMBOLP (fun) && !NILP (fun) && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) fun = indirect_function (fun); @@ -2081,7 +2081,7 @@ eval_sub (Lisp_Object form) val = apply_lambda (fun, original_args); else { - if (EQ (fun, Qunbound)) + if (NILP (fun)) xsignal1 (Qvoid_function, original_fun); if (!CONSP (fun)) xsignal1 (Qinvalid_function, original_fun); @@ -2155,10 +2155,10 @@ usage: (apply FUNCTION &rest ARGUMENTS) */) numargs += nargs - 2; /* Optimize for no indirection. */ - if (SYMBOLP (fun) && !EQ (fun, Qunbound) + if (SYMBOLP (fun) && !NILP (fun) && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) fun = indirect_function (fun); - if (EQ (fun, Qunbound)) + if (NILP (fun)) { /* Let funcall get the error. */ fun = args[0]; @@ -2632,7 +2632,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) /* Optimize for no indirection. */ fun = original_fun; - if (SYMBOLP (fun) && !EQ (fun, Qunbound) + if (SYMBOLP (fun) && !NILP (fun) && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) fun = indirect_function (fun); @@ -2720,7 +2720,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) val = funcall_lambda (fun, numargs, args + 1); else { - if (EQ (fun, Qunbound)) + if (NILP (fun)) xsignal1 (Qvoid_function, original_fun); if (!CONSP (fun)) xsignal1 (Qinvalid_function, original_fun); diff --git a/src/lisp.h b/src/lisp.h index 67ae28a488f..4817c6eb990 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1104,7 +1104,7 @@ struct Lisp_Symbol union Lisp_Fwd *fwd; } val; - /* Function value of the symbol or Qunbound if not fboundp. */ + /* Function value of the symbol or Qnil if not fboundp. */ Lisp_Object function; /* The symbol's property list. */ diff --git a/src/lread.c b/src/lread.c index 5859a2f85a9..6d0ff9f780e 100644 --- a/src/lread.c +++ b/src/lread.c @@ -3957,12 +3957,13 @@ init_obarray (void) /* Fmake_symbol inits fields of new symbols with Qunbound and Qnil, so those two need to be fixed manually. */ SET_SYMBOL_VAL (XSYMBOL (Qunbound), Qunbound); - set_symbol_function (Qunbound, Qunbound); + set_symbol_function (Qunbound, Qnil); set_symbol_plist (Qunbound, Qnil); SET_SYMBOL_VAL (XSYMBOL (Qnil), Qnil); XSYMBOL (Qnil)->constant = 1; XSYMBOL (Qnil)->declared_special = 1; set_symbol_plist (Qnil, Qnil); + set_symbol_function (Qnil, Qnil); Qt = intern_c_string ("t"); SET_SYMBOL_VAL (XSYMBOL (Qt), Qt); -- cgit v1.2.1 From 954bba56c62e4e0637a933cf21626a55b873e144 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Wed, 21 Nov 2012 11:34:35 -0500 Subject: * src/xdisp.c (fast_set_selected_frame): Rename from update_tool_bar_unwind. Make it set selected_window as well. (update_tool_bar): Use it. --- src/ChangeLog | 6 ++++++ src/xdisp.c | 21 ++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index c16a4dc87ce..b1a76bfdae0 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2012-11-21 Stefan Monnier + + * xdisp.c (fast_set_selected_frame): Rename from update_tool_bar_unwind. + Make it set selected_window as well. + (update_tool_bar): Use it. + 2012-11-21 Ken Brown * emacs.c (main): Set the G_SLICE environment variable for all diff --git a/src/xdisp.c b/src/xdisp.c index 4d359593c75..f0da28fcedd 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -11484,11 +11484,18 @@ FRAME_PTR last_mouse_frame; int last_tool_bar_item; - +/* Select `frame' temporarily without running all the code in + do_switch_frame. + FIXME: Maybe do_switch_frame should be trimmed down similarly + when `norecord' is set. */ static Lisp_Object -update_tool_bar_unwind (Lisp_Object frame) +fast_set_selected_frame (Lisp_Object frame) { - selected_frame = frame; + if (!EQ (selected_frame, frame)) + { + selected_frame = frame; + selected_window = XFRAME (frame)->selected_window; + } return Qnil; } @@ -11560,9 +11567,13 @@ update_tool_bar (struct frame *f, int save_match_data) before calling tool_bar_items, because the calculation of the tool-bar keymap uses the selected frame (see `tool-bar-make-keymap' in tool-bar.el). */ - record_unwind_protect (update_tool_bar_unwind, selected_frame); + eassert (EQ (selected_window, + /* Since we only explicitly preserve selected_frame, + check that selected_window would be redundant. */ + XFRAME (selected_frame)->selected_window)); + record_unwind_protect (fast_set_selected_frame, selected_frame); XSETFRAME (frame, f); - selected_frame = frame; + fast_set_selected_frame (frame); /* Build desired tool-bar items from keymaps. */ new_tool_bar -- cgit v1.2.1 From cb5867b1f8af39ffd70767fc06fd364bca67e968 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 21 Nov 2012 21:28:14 +0200 Subject: Fix bug #12930 with vertical-motion through a display string. src/indent.c (Fvertical_motion): If the starting position is covered by a display string, return to one position before that, to avoid overshooting it inside move_it_to. --- src/ChangeLog | 6 ++++++ src/indent.c | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index f7cb0fe850f..f760adf313f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2012-11-21 Eli Zaretskii + + * indent.c (Fvertical_motion): If the starting position is covered + by a display string, return to one position before that, to avoid + overshooting it inside move_it_to. (Bug#12930) + 2012-11-20 Daniel Colascione * w32fns.c (Fx_file_dialog): diff --git a/src/indent.c b/src/indent.c index bbc944d2518..33322287c9d 100644 --- a/src/indent.c +++ b/src/indent.c @@ -2057,7 +2057,13 @@ whether or not it is currently displayed in some window. */) comment said this is "so we don't move too far" (2005-01-19 checkin by kfs). But this does nothing useful that I can tell, and it causes Bug#2694 . -- cyd */ - move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); + /* When the position we started from is covered by a display + string, move_it_to will overshoot it, while vertical-motion + wants to put the cursor _before_ the display string. So in + that case, we move to buffer position before the display + string, and avoid overshooting. */ + move_it_to (&it, disp_string_at_start_p ? PT - 1 : PT, + -1, -1, -1, MOVE_TO_POS); /* IT may move too far if truncate-lines is on and PT lies beyond the right margin. IT may also move too far if the -- cgit v1.2.1 From 9239d970523919dfcf7437f728f4976b3a9467f3 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 21 Nov 2012 13:06:52 -0800 Subject: Assume POSIX 1003.1-1988 or later for unistd.h. * admin/CPP-DEFINES (BROKEN_GETWD, HAVE_GETCWD, HAVE_GETWD, HAVE_SIZE_T) (HAVE_UNISTD_H): Remove. * configure.ac: Do not check for getcwd or getwd. * lib-src/emacsclient.c (getcwd): Remove decl. (get_current_dir_name): Assume getcwd exists. * lib-src/etags.c (HAVE_GETCWD): Remove. (getcwd): Remove decl. (NO_LONG_OPTIONS): Remove this. All uses removed. Emacs always has GNU getopt. (etags_getcwd): Assume getcwd exists. * lib-src/movemail.c (F_OK, X_OK, W_OK, R_OK): Remove. * nt/config.nt (HAVE_GETCWD): Remove. * src/alloc.c: Assume unistd.h exists. * src/fileio.c (Fexpand_file_name) [DOS_NT]: Use getcwd, not getwd. * src/sysdep.c (get_current_dir_name): Assume getcwd exists. (getwd) [USG]: Remove; no longer needed. (sys_subshell) [DOS_NT]: Use getcwd, not getwd. * src/w32.c (getcwd): Rename from getwd, and switch to getcwd's API. * src/w32.h (getcwd): Remove decl. Fixes: debbugs:12945 --- src/ChangeLog | 11 ++++++++ src/alloc.c | 4 --- src/fileio.c | 2 +- src/sysdep.c | 80 +++-------------------------------------------------------- src/w32.c | 14 +++++++++-- src/w32.h | 2 -- 6 files changed, 28 insertions(+), 85 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index b1a76bfdae0..9e9ae468044 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,14 @@ +2012-11-21 Paul Eggert + + Assume POSIX 1003.1-1988 or later for unistd.h (Bug#12945). + * alloc.c: Assume unistd.h exists. + * fileio.c (Fexpand_file_name) [DOS_NT]: Use getcwd, not getwd. + * sysdep.c (get_current_dir_name): Assume getcwd exists. + (getwd) [USG]: Remove; no longer needed. + (sys_subshell) [DOS_NT]: Use getcwd, not getwd. + * w32.c (getcwd): Rename from getwd, and switch to getcwd's API. + * w32.h (getcwd): Remove decl. + 2012-11-21 Stefan Monnier * xdisp.c (fast_set_selected_frame): Rename from update_tool_bar_unwind. diff --git a/src/alloc.c b/src/alloc.c index 22e3db3cc77..46b2dde93a3 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -63,10 +63,6 @@ along with GNU Emacs. If not, see . */ #endif #include -#ifndef HAVE_UNISTD_H -extern void *sbrk (); -#endif - #include #ifdef USE_GTK diff --git a/src/fileio.c b/src/fileio.c index e1a7cf55e28..442c66550d3 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -1148,7 +1148,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) newdir = "/"; } else - getwd (adir); + getcwd (adir, MAXPATHLEN + 1); newdir = adir; } diff --git a/src/sysdep.c b/src/sysdep.c index 7c5c144fa8c..3dd19685540 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -101,7 +101,6 @@ along with GNU Emacs. If not, see . */ #define _P_WAIT 0 int _cdecl _spawnlp (int, const char *, const char *, ...); int _cdecl _getpid (void); -extern char *getwd (char *); #endif #include "syssignal.h" @@ -134,12 +133,12 @@ char* get_current_dir_name (void) { char *buf; - char *pwd; + char *pwd = getenv ("PWD"); struct stat dotstat, pwdstat; - /* If PWD is accurate, use it instead of calling getwd. PWD is + /* If PWD is accurate, use it instead of calling getcwd. PWD is sometimes a nicer name, and using it may avoid a fatal error if a parent directory is searchable but not readable. */ - if ((pwd = getenv ("PWD")) != 0 + if (pwd && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1]))) && stat (pwd, &pwdstat) == 0 && stat (".", &dotstat) == 0 @@ -155,7 +154,6 @@ get_current_dir_name (void) return NULL; strcpy (buf, pwd); } -#ifdef HAVE_GETCWD else { size_t buf_size = 1024; @@ -179,22 +177,6 @@ get_current_dir_name (void) return NULL; } } -#else - else - { - /* We need MAXPATHLEN here. */ - buf = malloc (MAXPATHLEN + 1); - if (!buf) - return NULL; - if (getwd (buf) == NULL) - { - int tmp_errno = errno; - free (buf); - errno = tmp_errno; - return NULL; - } - } -#endif return buf; } #endif @@ -521,7 +503,7 @@ sys_subshell (void) const char *sh = 0; #ifdef DOS_NT /* MW, Aug 1993 */ - getwd (oldwd); + getcwd (oldwd, sizeof oldwd); if (sh == 0) sh = (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */ #endif @@ -2238,60 +2220,6 @@ emacs_readlink (char const *filename, char initial_buf[READLINK_BUFSIZE]) &emacs_norealloc_allocator, careadlinkatcwd); } -#ifdef USG -/* - * All of the following are for USG. - * - * On USG systems the system calls are INTERRUPTIBLE by signals - * that the user program has elected to catch. Thus the system call - * must be retried in these cases. To handle this without massive - * changes in the source code, we remap the standard system call names - * to names for our own functions in sysdep.c that do the system call - * with retries. Actually, for portability reasons, it is good - * programming practice, as this example shows, to limit all actual - * system calls to a single occurrence in the source. Sure, this - * adds an extra level of function call overhead but it is almost - * always negligible. Fred Fish, Unisoft Systems Inc. - */ - -/* - * Warning, this function may not duplicate 4.2 action properly - * under error conditions. - */ - -#if !defined (HAVE_GETWD) || defined (BROKEN_GETWD) - -#ifndef MAXPATHLEN -/* In 4.1, param.h fails to define this. */ -#define MAXPATHLEN 1024 -#endif - -char * -getwd (char *pathname) -{ - char *npath, *spath; - extern char *getcwd (char *, size_t); - - block_input (); /* getcwd uses malloc */ - spath = npath = getcwd ((char *) 0, MAXPATHLEN); - if (spath == 0) - { - unblock_input (); - return spath; - } - /* On Altos 3068, getcwd can return @hostname/dir, so discard - up to first slash. Should be harmless on other systems. */ - while (*npath && *npath != '/') - npath++; - strcpy (pathname, npath); - free (spath); /* getcwd uses malloc */ - unblock_input (); - return pathname; -} - -#endif /* !defined (HAVE_GETWD) || defined (BROKEN_GETWD) */ -#endif /* USG */ - /* Directory routines for systems that don't have them. */ #ifdef HAVE_DIRENT_H diff --git a/src/w32.c b/src/w32.c index b51022c6001..da778eb8541 100644 --- a/src/w32.c +++ b/src/w32.c @@ -908,8 +908,18 @@ static char startup_dir[MAXPATHLEN]; /* Get the current working directory. */ char * -getwd (char *dir) +getcwd (char *dir, size_t dirsize) { + if (!dirsize) + { + errno = EINVAL; + return NULL; + } + if (dirsize <= strlen (startup_dir)) + { + errno = ERANGE; + return NULL; + } #if 0 if (GetCurrentDirectory (MAXPATHLEN, dir) > 0) return dir; @@ -1825,7 +1835,7 @@ init_environment (char ** argv) memcpy (*envp, "COMSPEC=", 8); } - /* Remember the initial working directory for getwd. */ + /* Remember the initial working directory for getcwd. */ /* FIXME: Do we need to resolve possible symlinks in startup_dir? Does it matter anywhere in Emacs? */ if (!GetCurrentDirectory (MAXPATHLEN, startup_dir)) diff --git a/src/w32.h b/src/w32.h index 8309a3cc23d..23eda830268 100644 --- a/src/w32.h +++ b/src/w32.h @@ -163,7 +163,6 @@ extern int sys_spawnve (int, char *, char **, char **); extern void register_child (int, int); extern void sys_sleep (int); -extern char *getwd (char *); extern int sys_link (const char *, const char *); @@ -181,4 +180,3 @@ extern ssize_t emacs_gnutls_push (gnutls_transport_ptr_t p, #endif /* HAVE_GNUTLS */ #endif /* EMACS_W32_H */ - -- cgit v1.2.1 From ec84768f9754d5943610cbbd048dc4d4a46d847f Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 22 Nov 2012 05:56:38 +0200 Subject: Fix MS-Windows build following 2012-11-21T21:06:52Z!eggert@cs.ucla.edu. src/w32.c (getcwd): Fix the 2nd argument type, to prevent conflicts with Windows system header. Fixes: debbugs:12945 --- src/ChangeLog | 5 +++++ src/w32.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 9e9ae468044..3587a9e295b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2012-11-22 Eli Zaretskii + + * w32.c (getcwd): Fix the 2nd argument type, to prevent conflicts + with Windows system header. + 2012-11-21 Paul Eggert Assume POSIX 1003.1-1988 or later for unistd.h (Bug#12945). diff --git a/src/w32.c b/src/w32.c index da778eb8541..038a442f529 100644 --- a/src/w32.c +++ b/src/w32.c @@ -908,7 +908,7 @@ static char startup_dir[MAXPATHLEN]; /* Get the current working directory. */ char * -getcwd (char *dir, size_t dirsize) +getcwd (char *dir, int dirsize) { if (!dirsize) { -- cgit v1.2.1 From 6ceeb5f14411ed388979d0bb944c06e36756f9af Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 22 Nov 2012 10:52:30 +0400 Subject: * xdisp.c (window_buffer_changed): New function. (update_menu_bar, update_tool_bar): Use it to simplify large 'if' statements. (redisplay_internal): Generalize commonly used 'tail' and 'frame' local variables. --- src/ChangeLog | 8 +++++++ src/xdisp.c | 74 ++++++++++++++++++++++++++--------------------------------- 2 files changed, 40 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 3587a9e295b..4a4572bdd63 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2012-11-22 Dmitry Antipov + + * xdisp.c (window_buffer_changed): New function. + (update_menu_bar, update_tool_bar): Use it to + simplify large 'if' statements. + (redisplay_internal): Generalize commonly used + 'tail' and 'frame' local variables. + 2012-11-22 Eli Zaretskii * w32.c (getcwd): Fix the 2nd argument type, to prevent conflicts diff --git a/src/xdisp.c b/src/xdisp.c index f0da28fcedd..e9b20d148c7 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10908,6 +10908,21 @@ window_outdated (struct window *w) || w->last_overlay_modified < OVERLAY_MODIFF); } +/* Nonzero if W's buffer was changed but not saved or Transient Mark mode + is enabled and mark of W's buffer was changed since last W's update. */ + +static int +window_buffer_changed (struct window *w) +{ + struct buffer *b = XBUFFER (w->buffer); + + eassert (BUFFER_LIVE_P (b)); + + return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star) + || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active))) + != !NILP (w->region_showing))); +} + /*********************************************************************** Mode Lines and Frame Titles ***********************************************************************/ @@ -11327,12 +11342,7 @@ update_menu_bar (struct frame *f, int save_match_data, int hooks_run) /* This used to test w->update_mode_line, but we believe there is no need to recompute the menu in that case. */ || update_mode_lines - || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer)) - < BUF_MODIFF (XBUFFER (w->buffer))) - != w->last_had_star) - || ((!NILP (Vtransient_mark_mode) - && !NILP (BVAR (XBUFFER (w->buffer), mark_active))) - != !NILP (w->region_showing))) + || window_buffer_changed (w)) { struct buffer *prev = current_buffer; ptrdiff_t count = SPECPDL_INDEX (); @@ -11532,12 +11542,7 @@ update_tool_bar (struct frame *f, int save_match_data) if (windows_or_buffers_changed || w->update_mode_line || update_mode_lines - || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer)) - < BUF_MODIFF (XBUFFER (w->buffer))) - != w->last_had_star) - || ((!NILP (Vtransient_mark_mode) - && !NILP (BVAR (XBUFFER (w->buffer), mark_active))) - != !NILP (w->region_showing))) + || window_buffer_changed (w)) { struct buffer *prev = current_buffer; ptrdiff_t count = SPECPDL_INDEX (); @@ -12988,7 +12993,7 @@ redisplay_internal (void) ptrdiff_t count, count1; struct frame *sf; int polling_stopped_here = 0; - Lisp_Object old_frame = selected_frame; + Lisp_Object tail, frame, old_frame = selected_frame; struct backtrace backtrace; /* Non-zero means redisplay has to consider all windows on all @@ -13040,15 +13045,8 @@ redisplay_internal (void) backtrace.debug_on_exit = 0; backtrace_list = &backtrace; - { - Lisp_Object tail, frame; - - FOR_EACH_FRAME (tail, frame) - { - struct frame *f = XFRAME (frame); - f->already_hscrolled_p = 0; - } - } + FOR_EACH_FRAME (tail, frame) + XFRAME (frame)->already_hscrolled_p = 0; retry: /* Remember the currently selected window. */ @@ -13098,25 +13096,20 @@ redisplay_internal (void) FRAME_TTY (sf)->previous_frame = sf; } - /* Set the visible flags for all frames. Do this before checking - for resized or garbaged frames; they want to know if their frames - are visible. See the comment in frame.h for - FRAME_SAMPLE_VISIBILITY. */ - { - Lisp_Object tail, frame; - - number_of_visible_frames = 0; + /* Set the visible flags for all frames. Do this before checking for + resized or garbaged frames; they want to know if their frames are + visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */ + number_of_visible_frames = 0; - FOR_EACH_FRAME (tail, frame) - { - struct frame *f = XFRAME (frame); + FOR_EACH_FRAME (tail, frame) + { + struct frame *f = XFRAME (frame); - FRAME_SAMPLE_VISIBILITY (f); - if (FRAME_VISIBLE_P (f)) - ++number_of_visible_frames; - clear_desired_matrices (f); - } - } + FRAME_SAMPLE_VISIBILITY (f); + if (FRAME_VISIBLE_P (f)) + ++number_of_visible_frames; + clear_desired_matrices (f); + } /* Notice any pending interrupt request to change frame size. */ do_pending_window_change (1); @@ -13467,8 +13460,6 @@ redisplay_internal (void) if (consider_all_windows_p) { - Lisp_Object tail, frame; - FOR_EACH_FRAME (tail, frame) XFRAME (frame)->updated_p = 0; @@ -13678,7 +13669,6 @@ redisplay_internal (void) frames here explicitly. */ if (!pending) { - Lisp_Object tail, frame; int new_count = 0; FOR_EACH_FRAME (tail, frame) -- cgit v1.2.1 From 5c74767510841c8afc35f66f5cb068fe99f29615 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 22 Nov 2012 13:32:32 +0400 Subject: * alloc.c (Fgarbage_collect): Unblock input after clearing gc_in_progress to avoid note_mouse_highlight glitch with GC. * frame.h (FRAME_MOUSE_UPDATE): New macro. * msdos.c (IT_frame_up_to_date): Use it here... * w32term.c (w32_frame_up_to_date): ...here... * xterm.c (XTframe_up_to_date): ...and here... * nsterm.m (ns_frame_up_to_date): ...but not here. * lisp.h (Mouse_HLInfo): Remove mouse_face_deferred_gc member. Adjust users. * xdisp.c (message2_nolog, message3_nolog, note_mouse_highlight): Do not check whether GC is in progress. --- src/ChangeLog | 14 ++++++++++++++ src/alloc.c | 4 ++-- src/frame.h | 15 +++++++++++++++ src/lisp.h | 4 ---- src/msdos.c | 15 +-------------- src/nsterm.m | 25 ++++++++++--------------- src/w32term.c | 17 +---------------- src/xdisp.c | 10 ++-------- src/xterm.c | 18 +----------------- 9 files changed, 46 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 4a4572bdd63..2e485f1b87b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2012-11-22 Dmitry Antipov + + * alloc.c (Fgarbage_collect): Unblock input after clearing + gc_in_progress to avoid note_mouse_highlight glitch with GC. + * frame.h (FRAME_MOUSE_UPDATE): New macro. + * msdos.c (IT_frame_up_to_date): Use it here... + * w32term.c (w32_frame_up_to_date): ...here... + * xterm.c (XTframe_up_to_date): ...and here... + * nsterm.m (ns_frame_up_to_date): ...but not here. + * lisp.h (Mouse_HLInfo): Remove mouse_face_deferred_gc member. + Adjust users. + * xdisp.c (message2_nolog, message3_nolog, note_mouse_highlight): + Do not check whether GC is in progress. + 2012-11-22 Dmitry Antipov * xdisp.c (window_buffer_changed): New function. diff --git a/src/alloc.c b/src/alloc.c index 46b2dde93a3..28c9b51dab4 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -5331,12 +5331,12 @@ See Info node `(elisp)Garbage Collection'. */) dump_zombies (); #endif - unblock_input (); - check_cons_list (); gc_in_progress = 0; + unblock_input (); + consing_since_gc = 0; if (gc_cons_threshold < GC_DEFAULT_THRESHOLD / 10) gc_cons_threshold = GC_DEFAULT_THRESHOLD / 10; diff --git a/src/frame.h b/src/frame.h index 35cbc44becc..87c4fcb0555 100644 --- a/src/frame.h +++ b/src/frame.h @@ -933,6 +933,21 @@ typedef struct frame *FRAME_PTR; && (frame_var = XCAR (list_var), 1)); \ list_var = XCDR (list_var)) +/* Reflect mouse movement when a complete frame update is performed. */ + +#define FRAME_MOUSE_UPDATE(frame) \ + do { \ + Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (frame); \ + if (frame == hlinfo->mouse_face_mouse_frame) \ + { \ + block_input (); \ + if (hlinfo->mouse_face_mouse_frame) \ + note_mouse_highlight (hlinfo->mouse_face_mouse_frame, \ + hlinfo->mouse_face_mouse_x, \ + hlinfo->mouse_face_mouse_y); \ + unblock_input (); \ + } \ + } while (0) extern Lisp_Object Qframep, Qframe_live_p; extern Lisp_Object Qtty, Qtty_type; diff --git a/src/lisp.h b/src/lisp.h index 4817c6eb990..419176d06c8 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1649,10 +1649,6 @@ typedef struct { int mouse_face_face_id; Lisp_Object mouse_face_overlay; - /* 1 if a mouse motion event came and we didn't handle it right away because - gc was in progress. */ - int mouse_face_deferred_gc; - /* FRAME and X, Y position of mouse when last checked for highlighting. X and Y can be negative or out of range for the frame. */ struct frame *mouse_face_mouse_frame; diff --git a/src/msdos.c b/src/msdos.c index dd05a8b2c5d..433bf1074d8 100644 --- a/src/msdos.c +++ b/src/msdos.c @@ -1275,7 +1275,6 @@ IT_update_begin (struct frame *f) hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; hlinfo->mouse_face_window = Qnil; - hlinfo->mouse_face_deferred_gc = 0; hlinfo->mouse_face_mouse_frame = NULL; } @@ -1295,21 +1294,10 @@ IT_update_end (struct frame *f) static void IT_frame_up_to_date (struct frame *f) { - Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); Lisp_Object new_cursor, frame_desired_cursor; struct window *sw; - if (hlinfo->mouse_face_deferred_gc - || (f && f == hlinfo->mouse_face_mouse_frame)) - { - block_input (); - if (hlinfo->mouse_face_mouse_frame) - note_mouse_highlight (hlinfo->mouse_face_mouse_frame, - hlinfo->mouse_face_mouse_x, - hlinfo->mouse_face_mouse_y); - hlinfo->mouse_face_deferred_gc = 0; - unblock_input (); - } + FRAME_MOUSE_UPDATE (f); /* Set the cursor type to whatever they wanted. In a minibuffer window, we want the cursor to appear only if we are reading input @@ -1849,7 +1837,6 @@ internal_terminal_init (void) FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = colors[1]; } the_only_display_info.mouse_highlight.mouse_face_mouse_frame = NULL; - the_only_display_info.mouse_highlight.mouse_face_deferred_gc = 0; the_only_display_info.mouse_highlight.mouse_face_beg_row = the_only_display_info.mouse_highlight.mouse_face_beg_col = -1; the_only_display_info.mouse_highlight.mouse_face_end_row = diff --git a/src/nsterm.m b/src/nsterm.m index 57d32ee0528..25eb7ebc495 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -1186,7 +1186,6 @@ x_free_frame_resources (struct frame *f) hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; hlinfo->mouse_face_window = Qnil; - hlinfo->mouse_face_deferred_gc = 0; hlinfo->mouse_face_mouse_frame = 0; } @@ -1887,8 +1886,7 @@ static void ns_frame_up_to_date (struct frame *f) /* -------------------------------------------------------------------------- External (hook): Fix up mouse highlighting right after a full update. - Some highlighting was deferred if GC was happening during - note_mouse_highlight (), while other highlighting was deferred for update. + Can't use FRAME_MOUSE_UPDATE due to ns_frame_begin and ns_frame_end calls. -------------------------------------------------------------------------- */ { NSTRACE (ns_frame_up_to_date); @@ -1896,19 +1894,17 @@ ns_frame_up_to_date (struct frame *f) if (FRAME_NS_P (f)) { Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); - if ((hlinfo->mouse_face_deferred_gc || f ==hlinfo->mouse_face_mouse_frame) - /*&& hlinfo->mouse_face_mouse_frame*/) - { - block_input (); + if (f == hlinfo->mouse_face_mouse_frame) + { + block_input (); ns_update_begin(f); - if (hlinfo->mouse_face_mouse_frame) - note_mouse_highlight (hlinfo->mouse_face_mouse_frame, - hlinfo->mouse_face_mouse_x, - hlinfo->mouse_face_mouse_y); - hlinfo->mouse_face_deferred_gc = 0; + if (hlinfo->mouse_face_mouse_frame) + note_mouse_highlight (hlinfo->mouse_face_mouse_frame, + hlinfo->mouse_face_mouse_x, + hlinfo->mouse_face_mouse_y); ns_update_end(f); - unblock_input (); - } + unblock_input (); + } } } @@ -3869,7 +3865,6 @@ ns_initialize_display_info (struct ns_display_info *dpyinfo) dpyinfo->root_window = 42; /* a placeholder.. */ hlinfo->mouse_face_mouse_frame = NULL; - hlinfo->mouse_face_deferred_gc = 0; hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; hlinfo->mouse_face_face_id = DEFAULT_FACE_ID; diff --git a/src/w32term.c b/src/w32term.c index 032912c27f4..ab6afd32c75 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -723,21 +723,7 @@ static void w32_frame_up_to_date (struct frame *f) { if (FRAME_W32_P (f)) - { - Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); - - if (hlinfo->mouse_face_deferred_gc - || f == hlinfo->mouse_face_mouse_frame) - { - block_input (); - if (hlinfo->mouse_face_mouse_frame) - note_mouse_highlight (hlinfo->mouse_face_mouse_frame, - hlinfo->mouse_face_mouse_x, - hlinfo->mouse_face_mouse_y); - hlinfo->mouse_face_deferred_gc = 0; - unblock_input (); - } - } + FRAME_MOUSE_UPDATE (f); } @@ -5979,7 +5965,6 @@ x_free_frame_resources (struct frame *f) hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; hlinfo->mouse_face_window = Qnil; - hlinfo->mouse_face_deferred_gc = 0; hlinfo->mouse_face_mouse_frame = 0; } diff --git a/src/xdisp.c b/src/xdisp.c index e9b20d148c7..5d260d851ef 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -9642,7 +9642,7 @@ message2_nolog (const char *m, ptrdiff_t nbytes, int multibyte) do_pending_window_change (0); echo_area_display (1); do_pending_window_change (0); - if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress) + if (FRAME_TERMINAL (f)->frame_up_to_date_hook) (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f); } } @@ -9739,7 +9739,7 @@ message3_nolog (Lisp_Object m, ptrdiff_t nbytes, int multibyte) do_pending_window_change (0); echo_area_display (1); do_pending_window_change (0); - if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress) + if (FRAME_TERMINAL (f)->frame_up_to_date_hook) (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f); } } @@ -27685,12 +27685,6 @@ note_mouse_highlight (struct frame *f, int x, int y) if (hlinfo->mouse_face_defer) return; - if (gc_in_progress) - { - hlinfo->mouse_face_deferred_gc = 1; - return; - } - /* Which window is that in? */ window = window_from_coordinates (f, x, y, &part, 1); diff --git a/src/xterm.c b/src/xterm.c index 463d82b4ee2..61e942e10d2 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -669,21 +669,7 @@ static void XTframe_up_to_date (struct frame *f) { if (FRAME_X_P (f)) - { - Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); - - if (hlinfo->mouse_face_deferred_gc - || f == hlinfo->mouse_face_mouse_frame) - { - block_input (); - if (hlinfo->mouse_face_mouse_frame) - note_mouse_highlight (hlinfo->mouse_face_mouse_frame, - hlinfo->mouse_face_mouse_x, - hlinfo->mouse_face_mouse_y); - hlinfo->mouse_face_deferred_gc = 0; - unblock_input (); - } - } + FRAME_MOUSE_UPDATE (f); } @@ -9502,7 +9488,6 @@ x_free_frame_resources (struct frame *f) hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; hlinfo->mouse_face_window = Qnil; - hlinfo->mouse_face_deferred_gc = 0; hlinfo->mouse_face_mouse_frame = 0; } @@ -10153,7 +10138,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) dpyinfo->bitmaps_last = 0; dpyinfo->scratch_cursor_gc = 0; hlinfo->mouse_face_mouse_frame = 0; - hlinfo->mouse_face_deferred_gc = 0; hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; hlinfo->mouse_face_face_id = DEFAULT_FACE_ID; -- cgit v1.2.1 From 12645ae6912e7627d71ebbc7c37d9335cd0a429e Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 23 Nov 2012 14:23:28 +0800 Subject: * xftfont.c (xftfont_open): Remove duplicate assignment. --- src/ChangeLog | 4 ++++ src/xftfont.c | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 2e485f1b87b..d0f4ad6869d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2012-11-23 Chong Yidong + + * xftfont.c (xftfont_open): Remove duplicate assignment. + 2012-11-22 Dmitry Antipov * alloc.c (Fgarbage_collect): Unblock input after clearing diff --git a/src/xftfont.c b/src/xftfont.c index 372ed87705f..181a1da9b38 100644 --- a/src/xftfont.c +++ b/src/xftfont.c @@ -369,7 +369,7 @@ xftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) ASET (font_object, FONT_FORMAT_INDEX, ftfont_font_format (xftfont->pattern, filename)); font = XFONT_OBJECT (font_object); - font->pixel_size = pixel_size; + font->pixel_size = size; font->driver = &xftfont_driver; font->encoding_charset = font->repertory_charset = -1; @@ -387,8 +387,6 @@ xftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) xftfont_info->matrix.xy = 0x10000L * matrix->xy; xftfont_info->matrix.yx = 0x10000L * matrix->yx; } - font->pixel_size = size; - font->driver = &xftfont_driver; if (INTEGERP (AREF (entity, FONT_SPACING_INDEX))) spacing = XINT (AREF (entity, FONT_SPACING_INDEX)); else -- cgit v1.2.1 From 95ef7787fb0a5786a2e4f150649aadfa687a15f2 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 22 Nov 2012 23:48:43 -0800 Subject: Assume POSIX 1003.1-1988 or later for dirent.h. * admin/CPP-DEFINES (HAVE_CLOSEDIR, HAVE_DIRENT_H): Remove. * admin/notes/copyright: Adjust to src/ndir.h -> nt/inc/dirent.h renaming. * configure.ac: Do not check for dirent.h or closdir. * nt/inc/dirent.h: Rename from ../src/ndir.h, with these changes: (struct dirent): Rename from struct direct. All uses changed. * nt/inc/sys/dir.h: Remove. * src/dired.c: Assume HAVE_DIRENT_H. (NAMLEN): Remove, replacing with ... (dirent_namelen): New function. All uses changed. Use the GNU macro _D_EXACT_NAMELEN if available, as it's faster than strlen. (DIRENTRY): Remove, replacing all uses with 'struct dirent'. (DIRENTRY_NONEMPTY): Remove. All callers now assume it's nonzero. * src/makefile.w32-in (DIR_H): Remove. All uses replaced with $(NT_INC)/dirent.h. ($(BLD)/w32.$(O)): Do not depend on $(SRC)/ndir.h. * src/ndir.h: Rename to ../nt/inc/dirent.h. * src/sysdep.h (closedir) [!HAVE_CLOSEDIR]: Remove. Do not include ; no longer needed. * src/w32.c: Include rather than "ndir.h". Fixes: debbugs:12958 --- src/ChangeLog | 17 +++++ src/dired.c | 205 +++++++++++++++++++++++----------------------------- src/makefile.w32-in | 6 +- src/ndir.h | 41 ----------- src/sysdep.c | 22 ------ src/w32.c | 8 +- 6 files changed, 113 insertions(+), 186 deletions(-) delete mode 100644 src/ndir.h (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index d0f4ad6869d..5566b623cec 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,20 @@ +2012-11-23 Paul Eggert + + Assume POSIX 1003.1-1988 or later for dirent.h (Bug#12958). + * dired.c: Assume HAVE_DIRENT_H. + (NAMLEN): Remove, replacing with ... + (dirent_namelen): New function. All uses changed. Use the GNU macro + _D_EXACT_NAMELEN if available, as it's faster than strlen. + (DIRENTRY): Remove, replacing all uses with 'struct dirent'. + (DIRENTRY_NONEMPTY): Remove. All callers now assume it's nonzero. + * makefile.w32-in (DIR_H): Remove. All uses replaced with + $(NT_INC)/dirent.h. + ($(BLD)/w32.$(O)): Do not depend on $(SRC)/ndir.h. + * ndir.h: Rename to ../nt/inc/dirent.h. + * sysdep.h (closedir) [!HAVE_CLOSEDIR]: Remove. + Do not include ; no longer needed. + * w32.c: Include rather than "ndir.h". + 2012-11-23 Chong Yidong * xftfont.c (xftfont_open): Remove duplicate assignment. diff --git a/src/dired.c b/src/dired.c index 4986f845101..3530b74ecb4 100644 --- a/src/dired.c +++ b/src/dired.c @@ -31,44 +31,10 @@ along with GNU Emacs. If not, see . */ #include #include -/* The d_nameln member of a struct dirent includes the '\0' character - on some systems, but not on others. What's worse, you can't tell - at compile-time which one it will be, since it really depends on - the sort of system providing the filesystem you're reading from, - not the system you are running on. Paul Eggert - says this occurs when Emacs is running on a - SunOS 4.1.2 host, reading a directory that is remote-mounted from a - Solaris 2.1 host and is in a native Solaris 2.1 filesystem. - - Since applying strlen to the name always works, we'll just do that. */ -#define NAMLEN(p) strlen (p->d_name) - -#ifdef HAVE_DIRENT_H - #include -#define DIRENTRY struct dirent - -#else /* not HAVE_DIRENT_H */ - -#include -#include - -#define DIRENTRY struct direct - -extern DIR *opendir (char *); -extern struct direct *readdir (DIR *); - -#endif /* HAVE_DIRENT_H */ - #include #include -#ifdef MSDOS -#define DIRENTRY_NONEMPTY(p) ((p)->d_name[0] != 0) -#else -#define DIRENTRY_NONEMPTY(p) ((p)->d_ino) -#endif - #include "lisp.h" #include "systime.h" #include "character.h" @@ -88,6 +54,17 @@ static Lisp_Object Qfile_attributes_lessp; static ptrdiff_t scmp (const char *, const char *, ptrdiff_t); +/* Return the number of bytes in DP's name. */ +static ptrdiff_t +dirent_namelen (struct dirent *dp) +{ +#ifdef _D_EXACT_NAMLEN + return _D_EXACT_NAMLEN (dp); +#else + return strlen (dp->d_name); +#endif +} + #ifdef WINDOWSNT Lisp_Object directory_files_internal_w32_unwind (Lisp_Object arg) @@ -124,7 +101,7 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, bool needsep = 0; ptrdiff_t count = SPECPDL_INDEX (); struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; - DIRENTRY *dp; + struct dirent *dp; #ifdef WINDOWSNT Lisp_Object w32_save = Qnil; #endif @@ -209,6 +186,11 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, /* Loop reading blocks until EOF or error. */ for (;;) { + ptrdiff_t len; + bool wanted = 0; + Lisp_Object name, finalname; + struct gcpro gcpro1, gcpro2; + errno = 0; dp = readdir (d); @@ -225,89 +207,81 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, if (dp == NULL) break; - if (DIRENTRY_NONEMPTY (dp)) + len = dirent_namelen (dp); + name = finalname = make_unibyte_string (dp->d_name, len); + GCPRO2 (finalname, name); + + /* Note: DECODE_FILE can GC; it should protect its argument, + though. */ + name = DECODE_FILE (name); + len = SBYTES (name); + + /* Now that we have unwind_protect in place, we might as well + allow matching to be interrupted. */ + immediate_quit = 1; + QUIT; + + if (NILP (match) + || (0 <= re_search (bufp, SSDATA (name), len, 0, len, 0))) + wanted = 1; + + immediate_quit = 0; + + if (wanted) { - ptrdiff_t len; - bool wanted = 0; - Lisp_Object name, finalname; - struct gcpro gcpro1, gcpro2; + if (!NILP (full)) + { + Lisp_Object fullname; + ptrdiff_t nbytes = len + directory_nbytes + needsep; + ptrdiff_t nchars; - len = NAMLEN (dp); - name = finalname = make_unibyte_string (dp->d_name, len); - GCPRO2 (finalname, name); + fullname = make_uninit_multibyte_string (nbytes, nbytes); + memcpy (SDATA (fullname), SDATA (directory), + directory_nbytes); - /* Note: DECODE_FILE can GC; it should protect its argument, - though. */ - name = DECODE_FILE (name); - len = SBYTES (name); + if (needsep) + SSET (fullname, directory_nbytes, DIRECTORY_SEP); - /* Now that we have unwind_protect in place, we might as well - allow matching to be interrupted. */ - immediate_quit = 1; - QUIT; + memcpy (SDATA (fullname) + directory_nbytes + needsep, + SDATA (name), len); - if (NILP (match) - || (0 <= re_search (bufp, SSDATA (name), len, 0, len, 0))) - wanted = 1; + nchars = chars_in_text (SDATA (fullname), nbytes); - immediate_quit = 0; + /* Some bug somewhere. */ + if (nchars > nbytes) + emacs_abort (); - if (wanted) - { - if (!NILP (full)) - { - Lisp_Object fullname; - ptrdiff_t nbytes = len + directory_nbytes + needsep; - ptrdiff_t nchars; - - fullname = make_uninit_multibyte_string (nbytes, nbytes); - memcpy (SDATA (fullname), SDATA (directory), - directory_nbytes); - - if (needsep) - SSET (fullname, directory_nbytes, DIRECTORY_SEP); - - memcpy (SDATA (fullname) + directory_nbytes + needsep, - SDATA (name), len); - - nchars = chars_in_text (SDATA (fullname), nbytes); - - /* Some bug somewhere. */ - if (nchars > nbytes) - emacs_abort (); - - STRING_SET_CHARS (fullname, nchars); - if (nchars == nbytes) - STRING_SET_UNIBYTE (fullname); - - finalname = fullname; - } - else - finalname = name; - - if (attrs) - { - /* Construct an expanded filename for the directory entry. - Use the decoded names for input to Ffile_attributes. */ - Lisp_Object decoded_fullname, fileattrs; - struct gcpro gcpro1, gcpro2; - - decoded_fullname = fileattrs = Qnil; - GCPRO2 (decoded_fullname, fileattrs); - - /* Both Fexpand_file_name and Ffile_attributes can GC. */ - decoded_fullname = Fexpand_file_name (name, directory); - fileattrs = Ffile_attributes (decoded_fullname, id_format); - - list = Fcons (Fcons (finalname, fileattrs), list); - UNGCPRO; - } - else - list = Fcons (finalname, list); + STRING_SET_CHARS (fullname, nchars); + if (nchars == nbytes) + STRING_SET_UNIBYTE (fullname); + + finalname = fullname; } + else + finalname = name; - UNGCPRO; + if (attrs) + { + /* Construct an expanded filename for the directory entry. + Use the decoded names for input to Ffile_attributes. */ + Lisp_Object decoded_fullname, fileattrs; + struct gcpro gcpro1, gcpro2; + + decoded_fullname = fileattrs = Qnil; + GCPRO2 (decoded_fullname, fileattrs); + + /* Both Fexpand_file_name and Ffile_attributes can GC. */ + decoded_fullname = Fexpand_file_name (name, directory); + fileattrs = Ffile_attributes (decoded_fullname, id_format); + + list = Fcons (Fcons (finalname, fileattrs), list); + UNGCPRO; + } + else + list = Fcons (finalname, list); } + + UNGCPRO; } block_input (); @@ -442,7 +416,8 @@ These are all file names in directory DIRECTORY which begin with FILE. */) return file_name_completion (file, directory, 1, Qnil); } -static int file_name_completion_stat (Lisp_Object dirname, DIRENTRY *dp, struct stat *st_addr); +static int file_name_completion_stat (Lisp_Object dirname, struct dirent *dp, + struct stat *st_addr); static Lisp_Object Qdefault_directory; static Lisp_Object @@ -499,7 +474,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag, /* (att3b compiler bug requires do a null comparison this way) */ while (1) { - DIRENTRY *dp; + struct dirent *dp; ptrdiff_t len; bool canexclude = 0; @@ -517,11 +492,10 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag, if (!dp) break; - len = NAMLEN (dp); + len = dirent_namelen (dp); QUIT; - if (! DIRENTRY_NONEMPTY (dp) - || len < SCHARS (encoded_file) + if (len < SCHARS (encoded_file) || 0 <= scmp (dp->d_name, SSDATA (encoded_file), SCHARS (encoded_file))) continue; @@ -806,9 +780,10 @@ scmp (const char *s1, const char *s2, ptrdiff_t len) } static int -file_name_completion_stat (Lisp_Object dirname, DIRENTRY *dp, struct stat *st_addr) +file_name_completion_stat (Lisp_Object dirname, struct dirent *dp, + struct stat *st_addr) { - ptrdiff_t len = NAMLEN (dp); + ptrdiff_t len = dirent_namelen (dp); ptrdiff_t pos = SCHARS (dirname); int value; USE_SAFE_ALLOCA; diff --git a/src/makefile.w32-in b/src/makefile.w32-in index 9778e955677..5d0c6e72146 100644 --- a/src/makefile.w32-in +++ b/src/makefile.w32-in @@ -413,8 +413,6 @@ CONF_POST_H = $(SRC)/conf_post.h \ $(MS_W32_H) CONFIG_H = $(SRC)/config.h \ $(CONF_POST_H) -DIR_H = $(NT_INC)/sys/dir.h \ - $(SRC)/ndir.h W32GUI_H = $(SRC)/w32gui.h \ $(SYSTIME_H) DISPEXTERN_H = $(SRC)/dispextern.h \ @@ -714,6 +712,7 @@ $(BLD)/dired.$(O) : \ $(SRC)/blockinput.h \ $(SRC)/commands.h \ $(SRC)/regex.h \ + $(NT_INC)/dirent.h \ $(NT_INC)/pwd.h \ $(NT_INC)/sys/stat.h \ $(NT_INC)/unistd.h \ @@ -722,7 +721,6 @@ $(BLD)/dired.$(O) : \ $(CHARSET_H) \ $(CODING_H) \ $(CONFIG_H) \ - $(DIR_H) \ $(FILEMODE_H) \ $(GRP_H) \ $(LISP_H) \ @@ -1175,11 +1173,11 @@ $(BLD)/minibuf.$(O) : \ $(BLD)/w32.$(O) : \ $(SRC)/w32.c \ - $(SRC)/ndir.h \ $(SRC)/w32.h \ $(SRC)/w32common.h \ $(SRC)/w32heap.h \ $(SRC)/w32select.h \ + $(NT_INC)/dirent.h \ $(NT_INC)/pwd.h \ $(NT_INC)/sys/file.h \ $(NT_INC)/sys/time.h \ diff --git a/src/ndir.h b/src/ndir.h deleted file mode 100644 index cd7cdbe55f5..00000000000 --- a/src/ndir.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - -- definitions for 4.2BSD-compatible directory access - - last edit: 09-Jul-1983 D A Gwyn - - * The code here is forced by the interface, and is not subject to - * copyright, constituting the only possible expression of the - * algorithm in this format. - */ - -#define DIRBLKSIZ 512 /* size of directory block */ -#ifdef WINDOWSNT -#define MAXNAMLEN 255 -#else /* not WINDOWSNT */ -#define MAXNAMLEN 15 /* maximum filename length */ -#endif /* not WINDOWSNT */ - /* NOTE: MAXNAMLEN must be one less than a multiple of 4 */ - -struct direct /* data from readdir() */ - { - long d_ino; /* inode number of entry */ - unsigned short d_reclen; /* length of this record */ - unsigned short d_namlen; /* length of string in d_name */ - char d_name[MAXNAMLEN+1]; /* name of file */ - }; - -typedef struct - { - int dd_fd; /* file descriptor */ - int dd_loc; /* offset in block */ - int dd_size; /* amount of valid data */ - char dd_buf[DIRBLKSIZ]; /* directory block */ - } DIR; /* stream data from opendir() */ - -extern DIR *opendir (char *); -extern struct direct *readdir (DIR *); -extern void seekdir (DIR *, long); -extern void closedir (DIR *); - -#define rewinddir( dirp ) seekdir( dirp, 0L ) - diff --git a/src/sysdep.c b/src/sysdep.c index 3dd19685540..bc4dc91509f 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -2220,28 +2220,6 @@ emacs_readlink (char const *filename, char initial_buf[READLINK_BUFSIZE]) &emacs_norealloc_allocator, careadlinkatcwd); } -/* Directory routines for systems that don't have them. */ - -#ifdef HAVE_DIRENT_H - -#include - -#if !defined (HAVE_CLOSEDIR) - -int -closedir (DIR *dirp /* stream from opendir */) -{ - int rtnval; - - rtnval = emacs_close (dirp->dd_fd); - xfree (dirp); - - return rtnval; -} -#endif /* not HAVE_CLOSEDIR */ -#endif /* HAVE_DIRENT_H */ - - /* Return a struct timeval that is roughly equivalent to T. Use the least timeval not less than T. Return an extremal value if the result would overflow. */ diff --git a/src/w32.c b/src/w32.c index 038a442f529..c8e16dfaa94 100644 --- a/src/w32.c +++ b/src/w32.c @@ -179,7 +179,7 @@ typedef struct _REPARSE_DATA_BUFFER { #undef sendto #include "w32.h" -#include "ndir.h" +#include #include "w32common.h" #include "w32heap.h" #include "w32select.h" @@ -2448,7 +2448,7 @@ is_exec (const char * name) and readdir. We can't use the procedures supplied in sysdep.c, so we provide them here. */ -struct direct dir_static; /* simulated directory contents */ +struct dirent dir_static; /* simulated directory contents */ static HANDLE dir_find_handle = INVALID_HANDLE_VALUE; static int dir_is_fat; static char dir_pathname[MAXPATHLEN+1]; @@ -2518,7 +2518,7 @@ closedir (DIR *dirp) xfree ((char *) dirp); } -struct direct * +struct dirent * readdir (DIR *dirp) { int downcase = !NILP (Vw32_downcase_file_names); @@ -2572,7 +2572,7 @@ readdir (DIR *dirp) downcase = 1; /* 8+3 aliases are returned in all caps */ } dir_static.d_namlen = strlen (dir_static.d_name); - dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 + + dir_static.d_reclen = sizeof (struct dirent) - MAXNAMLEN + 3 + dir_static.d_namlen - dir_static.d_namlen % 4; /* If the file name in cFileName[] includes `?' characters, it means -- cgit v1.2.1 From 8654a41b44c8fe925af2b10378faa09909699240 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 23 Nov 2012 09:54:33 +0200 Subject: Fix pgx in .gdbinit when CHECK_LISP_OBJECT_TYPE is defined. src/.gdbinit (pgx): If the glyph's object is a string, display the pointer to string data, rather than the value of the string object itself (which barfs under CHECK_LISP_OBJECT_TYPE). --- src/.gdbinit | 3 ++- src/ChangeLog | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/.gdbinit b/src/.gdbinit index 952d7392a4c..98ae247b8c5 100644 --- a/src/.gdbinit +++ b/src/.gdbinit @@ -495,7 +495,8 @@ define pgx end xgettype ($g.object) if ($type == Lisp_String) - printf " str=%x[%d]", $g.object, $g.charpos + xgetptr $g.object + printf " str=0x%x[%d]", ((struct Lisp_String *)$ptr)->data, $g.charpos else printf " pos=%d", $g.charpos end diff --git a/src/ChangeLog b/src/ChangeLog index f760adf313f..7460e2c5704 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2012-11-23 Eli Zaretskii + + * .gdbinit (pgx): If the glyph's object is a string, display the + pointer to string data, rather than the value of the string object + itself (which barfs under CHECK_LISP_OBJECT_TYPE). + 2012-11-21 Eli Zaretskii * indent.c (Fvertical_motion): If the starting position is covered -- cgit v1.2.1 From 24becea4a7839adcea1bafd28604b204ff5cb7d6 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 23 Nov 2012 10:27:05 +0200 Subject: Fix cursor display when several display strings follow each other. src/xdisp.c (set_cursor_from_row): Skip step 2 only if point is not between bpos_covered and bpos_max. This fixes cursor display when several display strings follow each other. --- src/ChangeLog | 4 ++++ src/xdisp.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 7460e2c5704..88fbf7a99f2 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,9 @@ 2012-11-23 Eli Zaretskii + * xdisp.c (set_cursor_from_row): Skip step 2 only if point is not + between bpos_covered and bpos_max. This fixes cursor display when + several display strings follow each other. + * .gdbinit (pgx): If the glyph's object is a string, display the pointer to string data, rather than the value of the string object itself (which barfs under CHECK_LISP_OBJECT_TYPE). diff --git a/src/xdisp.c b/src/xdisp.c index 85fe9a00f60..4bb744a2f9d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -14232,7 +14232,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, GLYPH_BEFORE and GLYPH_AFTER. */ if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end) && BUFFERP (glyph->object) && glyph->charpos == pt_old) - && bpos_covered < pt_old) + && !(bpos_max < pt_old && pt_old <= bpos_covered)) { /* An empty line has a single glyph whose OBJECT is zero and whose CHARPOS is the position of a newline on that line. -- cgit v1.2.1 From a879f0eaae49460a29c840e3e35acdb84aa9aa7e Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 23 Nov 2012 10:47:34 +0200 Subject: Fix bug #12955 with building under MSYS Bash. src/makefile.w32-in (globals.h, gl-stamp): Use $(SWITCHCHAR) instead of a literal "/". (gl-stamp): Invoke fc.exe directly, not through cmd. --- src/ChangeLog | 6 ++++++ src/makefile.w32-in | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 5566b623cec..45df517eff5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2012-11-23 Eli Zaretskii + + * makefile.w32-in (globals.h, gl-stamp): Use $(SWITCHCHAR) instead + of a literal "/". (Bug#12955) + (gl-stamp): Invoke fc.exe directly, not through cmd. + 2012-11-23 Paul Eggert Assume POSIX 1003.1-1988 or later for dirent.h (Bug#12958). diff --git a/src/makefile.w32-in b/src/makefile.w32-in index 5d0c6e72146..a296f6eb393 100644 --- a/src/makefile.w32-in +++ b/src/makefile.w32-in @@ -229,12 +229,12 @@ SOME_MACHINE_OBJECTS = dosfns.o msdos.o \ obj = $(GLOBAL_SOURCES:.c=.o) globals.h: gl-stamp - @cmd /c rem true + @cmd $(SWITCHCHAR)c rem true gl-stamp: ../lib-src/$(BLD)/make-docfile.exe $(GLOBAL_SOURCES) - $(DEL) gl-tmp "$(THISDIR)/../lib-src/$(BLD)/make-docfile" -d . -g $(SOME_MACHINE_OBJECTS) $(obj) > gl-tmp - cmd /c "fc /b gl-tmp globals.h >nul 2>&1 || $(CP) gl-tmp globals.h" + fc.exe $(SWITCHCHAR)b gl-tmp globals.h >nul 2>&1 || $(CP) gl-tmp globals.h - $(DEL) gl-tmp echo timestamp > $@ -- cgit v1.2.1 From f418b22ee985bb6887c45856a1cabe2f5c726fca Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Fri, 23 Nov 2012 19:39:48 +0400 Subject: * frame.h (struct frame): Remove display_preempted member since all users are dead long ago. * nsterm.h (struct x_output): Use the only dummy member. * w32menu.c (pending_menu_activation): Remove since not really used. (set_frame_menubar): Adjust user. * w32term.h (struct x_output): Drop outdated #if 0 code. (struct w32_output): Use bitfields for explicit_parent, asked_for_visible and menubar_active members. Drop unused pending_menu_activation member. * xterm.h (struct x_output): Drop outdated #if 0 code. Use bitfields for explicit_parent, asked_for_visible, has_been_visible and net_wm_state_hidden_seen members. --- src/ChangeLog | 16 ++++++++++++++++ src/frame.h | 3 --- src/nsterm.h | 3 +-- src/w32menu.c | 13 ------------- src/w32term.h | 16 +++------------- src/xterm.h | 14 ++++---------- 6 files changed, 24 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 45df517eff5..e5669da5196 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,19 @@ +2012-11-23 Dmitry Antipov + + * frame.h (struct frame): Remove display_preempted member + since all users are dead long ago. + * nsterm.h (struct x_output): Use the only dummy member. + * w32menu.c (pending_menu_activation): Remove since not + really used. + (set_frame_menubar): Adjust user. + * w32term.h (struct x_output): Drop outdated #if 0 code. + (struct w32_output): Use bitfields for explicit_parent, + asked_for_visible and menubar_active members. Drop + unused pending_menu_activation member. + * xterm.h (struct x_output): Drop outdated #if 0 code. + Use bitfields for explicit_parent, asked_for_visible, + has_been_visible and net_wm_state_hidden_seen members. + 2012-11-23 Eli Zaretskii * makefile.w32-in (globals.h, gl-stamp): Use $(SWITCHCHAR) instead diff --git a/src/frame.h b/src/frame.h index 87c4fcb0555..5ebfc2f7ec3 100644 --- a/src/frame.h +++ b/src/frame.h @@ -357,9 +357,6 @@ struct frame unsigned int external_menu_bar : 1; #endif - /* Nonzero if last attempt at redisplay on this frame was preempted. */ - unsigned display_preempted : 1; - /* visible is nonzero if the frame is currently displayed; we check it to see if we should bother updating the frame's contents. DON'T SET IT DIRECTLY; instead, use FRAME_SET_VISIBLE. diff --git a/src/nsterm.h b/src/nsterm.h index 2e868b86caf..005701ed415 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -630,8 +630,7 @@ struct ns_output /* this dummy decl needed to support TTYs */ struct x_output { - unsigned long background_pixel; - unsigned long foreground_pixel; + int unused; }; diff --git a/src/w32menu.c b/src/w32menu.c index 36bf9574fdc..84fb1bdc71e 100644 --- a/src/w32menu.c +++ b/src/w32menu.c @@ -114,17 +114,6 @@ static int fill_in_menu (HMENU, widget_value *); void w32_free_menu_strings (HWND); - - -/* This is set nonzero after the user activates the menu bar, and set - to zero again after the menu bars are redisplayed by prepare_menu_bar. - While it is nonzero, all calls to set_frame_menubar go deep. - - I don't understand why this is needed, but it does seem to be - needed on Motif, according to Marcus Daniels . */ - -int pending_menu_activation; - #ifdef HAVE_MENUS DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0, @@ -389,8 +378,6 @@ set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p) if (! menubar_widget) deep_p = 1; - else if (pending_menu_activation && !deep_p) - deep_p = 1; if (deep_p) { diff --git a/src/w32term.h b/src/w32term.h index ce709c1231d..28d4ca6c490 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -251,16 +251,10 @@ extern Lisp_Object x_get_focus_frame (struct frame *); diffs between X and w32 code. */ struct x_output { -#if 0 /* These are also defined in struct frame. Use that instead. */ - PIX_TYPE background_pixel; - PIX_TYPE foreground_pixel; -#endif - /* Keep track of focus. May be EXPLICIT if we received a FocusIn for this frame, or IMPLICIT if we received an EnterNotify. FocusOut and LeaveNotify clears EXPLICIT/IMPLICIT. */ int focus_state; - }; enum @@ -347,17 +341,13 @@ struct w32_output /* Nonzero means our parent is another application's window and was explicitly specified. */ - char explicit_parent; + unsigned explicit_parent : 1; /* Nonzero means tried already to make this frame visible. */ - char asked_for_visible; + unsigned asked_for_visible : 1; /* Nonzero means menubar is currently active. */ - char menubar_active; - - /* Nonzero means menubar is about to become active, but should be - brought up to date first. */ - volatile char pending_menu_activation; + unsigned menubar_active : 1; /* Relief GCs, colors etc. */ struct relief diff --git a/src/xterm.h b/src/xterm.h index 6ef3d11fe48..d63ed1c4583 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -506,12 +506,6 @@ struct x_output value contains an ID of the fontset, else -1. */ int fontset; - /* Pixel values used for various purposes. - border_pixel may be -1 meaning use a gray tile. */ -#if 0 /* These are also defined in struct frame. Use that instead. */ - unsigned long background_pixel; - unsigned long foreground_pixel; -#endif unsigned long cursor_pixel; unsigned long border_pixel; unsigned long mouse_pixel; @@ -574,13 +568,13 @@ struct x_output /* Nonzero means our parent is another application's window and was explicitly specified. */ - char explicit_parent; + unsigned explicit_parent : 1; /* Nonzero means tried already to make this frame visible. */ - char asked_for_visible; + unsigned asked_for_visible : 1; /* Nonzero if this frame was ever previously visible. */ - char has_been_visible; + unsigned has_been_visible : 1; #ifdef HAVE_X_I18N /* Input context (currently, this means Compose key handler setup). */ @@ -634,7 +628,7 @@ struct x_output int top_before_move; /* Non-zero if _NET_WM_STATE_HIDDEN is set for this frame. */ - int net_wm_state_hidden_seen; + unsigned net_wm_state_hidden_seen : 1; }; #define No_Cursor (None) -- cgit v1.2.1 From 6d4e8f62e93b575a1da2cd2b4abeb9dce56e1e52 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 23 Nov 2012 14:20:31 -0800 Subject: Fix a race condition with glib (Bug#8855). This is a backport from the trunk, consisting of: 2012-11-17 Eli Zaretskii * nt/inc/sys/wait.h: New file, with prototype of waitpid and definitions of macros it needs. * nt/inc/ms-w32.h (wait): Don't define, 'wait' is not used anymore. (sys_wait): Remove prototype. * nt/config.nt (HAVE_SYS_WAIT_H): Define to 1. * src/w32proc.c (create_child): Don't clip the PID of the child process to fit into an Emacs integer, as this is no longer a restriction. (waitpid): Rename from sys_wait. Emulate a Posix 'waitpid' by reaping only the process specified by PID argument, if that is positive. Use PID instead of dead_child to know which process to reap. Wait for the child to die only if WNOHANG is not in OPTIONS. (sys_select): Don't set dead_child. * src/sysdep.c (wait_for_termination_1): Remove the WINDOWSNT portion, as it is no longer needed. * src/process.c (waitpid, WUNTRACED) [!WNOHANG]: Remove definitions, no longer needed. (record_child_status_change): Remove the setting of record_at_most_one_child for the !WNOHANG case. 2012-11-03 Paul Eggert Fix a race condition that causes Emacs to mess up glib (Bug#8855). This is a backport from the trunk. The symptom is a diagnostic "GLib-WARNING **: In call to g_spawn_sync(), exit status of a child process was requested but SIGCHLD action was set to SIG_IGN and ECHILD was received by waitpid(), so exit status can't be returned." The diagnostic is partly wrong, as the SIGCHLD action is not set to SIG_IGN. The real bug is a race condition between Emacs and glib: Emacs does a waitpid (-1, ...) and reaps glib's subprocess by mistake, so that glib can't find it. Work around the bug by invoking waitpid only on subprocesses that Emacs itself creates. * src/process.c (create_process, record_child_status_change): Don't use special value -1 in pid field, as the caller now must know the pid rather than having the callee infer it. The inference was sometimes incorrect anyway, due to another race. (create_process): Set new 'alive' member if child is created. (process_status_retrieved): New function. (record_child_status_change): Use it. Accept negative 1st argument, which means to wait for the processes that Emacs already knows about. Move special-case code for DOS_NT (which lacks WNOHANG) here, from caller. Keep track of processes that have already been waited for, by testing and clearing new 'alive' member. (CAN_HANDLE_MULTIPLE_CHILDREN): Remove, as record_child_status_change now does this internally. (handle_child_signal): Let record_child_status_change do all the work, since we do not want to reap all exited child processes, only the child processes that Emacs itself created. * src/process.h (Lisp_Process): New boolean member 'alive'. --- src/ChangeLog | 57 ++++++++++++++++++ src/process.c | 191 +++++++++++++++++++++++++++------------------------------- src/process.h | 3 + src/sysdep.c | 7 +-- src/w32proc.c | 127 ++++++++++++++++++++++++++------------ 5 files changed, 240 insertions(+), 145 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 88fbf7a99f2..655eb1595c0 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,60 @@ +2012-11-23 Paul Eggert + + Fix a race condition with glib (Bug#8855). + This is a backport from the trunk, consisting of: + + 2012-11-17 Eli Zaretskii + + * w32proc.c (create_child): Don't clip the PID of the child + process to fit into an Emacs integer, as this is no longer a + restriction. + (waitpid): Rename from sys_wait. Emulate a Posix 'waitpid' by + reaping only the process specified by PID argument, if that is + positive. Use PID instead of dead_child to know which process to + reap. Wait for the child to die only if WNOHANG is not in + OPTIONS. + (sys_select): Don't set dead_child. + + * sysdep.c (wait_for_termination_1): Remove the WINDOWSNT portion, + as it is no longer needed. + + * process.c (waitpid, WUNTRACED) [!WNOHANG]: Remove definitions, + no longer needed. + (record_child_status_change): Remove the setting of + record_at_most_one_child for the !WNOHANG case. + + 2012-11-03 Paul Eggert + + Fix a race condition that causes Emacs to mess up glib (Bug#8855). + This is a backport from the trunk. + The symptom is a diagnostic "GLib-WARNING **: In call to + g_spawn_sync(), exit status of a child process was requested but + SIGCHLD action was set to SIG_IGN and ECHILD was received by + waitpid(), so exit status can't be returned." The diagnostic + is partly wrong, as the SIGCHLD action is not set to SIG_IGN. + The real bug is a race condition between Emacs and glib: Emacs + does a waitpid (-1, ...) and reaps glib's subprocess by mistake, + so that glib can't find it. Work around the bug by invoking + waitpid only on subprocesses that Emacs itself creates. + * process.c (create_process, record_child_status_change): + Don't use special value -1 in pid field, as the caller now must + know the pid rather than having the callee infer it. The + inference was sometimes incorrect anyway, due to another race. + (create_process): Set new 'alive' member if child is created. + (process_status_retrieved): New function. + (record_child_status_change): Use it. + Accept negative 1st argument, which means to wait for the + processes that Emacs already knows about. Move special-case code + for DOS_NT (which lacks WNOHANG) here, from caller. Keep track of + processes that have already been waited for, by testing and + clearing new 'alive' member. + (CAN_HANDLE_MULTIPLE_CHILDREN): Remove, as record_child_status_change + now does this internally. + (handle_child_signal): Let record_child_status_change do all + the work, since we do not want to reap all exited child processes, + only the child processes that Emacs itself created. + * process.h (Lisp_Process): New boolean member 'alive'. + 2012-11-23 Eli Zaretskii * xdisp.c (set_cursor_from_row): Skip step 2 only if point is not diff --git a/src/process.c b/src/process.c index 77e99ead01f..c095d13293b 100644 --- a/src/process.c +++ b/src/process.c @@ -130,14 +130,6 @@ extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, EMACS_TIME *, void *); #endif -#ifndef WNOHANG -# undef waitpid -# define waitpid(pid, status, options) wait (status) -#endif -#ifndef WUNTRACED -# define WUNTRACED 0 -#endif - /* Work around GCC 4.7.0 bug with strict overflow checking; see . These lines can be removed once the GCC bug is fixed. */ @@ -795,9 +787,8 @@ get_process (register Lisp_Object name) #ifdef SIGCHLD /* Fdelete_process promises to immediately forget about the process, but in reality, Emacs needs to remember those processes until they have been - treated by the SIGCHLD handler; otherwise this handler would consider the - process as being synchronous and say that the synchronous process is - dead. */ + treated by the SIGCHLD handler and waitpid has been invoked on them; + otherwise they might fill up the kernel's process table. */ static Lisp_Object deleted_pid_list; #endif @@ -1704,16 +1695,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) if (inchannel > max_process_desc) max_process_desc = inchannel; - /* Until we store the proper pid, enable the SIGCHLD handler - to recognize an unknown pid as standing for this process. - It is very important not to let this `marker' value stay - in the table after this function has returned; if it does - it might cause call-process to hang and subsequent asynchronous - processes to get their return values scrambled. */ - XPROCESS (process)->pid = -1; - - /* This must be called after the above line because it may signal an - error. */ + /* This may signal an error. */ setup_process_coding_systems (process); encoded_current_dir = ENCODE_FILE (current_dir); @@ -1880,6 +1862,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) #endif XPROCESS (process)->pid = pid; + if (0 <= pid) + XPROCESS (process)->alive = 1; /* Stop blocking signals in the parent. */ #ifdef SIGCHLD @@ -6273,9 +6257,35 @@ process has been transmitted to the serial port. */) return process; } -/* On receipt of a signal that a child status has changed, loop asking - about children with changed statuses until the system says there - are no more. +/* If the status of the process DESIRED has changed, return true and + set *STATUS to its exit status; otherwise, return false. + If HAVE is nonnegative, assume that HAVE = waitpid (HAVE, STATUS, ...) + has already been invoked, and do not invoke waitpid again. */ + +static bool +process_status_retrieved (pid_t desired, pid_t have, int *status) +{ + if (have < 0) + { + /* Invoke waitpid only with a known process ID; do not invoke + waitpid with a nonpositive argument. Otherwise, Emacs might + reap an unwanted process by mistake. For example, invoking + waitpid (-1, ...) can mess up glib by reaping glib's subprocesses, + so that another thread running glib won't find them. */ + do + have = waitpid (desired, status, WNOHANG | WUNTRACED); + while (have < 0 && errno == EINTR); + } + + return have == desired; +} + +/* If PID is nonnegative, the child process PID with wait status W has + changed its status; record this and return true. + + If PID is negative, ignore W, and look for known child processes + of Emacs whose status have changed. For each one found, record its new + status. All we do is change the status; we do not run sentinels or print notifications. That is saved for the next time keyboard input is @@ -6298,13 +6308,15 @@ process has been transmitted to the serial port. */) ** Malloc WARNING: This should never call malloc either directly or indirectly; if it does, that is a bug */ -/* Record the changed status of the child process PID with wait status W. */ void record_child_status_change (pid_t pid, int w) { #ifdef SIGCHLD - Lisp_Object proc; - struct Lisp_Process *p; + + /* On POSIXish hosts, record at most one child only if we already + know one child that has exited. */ + bool record_at_most_one_child = 0 <= pid; + Lisp_Object tail; /* Find the process that signaled us, and record its status. */ @@ -6312,68 +6324,69 @@ record_child_status_change (pid_t pid, int w) /* The process can have been deleted by Fdelete_process. */ for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail)) { + bool all_pids_are_fixnums + = (MOST_NEGATIVE_FIXNUM <= TYPE_MINIMUM (pid_t) + && TYPE_MAXIMUM (pid_t) <= MOST_POSITIVE_FIXNUM); Lisp_Object xpid = XCAR (tail); - if ((INTEGERP (xpid) && pid == XINT (xpid)) - || (FLOATP (xpid) && pid == XFLOAT_DATA (xpid))) + if (all_pids_are_fixnums ? INTEGERP (xpid) : NUMBERP (xpid)) { - XSETCAR (tail, Qnil); - return; + pid_t deleted_pid; + if (INTEGERP (xpid)) + deleted_pid = XINT (xpid); + else + deleted_pid = XFLOAT_DATA (xpid); + if (process_status_retrieved (deleted_pid, pid, &w)) + { + XSETCAR (tail, Qnil); + if (record_at_most_one_child) + return; + } } } /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */ - p = 0; for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) { - proc = XCDR (XCAR (tail)); - p = XPROCESS (proc); - if (EQ (p->type, Qreal) && p->pid == pid) - break; - p = 0; - } - - /* Look for an asynchronous process whose pid hasn't been filled - in yet. */ - if (! p) - for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) - { - proc = XCDR (XCAR (tail)); - p = XPROCESS (proc); - if (p->pid == -1) - break; - p = 0; - } + Lisp_Object proc = XCDR (XCAR (tail)); + struct Lisp_Process *p = XPROCESS (proc); + if (p->alive && process_status_retrieved (p->pid, pid, &w)) + { + /* Change the status of the process that was found. */ + p->tick = ++process_tick; + p->raw_status = w; + p->raw_status_new = 1; - /* Change the status of the process that was found. */ - if (p) - { - int clear_desc_flag = 0; + /* If process has terminated, stop waiting for its output. */ + if (WIFSIGNALED (w) || WIFEXITED (w)) + { + int clear_desc_flag = 0; + p->alive = 0; + if (p->infd >= 0) + clear_desc_flag = 1; - p->tick = ++process_tick; - p->raw_status = w; - p->raw_status_new = 1; + /* clear_desc_flag avoids a compiler bug in Microsoft C. */ + if (clear_desc_flag) + { + FD_CLR (p->infd, &input_wait_mask); + FD_CLR (p->infd, &non_keyboard_wait_mask); + } + } - /* If process has terminated, stop waiting for its output. */ - if ((WIFSIGNALED (w) || WIFEXITED (w)) - && p->infd >= 0) - clear_desc_flag = 1; + /* Tell wait_reading_process_output that it needs to wake up and + look around. */ + if (input_available_clear_time) + *input_available_clear_time = make_emacs_time (0, 0); - /* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */ - if (clear_desc_flag) - { - FD_CLR (p->infd, &input_wait_mask); - FD_CLR (p->infd, &non_keyboard_wait_mask); + if (record_at_most_one_child) + return; } - - /* Tell wait_reading_process_output that it needs to wake up and - look around. */ - if (input_available_clear_time) - *input_available_clear_time = make_emacs_time (0, 0); } - /* There was no asynchronous process found for that pid: we have - a synchronous process. */ - else + + if (0 <= pid) { + /* The caller successfully waited for a pid but no asynchronous + process was found for it, so this is a synchronous process. */ + synch_process_alive = 0; /* Report the status of the synchronous process. */ @@ -6392,38 +6405,10 @@ record_child_status_change (pid_t pid, int w) #ifdef SIGCHLD -/* On some systems, the SIGCHLD handler must return right away. If - any more processes want to signal us, we will get another signal. - Otherwise, loop around to use up all the processes that have - something to tell us. */ -#if (defined WINDOWSNT \ - || (defined USG && !defined GNU_LINUX \ - && !(defined HPUX && defined WNOHANG))) -enum { CAN_HANDLE_MULTIPLE_CHILDREN = 0 }; -#else -enum { CAN_HANDLE_MULTIPLE_CHILDREN = 1 }; -#endif - static void handle_child_signal (int sig) { - do - { - pid_t pid; - int status; - - do - pid = waitpid (-1, &status, WNOHANG | WUNTRACED); - while (pid < 0 && errno == EINTR); - - /* PID == 0 means no processes found, PID == -1 means a real failure. - Either way, we have done all our job. */ - if (pid <= 0) - break; - - record_child_status_change (pid, status); - } - while (CAN_HANDLE_MULTIPLE_CHILDREN); + record_child_status_change (-1, 0); } static void diff --git a/src/process.h b/src/process.h index ce3d2e702cc..74d1a124060 100644 --- a/src/process.h +++ b/src/process.h @@ -142,6 +142,9 @@ struct Lisp_Process /* Flag to set coding-system of the process buffer from the coding_system used to decode process output. */ unsigned int inherit_coding_system_flag : 1; + /* Whether the process is alive, i.e., can be waited for. Running + processes can be waited for, but exited and fake processes cannot. */ + unsigned int alive : 1; /* Record the process status in the raw form in which it comes from `wait'. This is to avoid consing in a signal handler. The `raw_status_new' flag indicates that `raw_status' contains a new status that still diff --git a/src/sysdep.c b/src/sysdep.c index 63eac5d9e09..bb81353847b 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -289,10 +289,6 @@ wait_for_termination_1 (pid_t pid, int interruptible) { while (1) { -#ifdef WINDOWSNT - wait (0); - break; -#else /* not WINDOWSNT */ int status; int wait_result = waitpid (pid, &status, 0); if (wait_result < 0) @@ -306,7 +302,8 @@ wait_for_termination_1 (pid_t pid, int interruptible) break; } -#endif /* not WINDOWSNT */ + /* Note: the MS-Windows emulation of waitpid calls QUIT + internally. */ if (interruptible) QUIT; } diff --git a/src/w32proc.c b/src/w32proc.c index e3c54fe5460..b4f2099f06a 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -783,7 +783,6 @@ alarm (int seconds) /* Child process management list. */ int child_proc_count = 0; child_process child_procs[ MAX_CHILDREN ]; -child_process *dead_child = NULL; static DWORD WINAPI reader_thread (void *arg); @@ -1036,9 +1035,6 @@ create_child (char *exe, char *cmdline, char *env, int is_gui_app, if (cp->pid < 0) cp->pid = -cp->pid; - /* pid must fit in a Lisp_Int */ - cp->pid = cp->pid & INTMASK; - *pPid = cp->pid; return TRUE; @@ -1114,55 +1110,110 @@ reap_subprocess (child_process *cp) delete_child (cp); } -/* Wait for any of our existing child processes to die - When it does, close its handle - Return the pid and fill in the status if non-NULL. */ +/* Wait for a child process specified by PID, or for any of our + existing child processes (if PID is nonpositive) to die. When it + does, close its handle. Return the pid of the process that died + and fill in STATUS if non-NULL. */ -int -sys_wait (int *status) +pid_t +waitpid (pid_t pid, int *status, int options) { DWORD active, retval; int nh; - int pid; child_process *cp, *cps[MAX_CHILDREN]; HANDLE wait_hnd[MAX_CHILDREN]; + DWORD timeout_ms; + int dont_wait = (options & WNOHANG) != 0; nh = 0; - if (dead_child != NULL) + /* According to Posix: + + PID = -1 means status is requested for any child process. + + PID > 0 means status is requested for a single child process + whose pid is PID. + + PID = 0 means status is requested for any child process whose + process group ID is equal to that of the calling process. But + since Windows has only a limited support for process groups (only + for console processes and only for the purposes of passing + Ctrl-BREAK signal to them), and since we have no documented way + of determining whether a given process belongs to our group, we + treat 0 as -1. + + PID < -1 means status is requested for any child process whose + process group ID is equal to the absolute value of PID. Again, + since we don't support process groups, we treat that as -1. */ + if (pid > 0) { - /* We want to wait for a specific child */ - wait_hnd[nh] = dead_child->procinfo.hProcess; - cps[nh] = dead_child; - if (!wait_hnd[nh]) emacs_abort (); - nh++; - active = 0; - goto get_result; + int our_child = 0; + + /* We are requested to wait for a specific child. */ + for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) + { + /* Some child_procs might be sockets; ignore them. Also + ignore subprocesses whose output is not yet completely + read. */ + if (CHILD_ACTIVE (cp) + && cp->procinfo.hProcess + && cp->pid == pid) + { + our_child = 1; + break; + } + } + if (our_child) + { + if (cp->fd < 0 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0) + { + wait_hnd[nh] = cp->procinfo.hProcess; + cps[nh] = cp; + nh++; + } + else if (dont_wait) + { + /* PID specifies our subprocess, but its status is not + yet available. */ + return 0; + } + } + if (nh == 0) + { + /* No such child process, or nothing to wait for, so fail. */ + errno = ECHILD; + return -1; + } } else { for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) - /* some child_procs might be sockets; ignore them */ - if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess - && (cp->fd < 0 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0)) - { - wait_hnd[nh] = cp->procinfo.hProcess; - cps[nh] = cp; - nh++; - } + { + if (CHILD_ACTIVE (cp) + && cp->procinfo.hProcess + && (cp->fd < 0 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0)) + { + wait_hnd[nh] = cp->procinfo.hProcess; + cps[nh] = cp; + nh++; + } + } + if (nh == 0) + { + /* Nothing to wait on, so fail. */ + errno = ECHILD; + return -1; + } } - if (nh == 0) - { - /* Nothing to wait on, so fail */ - errno = ECHILD; - return -1; - } + if (dont_wait) + timeout_ms = 0; + else + timeout_ms = 1000; /* check for quit about once a second. */ do { - /* Check for quit about once a second. */ QUIT; - active = WaitForMultipleObjects (nh, wait_hnd, FALSE, 1000); + active = WaitForMultipleObjects (nh, wait_hnd, FALSE, timeout_ms); } while (active == WAIT_TIMEOUT); if (active == WAIT_FAILED) @@ -1192,8 +1243,10 @@ get_result: } if (retval == STILL_ACTIVE) { - /* Should never happen */ + /* Should never happen. */ DebPrint (("Wait.WaitForMultipleObjects returned an active process\n")); + if (pid > 0 && dont_wait) + return 0; errno = EINVAL; return -1; } @@ -1207,6 +1260,8 @@ get_result: else retval <<= 8; + if (pid > 0 && active != 0) + emacs_abort (); cp = cps[active]; pid = cp->pid; #ifdef FULL_DEBUG @@ -1995,9 +2050,7 @@ count_children: DebPrint (("select calling SIGCHLD handler for pid %d\n", cp->pid)); #endif - dead_child = cp; sig_handlers[SIGCHLD] (SIGCHLD); - dead_child = NULL; } } else if (fdindex[active] == -1) -- cgit v1.2.1 From 259719a65db5d0aa315d6f942f333494b88619a2 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 24 Nov 2012 08:24:13 +0200 Subject: Fix ChangeLog entries for the last commit. --- src/ChangeLog | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 655eb1595c0..8ca913b75fc 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,9 +1,18 @@ 2012-11-23 Paul Eggert + Eli Zaretskii Fix a race condition with glib (Bug#8855). - This is a backport from the trunk, consisting of: + The symptom is a diagnostic "GLib-WARNING **: In call to + g_spawn_sync(), exit status of a child process was requested but + SIGCHLD action was set to SIG_IGN and ECHILD was received by + waitpid(), so exit status can't be returned." The diagnostic + is partly wrong, as the SIGCHLD action is not set to SIG_IGN. + The real bug is a race condition between Emacs and glib: Emacs + does a waitpid (-1, ...) and reaps glib's subprocess by mistake, + so that glib can't find it. Work around the bug by invoking + waitpid only on subprocesses that Emacs itself creates. - 2012-11-17 Eli Zaretskii + This is a backport from the trunk, consisting of: * w32proc.c (create_child): Don't clip the PID of the child process to fit into an Emacs integer, as this is no longer a @@ -20,26 +29,10 @@ * process.c (waitpid, WUNTRACED) [!WNOHANG]: Remove definitions, no longer needed. - (record_child_status_change): Remove the setting of - record_at_most_one_child for the !WNOHANG case. - - 2012-11-03 Paul Eggert - - Fix a race condition that causes Emacs to mess up glib (Bug#8855). - This is a backport from the trunk. - The symptom is a diagnostic "GLib-WARNING **: In call to - g_spawn_sync(), exit status of a child process was requested but - SIGCHLD action was set to SIG_IGN and ECHILD was received by - waitpid(), so exit status can't be returned." The diagnostic - is partly wrong, as the SIGCHLD action is not set to SIG_IGN. - The real bug is a race condition between Emacs and glib: Emacs - does a waitpid (-1, ...) and reaps glib's subprocess by mistake, - so that glib can't find it. Work around the bug by invoking - waitpid only on subprocesses that Emacs itself creates. - * process.c (create_process, record_child_status_change): - Don't use special value -1 in pid field, as the caller now must - know the pid rather than having the callee infer it. The - inference was sometimes incorrect anyway, due to another race. + (create_process, record_child_status_change): Don't use special + value -1 in pid field, as the caller now must know the pid rather + than having the callee infer it. The inference was sometimes + incorrect anyway, due to another race. (create_process): Set new 'alive' member if child is created. (process_status_retrieved): New function. (record_child_status_change): Use it. @@ -47,7 +40,8 @@ processes that Emacs already knows about. Move special-case code for DOS_NT (which lacks WNOHANG) here, from caller. Keep track of processes that have already been waited for, by testing and - clearing new 'alive' member. + clearing new 'alive' member. Remove the setting of + record_at_most_one_child for the !WNOHANG case. (CAN_HANDLE_MULTIPLE_CHILDREN): Remove, as record_child_status_change now does this internally. (handle_child_signal): Let record_child_status_change do all -- cgit v1.2.1 From 22294a56e8115801f7b515f71ca87342d3e2e558 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 24 Nov 2012 09:25:52 +0200 Subject: Fix assertion violations when clicking on Info bread-crumbs. src/xdisp.c (draw_glyphs): Don't draw in mouse face if mouse highlighting on the frame was cleared. Prevents assertion violations when repeatedly clicking on the "Top" link of the "bread-crumbs" in Info buffers. --- src/ChangeLog | 7 +++++++ src/xdisp.c | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 8ca913b75fc..6c9893b2f4f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2012-11-24 Eli Zaretskii + + * xdisp.c (draw_glyphs): Don't draw in mouse face if mouse + highlighting on the frame was cleared. Prevents assertion + violations when repeatedly clicking on the "Top" link of the + "bread-crumbs" in Info buffers. + 2012-11-23 Paul Eggert Eli Zaretskii diff --git a/src/xdisp.c b/src/xdisp.c index 4bb744a2f9d..8336594ca61 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -23512,7 +23512,9 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row, /* If mouse highlighting is on, we may need to draw adjacent glyphs using mouse-face highlighting. */ - if (area == TEXT_AREA && row->mouse_face_p) + if (area == TEXT_AREA && row->mouse_face_p + && hlinfo->mouse_face_beg_row >= 0 + && hlinfo->mouse_face_end_row >= 0) { struct glyph_row *mouse_beg_row, *mouse_end_row; -- cgit v1.2.1 From d4547511735190a81449727a89dc90f6ef1d99a3 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 24 Nov 2012 00:24:11 -0800 Subject: Revert recent change for Bug#8855. As reported by Harald Hanche-Olsen in the change introduces a further bug, of creating lots of zombie processes in some cases. Further work is needed to come up with a better fix for Bug#8855. --- src/ChangeLog | 9 +++ src/process.c | 191 +++++++++++++++++++++++++++++++--------------------------- src/process.h | 3 - src/sysdep.c | 7 ++- src/w32proc.c | 127 ++++++++++++-------------------------- 5 files changed, 154 insertions(+), 183 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 6c9893b2f4f..99abda8a884 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2012-11-24 Paul Eggert + + Revert recent change for Bug#8855. + As reported by Harald Hanche-Olsen in + + the change introduces a further bug, of creating lots of zombie + processes in some cases. Further work is needed to come up with a + better fix for Bug#8855. + 2012-11-24 Eli Zaretskii * xdisp.c (draw_glyphs): Don't draw in mouse face if mouse diff --git a/src/process.c b/src/process.c index c095d13293b..77e99ead01f 100644 --- a/src/process.c +++ b/src/process.c @@ -130,6 +130,14 @@ extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, EMACS_TIME *, void *); #endif +#ifndef WNOHANG +# undef waitpid +# define waitpid(pid, status, options) wait (status) +#endif +#ifndef WUNTRACED +# define WUNTRACED 0 +#endif + /* Work around GCC 4.7.0 bug with strict overflow checking; see . These lines can be removed once the GCC bug is fixed. */ @@ -787,8 +795,9 @@ get_process (register Lisp_Object name) #ifdef SIGCHLD /* Fdelete_process promises to immediately forget about the process, but in reality, Emacs needs to remember those processes until they have been - treated by the SIGCHLD handler and waitpid has been invoked on them; - otherwise they might fill up the kernel's process table. */ + treated by the SIGCHLD handler; otherwise this handler would consider the + process as being synchronous and say that the synchronous process is + dead. */ static Lisp_Object deleted_pid_list; #endif @@ -1695,7 +1704,16 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) if (inchannel > max_process_desc) max_process_desc = inchannel; - /* This may signal an error. */ + /* Until we store the proper pid, enable the SIGCHLD handler + to recognize an unknown pid as standing for this process. + It is very important not to let this `marker' value stay + in the table after this function has returned; if it does + it might cause call-process to hang and subsequent asynchronous + processes to get their return values scrambled. */ + XPROCESS (process)->pid = -1; + + /* This must be called after the above line because it may signal an + error. */ setup_process_coding_systems (process); encoded_current_dir = ENCODE_FILE (current_dir); @@ -1862,8 +1880,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) #endif XPROCESS (process)->pid = pid; - if (0 <= pid) - XPROCESS (process)->alive = 1; /* Stop blocking signals in the parent. */ #ifdef SIGCHLD @@ -6257,35 +6273,9 @@ process has been transmitted to the serial port. */) return process; } -/* If the status of the process DESIRED has changed, return true and - set *STATUS to its exit status; otherwise, return false. - If HAVE is nonnegative, assume that HAVE = waitpid (HAVE, STATUS, ...) - has already been invoked, and do not invoke waitpid again. */ - -static bool -process_status_retrieved (pid_t desired, pid_t have, int *status) -{ - if (have < 0) - { - /* Invoke waitpid only with a known process ID; do not invoke - waitpid with a nonpositive argument. Otherwise, Emacs might - reap an unwanted process by mistake. For example, invoking - waitpid (-1, ...) can mess up glib by reaping glib's subprocesses, - so that another thread running glib won't find them. */ - do - have = waitpid (desired, status, WNOHANG | WUNTRACED); - while (have < 0 && errno == EINTR); - } - - return have == desired; -} - -/* If PID is nonnegative, the child process PID with wait status W has - changed its status; record this and return true. - - If PID is negative, ignore W, and look for known child processes - of Emacs whose status have changed. For each one found, record its new - status. +/* On receipt of a signal that a child status has changed, loop asking + about children with changed statuses until the system says there + are no more. All we do is change the status; we do not run sentinels or print notifications. That is saved for the next time keyboard input is @@ -6308,15 +6298,13 @@ process_status_retrieved (pid_t desired, pid_t have, int *status) ** Malloc WARNING: This should never call malloc either directly or indirectly; if it does, that is a bug */ +/* Record the changed status of the child process PID with wait status W. */ void record_child_status_change (pid_t pid, int w) { #ifdef SIGCHLD - - /* On POSIXish hosts, record at most one child only if we already - know one child that has exited. */ - bool record_at_most_one_child = 0 <= pid; - + Lisp_Object proc; + struct Lisp_Process *p; Lisp_Object tail; /* Find the process that signaled us, and record its status. */ @@ -6324,69 +6312,68 @@ record_child_status_change (pid_t pid, int w) /* The process can have been deleted by Fdelete_process. */ for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail)) { - bool all_pids_are_fixnums - = (MOST_NEGATIVE_FIXNUM <= TYPE_MINIMUM (pid_t) - && TYPE_MAXIMUM (pid_t) <= MOST_POSITIVE_FIXNUM); Lisp_Object xpid = XCAR (tail); - if (all_pids_are_fixnums ? INTEGERP (xpid) : NUMBERP (xpid)) + if ((INTEGERP (xpid) && pid == XINT (xpid)) + || (FLOATP (xpid) && pid == XFLOAT_DATA (xpid))) { - pid_t deleted_pid; - if (INTEGERP (xpid)) - deleted_pid = XINT (xpid); - else - deleted_pid = XFLOAT_DATA (xpid); - if (process_status_retrieved (deleted_pid, pid, &w)) - { - XSETCAR (tail, Qnil); - if (record_at_most_one_child) - return; - } + XSETCAR (tail, Qnil); + return; } } /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */ + p = 0; for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) { - Lisp_Object proc = XCDR (XCAR (tail)); - struct Lisp_Process *p = XPROCESS (proc); - if (p->alive && process_status_retrieved (p->pid, pid, &w)) - { - /* Change the status of the process that was found. */ - p->tick = ++process_tick; - p->raw_status = w; - p->raw_status_new = 1; + proc = XCDR (XCAR (tail)); + p = XPROCESS (proc); + if (EQ (p->type, Qreal) && p->pid == pid) + break; + p = 0; + } - /* If process has terminated, stop waiting for its output. */ - if (WIFSIGNALED (w) || WIFEXITED (w)) - { - int clear_desc_flag = 0; - p->alive = 0; - if (p->infd >= 0) - clear_desc_flag = 1; + /* Look for an asynchronous process whose pid hasn't been filled + in yet. */ + if (! p) + for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) + { + proc = XCDR (XCAR (tail)); + p = XPROCESS (proc); + if (p->pid == -1) + break; + p = 0; + } - /* clear_desc_flag avoids a compiler bug in Microsoft C. */ - if (clear_desc_flag) - { - FD_CLR (p->infd, &input_wait_mask); - FD_CLR (p->infd, &non_keyboard_wait_mask); - } - } + /* Change the status of the process that was found. */ + if (p) + { + int clear_desc_flag = 0; - /* Tell wait_reading_process_output that it needs to wake up and - look around. */ - if (input_available_clear_time) - *input_available_clear_time = make_emacs_time (0, 0); + p->tick = ++process_tick; + p->raw_status = w; + p->raw_status_new = 1; + + /* If process has terminated, stop waiting for its output. */ + if ((WIFSIGNALED (w) || WIFEXITED (w)) + && p->infd >= 0) + clear_desc_flag = 1; - if (record_at_most_one_child) - return; + /* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */ + if (clear_desc_flag) + { + FD_CLR (p->infd, &input_wait_mask); + FD_CLR (p->infd, &non_keyboard_wait_mask); } - } - if (0 <= pid) + /* Tell wait_reading_process_output that it needs to wake up and + look around. */ + if (input_available_clear_time) + *input_available_clear_time = make_emacs_time (0, 0); + } + /* There was no asynchronous process found for that pid: we have + a synchronous process. */ + else { - /* The caller successfully waited for a pid but no asynchronous - process was found for it, so this is a synchronous process. */ - synch_process_alive = 0; /* Report the status of the synchronous process. */ @@ -6405,10 +6392,38 @@ record_child_status_change (pid_t pid, int w) #ifdef SIGCHLD +/* On some systems, the SIGCHLD handler must return right away. If + any more processes want to signal us, we will get another signal. + Otherwise, loop around to use up all the processes that have + something to tell us. */ +#if (defined WINDOWSNT \ + || (defined USG && !defined GNU_LINUX \ + && !(defined HPUX && defined WNOHANG))) +enum { CAN_HANDLE_MULTIPLE_CHILDREN = 0 }; +#else +enum { CAN_HANDLE_MULTIPLE_CHILDREN = 1 }; +#endif + static void handle_child_signal (int sig) { - record_child_status_change (-1, 0); + do + { + pid_t pid; + int status; + + do + pid = waitpid (-1, &status, WNOHANG | WUNTRACED); + while (pid < 0 && errno == EINTR); + + /* PID == 0 means no processes found, PID == -1 means a real failure. + Either way, we have done all our job. */ + if (pid <= 0) + break; + + record_child_status_change (pid, status); + } + while (CAN_HANDLE_MULTIPLE_CHILDREN); } static void diff --git a/src/process.h b/src/process.h index 74d1a124060..ce3d2e702cc 100644 --- a/src/process.h +++ b/src/process.h @@ -142,9 +142,6 @@ struct Lisp_Process /* Flag to set coding-system of the process buffer from the coding_system used to decode process output. */ unsigned int inherit_coding_system_flag : 1; - /* Whether the process is alive, i.e., can be waited for. Running - processes can be waited for, but exited and fake processes cannot. */ - unsigned int alive : 1; /* Record the process status in the raw form in which it comes from `wait'. This is to avoid consing in a signal handler. The `raw_status_new' flag indicates that `raw_status' contains a new status that still diff --git a/src/sysdep.c b/src/sysdep.c index bb81353847b..63eac5d9e09 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -289,6 +289,10 @@ wait_for_termination_1 (pid_t pid, int interruptible) { while (1) { +#ifdef WINDOWSNT + wait (0); + break; +#else /* not WINDOWSNT */ int status; int wait_result = waitpid (pid, &status, 0); if (wait_result < 0) @@ -302,8 +306,7 @@ wait_for_termination_1 (pid_t pid, int interruptible) break; } - /* Note: the MS-Windows emulation of waitpid calls QUIT - internally. */ +#endif /* not WINDOWSNT */ if (interruptible) QUIT; } diff --git a/src/w32proc.c b/src/w32proc.c index b4f2099f06a..e3c54fe5460 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -783,6 +783,7 @@ alarm (int seconds) /* Child process management list. */ int child_proc_count = 0; child_process child_procs[ MAX_CHILDREN ]; +child_process *dead_child = NULL; static DWORD WINAPI reader_thread (void *arg); @@ -1035,6 +1036,9 @@ create_child (char *exe, char *cmdline, char *env, int is_gui_app, if (cp->pid < 0) cp->pid = -cp->pid; + /* pid must fit in a Lisp_Int */ + cp->pid = cp->pid & INTMASK; + *pPid = cp->pid; return TRUE; @@ -1110,110 +1114,55 @@ reap_subprocess (child_process *cp) delete_child (cp); } -/* Wait for a child process specified by PID, or for any of our - existing child processes (if PID is nonpositive) to die. When it - does, close its handle. Return the pid of the process that died - and fill in STATUS if non-NULL. */ +/* Wait for any of our existing child processes to die + When it does, close its handle + Return the pid and fill in the status if non-NULL. */ -pid_t -waitpid (pid_t pid, int *status, int options) +int +sys_wait (int *status) { DWORD active, retval; int nh; + int pid; child_process *cp, *cps[MAX_CHILDREN]; HANDLE wait_hnd[MAX_CHILDREN]; - DWORD timeout_ms; - int dont_wait = (options & WNOHANG) != 0; nh = 0; - /* According to Posix: - - PID = -1 means status is requested for any child process. - - PID > 0 means status is requested for a single child process - whose pid is PID. - - PID = 0 means status is requested for any child process whose - process group ID is equal to that of the calling process. But - since Windows has only a limited support for process groups (only - for console processes and only for the purposes of passing - Ctrl-BREAK signal to them), and since we have no documented way - of determining whether a given process belongs to our group, we - treat 0 as -1. - - PID < -1 means status is requested for any child process whose - process group ID is equal to the absolute value of PID. Again, - since we don't support process groups, we treat that as -1. */ - if (pid > 0) + if (dead_child != NULL) { - int our_child = 0; - - /* We are requested to wait for a specific child. */ - for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) - { - /* Some child_procs might be sockets; ignore them. Also - ignore subprocesses whose output is not yet completely - read. */ - if (CHILD_ACTIVE (cp) - && cp->procinfo.hProcess - && cp->pid == pid) - { - our_child = 1; - break; - } - } - if (our_child) - { - if (cp->fd < 0 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0) - { - wait_hnd[nh] = cp->procinfo.hProcess; - cps[nh] = cp; - nh++; - } - else if (dont_wait) - { - /* PID specifies our subprocess, but its status is not - yet available. */ - return 0; - } - } - if (nh == 0) - { - /* No such child process, or nothing to wait for, so fail. */ - errno = ECHILD; - return -1; - } + /* We want to wait for a specific child */ + wait_hnd[nh] = dead_child->procinfo.hProcess; + cps[nh] = dead_child; + if (!wait_hnd[nh]) emacs_abort (); + nh++; + active = 0; + goto get_result; } else { for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) - { - if (CHILD_ACTIVE (cp) - && cp->procinfo.hProcess - && (cp->fd < 0 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0)) - { - wait_hnd[nh] = cp->procinfo.hProcess; - cps[nh] = cp; - nh++; - } - } - if (nh == 0) - { - /* Nothing to wait on, so fail. */ - errno = ECHILD; - return -1; - } + /* some child_procs might be sockets; ignore them */ + if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess + && (cp->fd < 0 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0)) + { + wait_hnd[nh] = cp->procinfo.hProcess; + cps[nh] = cp; + nh++; + } } - if (dont_wait) - timeout_ms = 0; - else - timeout_ms = 1000; /* check for quit about once a second. */ + if (nh == 0) + { + /* Nothing to wait on, so fail */ + errno = ECHILD; + return -1; + } do { + /* Check for quit about once a second. */ QUIT; - active = WaitForMultipleObjects (nh, wait_hnd, FALSE, timeout_ms); + active = WaitForMultipleObjects (nh, wait_hnd, FALSE, 1000); } while (active == WAIT_TIMEOUT); if (active == WAIT_FAILED) @@ -1243,10 +1192,8 @@ get_result: } if (retval == STILL_ACTIVE) { - /* Should never happen. */ + /* Should never happen */ DebPrint (("Wait.WaitForMultipleObjects returned an active process\n")); - if (pid > 0 && dont_wait) - return 0; errno = EINVAL; return -1; } @@ -1260,8 +1207,6 @@ get_result: else retval <<= 8; - if (pid > 0 && active != 0) - emacs_abort (); cp = cps[active]; pid = cp->pid; #ifdef FULL_DEBUG @@ -2050,7 +1995,9 @@ count_children: DebPrint (("select calling SIGCHLD handler for pid %d\n", cp->pid)); #endif + dead_child = cp; sig_handlers[SIGCHLD] (SIGCHLD); + dead_child = NULL; } } else if (fdindex[active] == -1) -- cgit v1.2.1 From bcd77a2ba0298c8551fef7c08b001a0f0517bac3 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sat, 24 Nov 2012 12:20:49 -0500 Subject: Remove HAVE_MOUSE; see https://lists.gnu.org/archive/html/emacs-devel/2012-10/msg00403.html. * configure.ac (HAVE_MOUSE): Remove. * admin/CPP-DEFINES (HAVE_MOUSE): Remove. * msdos/sed2v2.inp (HAVE_MOUSE): Remove. * nt/config.nt (HAVE_MOUSE): Remove. * src/keyboard.c (HAVE_MOUSE): * src/frame.c (HAVE_MOUSE): Remove, and rewrite code as if HAVE_MOUSE were always defined. --- src/ChangeLog | 6 ++++++ src/frame.c | 8 ++------ src/keyboard.c | 32 -------------------------------- 3 files changed, 8 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 32a14ef9e62..859b3a7d254 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2012-11-24 Ken Brown + + * keyboard.c (HAVE_MOUSE): + * frame.c (HAVE_MOUSE): Remove, and rewrite code as if HAVE_MOUSE + were always defined. + 2012-11-24 Eli Zaretskii * xdisp.c (set_cursor_from_row): Skip step 2 only if point is not diff --git a/src/frame.c b/src/frame.c index d580bf7f148..3501fc36675 100644 --- a/src/frame.c +++ b/src/frame.c @@ -1467,7 +1467,6 @@ and returns whatever that function returns. */) f = SELECTED_FRAME (); x = y = Qnil; -#if defined (HAVE_MOUSE) || defined (HAVE_GPM) /* It's okay for the hook to refrain from storing anything. */ if (FRAME_TERMINAL (f)->mouse_position_hook) { @@ -1487,7 +1486,6 @@ and returns whatever that function returns. */) XSETINT (x, col); XSETINT (y, row); } -#endif XSETFRAME (lispy_dummy, f); retval = Fcons (lispy_dummy, Fcons (x, y)); GCPRO1 (retval); @@ -1514,7 +1512,6 @@ and nil for X and Y. */) f = SELECTED_FRAME (); x = y = Qnil; -#if defined (HAVE_MOUSE) || defined (HAVE_GPM) /* It's okay for the hook to refrain from storing anything. */ if (FRAME_TERMINAL (f)->mouse_position_hook) { @@ -1526,7 +1523,6 @@ and nil for X and Y. */) &time_dummy); } -#endif XSETFRAME (lispy_dummy, f); return Fcons (lispy_dummy, Fcons (x, y)); } @@ -1557,7 +1553,7 @@ before calling this function on it, like this. /* Warping the mouse will cause enternotify and focus events. */ x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y)); #else -#if defined (MSDOS) && defined (HAVE_MOUSE) +#if defined (MSDOS) if (FRAME_MSDOS_P (XFRAME (frame))) { Fselect_frame (frame, Qnil); @@ -1598,7 +1594,7 @@ before calling this function on it, like this. /* Warping the mouse will cause enternotify and focus events. */ x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y)); #else -#if defined (MSDOS) && defined (HAVE_MOUSE) +#if defined (MSDOS) if (FRAME_MSDOS_P (XFRAME (frame))) { Fselect_frame (frame, Qnil); diff --git a/src/keyboard.c b/src/keyboard.c index 951d4ad79dc..0ad6d18c044 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -306,9 +306,7 @@ static Lisp_Object Qmake_frame_visible; static Lisp_Object Qselect_window; Lisp_Object Qhelp_echo; -#if defined (HAVE_MOUSE) || defined (HAVE_GPM) static Lisp_Object Qmouse_fixup_help_message; -#endif /* Symbols to denote kinds of events. */ static Lisp_Object Qfunction_key; @@ -417,12 +415,10 @@ static Lisp_Object read_char_x_menu_prompt (ptrdiff_t, Lisp_Object *, static Lisp_Object read_char_minibuf_menu_prompt (int, ptrdiff_t, Lisp_Object *); static Lisp_Object make_lispy_event (struct input_event *); -#if defined (HAVE_MOUSE) || defined (HAVE_GPM) static Lisp_Object make_lispy_movement (struct frame *, Lisp_Object, enum scroll_bar_part, Lisp_Object, Lisp_Object, Time); -#endif static Lisp_Object modify_event_symbol (ptrdiff_t, int, Lisp_Object, Lisp_Object, const char *const *, Lisp_Object *, ptrdiff_t); @@ -1234,8 +1230,6 @@ DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0, user_error ("No recursive edit is in progress"); } -#if defined (HAVE_MOUSE) || defined (HAVE_GPM) - /* Restore mouse tracking enablement. See Ftrack_mouse for the only use of this function. */ @@ -1310,7 +1304,6 @@ some_mouse_moved (void) return 0; } -#endif /* HAVE_MOUSE || HAVE_GPM */ /* This is the actual command reading loop, sans error-handling encapsulation. */ @@ -1402,14 +1395,11 @@ command_loop_1 (void) Vdeactivate_mark = Qnil; -#if defined (HAVE_MOUSE) || defined (HAVE_GPM) - /* Don't ignore mouse movements for more than a single command loop. (This flag is set in xdisp.c whenever the tool bar is resized, because the resize moves text up or down, and would generate false mouse drag events if we don't ignore them.) */ ignore_mouse_drag_p = 0; -#endif /* If minibuffer on and echo area in use, wait a short time and redraw minibuffer. */ @@ -2182,7 +2172,6 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object, return; } -#if defined (HAVE_MOUSE) || defined (HAVE_GPM) if (!noninteractive && STRINGP (help)) { /* The mouse-fixup-help-message Lisp function can call @@ -2195,7 +2184,6 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object, if (f) f->mouse_moved = 1; } -#endif if (STRINGP (help) || NILP (help)) { @@ -3390,11 +3378,9 @@ readable_events (int flags) return 1; } -#if defined (HAVE_MOUSE) || defined (HAVE_GPM) if (!(flags & READABLE_EVENTS_IGNORE_SQUEEZABLES) && !NILP (do_mouse_tracking) && some_mouse_moved ()) return 1; -#endif if (single_kboard) { if (current_kboard->kbd_queue_has_data) @@ -3762,10 +3748,8 @@ kbd_buffer_get_event (KBOARD **kbp, if (kbd_fetch_ptr != kbd_store_ptr) break; -#if defined (HAVE_MOUSE) || defined (HAVE_GPM) if (!NILP (do_mouse_tracking) && some_mouse_moved ()) break; -#endif /* If the quit flag is set, then read_char will return quit_char, so that counts as "available input." */ @@ -3780,10 +3764,8 @@ kbd_buffer_get_event (KBOARD **kbp, #endif if (kbd_fetch_ptr != kbd_store_ptr) break; -#if defined (HAVE_MOUSE) || defined (HAVE_GPM) if (!NILP (do_mouse_tracking) && some_mouse_moved ()) break; -#endif if (end_time) { EMACS_TIME now = current_emacs_time (); @@ -4040,7 +4022,6 @@ kbd_buffer_get_event (KBOARD **kbp, } } } -#if defined (HAVE_MOUSE) || defined (HAVE_GPM) /* Try generating a mouse motion event. */ else if (!NILP (do_mouse_tracking) && some_mouse_moved ()) { @@ -4085,7 +4066,6 @@ kbd_buffer_get_event (KBOARD **kbp, if (!NILP (x) && NILP (obj)) obj = make_lispy_movement (f, bar_window, part, x, y, t); } -#endif /* HAVE_MOUSE || HAVE GPM */ else /* We were promised by the above while loop that there was something for us to read! */ @@ -5397,7 +5377,6 @@ make_lispy_event (struct input_event *event) return Qnil; #endif -#ifdef HAVE_MOUSE /* A mouse click. Figure out where it is, decide whether it's a press, click or drag, and build the appropriate structure. */ case MOUSE_CLICK_EVENT: @@ -5849,7 +5828,6 @@ make_lispy_event (struct input_event *event) Fcons (files, Qnil))); } -#endif /* HAVE_MOUSE */ #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \ || defined (HAVE_NS) || defined (USE_GTK) @@ -5968,8 +5946,6 @@ make_lispy_event (struct input_event *event) } } -#if defined (HAVE_MOUSE) || defined (HAVE_GPM) - static Lisp_Object make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_part part, Lisp_Object x, Lisp_Object y, Time t) @@ -5997,8 +5973,6 @@ make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_pa } } -#endif /* HAVE_MOUSE || HAVE GPM */ - /* Construct a switch frame event. */ static Lisp_Object make_lispy_switch_frame (Lisp_Object frame) @@ -11233,9 +11207,7 @@ init_keyboard (void) recent_keys_index = 0; kbd_fetch_ptr = kbd_buffer; kbd_store_ptr = kbd_buffer; -#if defined (HAVE_MOUSE) || defined (HAVE_GPM) do_mouse_tracking = Qnil; -#endif input_pending = 0; interrupt_input_blocked = 0; pending_signals = 0; @@ -11386,9 +11358,7 @@ syms_of_keyboard (void) DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar"); DEFSYM (Qmenu_bar, "menu-bar"); -#if defined (HAVE_MOUSE) || defined (HAVE_GPM) DEFSYM (Qmouse_fixup_help_message, "mouse-fixup-help-message"); -#endif DEFSYM (Qabove_handle, "above-handle"); DEFSYM (Qhandle, "handle"); @@ -11508,9 +11478,7 @@ syms_of_keyboard (void) defsubr (&Sread_key_sequence); defsubr (&Sread_key_sequence_vector); defsubr (&Srecursive_edit); -#if defined (HAVE_MOUSE) || defined (HAVE_GPM) defsubr (&Strack_mouse); -#endif defsubr (&Sinput_pending_p); defsubr (&Scommand_execute); defsubr (&Srecent_keys); -- cgit v1.2.1 From 5fbab051226a3f92fadd45ca716df3af67de8954 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 24 Nov 2012 23:50:55 -0800 Subject: * sysdep.c (sys_subshell): Don't assume pid_t fits in int. --- src/ChangeLog | 4 ++++ src/sysdep.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 859b3a7d254..c612c4dd365 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2012-11-25 Paul Eggert + + * sysdep.c (sys_subshell): Don't assume pid_t fits in int. + 2012-11-24 Ken Brown * keyboard.c (HAVE_MOUSE): diff --git a/src/sysdep.c b/src/sysdep.c index bc4dc91509f..1a3834f0379 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -453,7 +453,7 @@ sys_subshell (void) int st; char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */ #endif - int pid; + pid_t pid; struct save_signal saved_handlers[5]; Lisp_Object dir; unsigned char *volatile str_volatile = 0; -- cgit v1.2.1 From 3fa1e84d43f401876db74e14c7b72f5190fc13b0 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 26 Nov 2012 19:46:35 +0200 Subject: Don't crash if internal-char-font is called on non-GUI frames. src/fontset.c (Finternal_char_font): Return nil on non-GUI frames. (Bug#11964) --- src/ChangeLog | 5 +++++ src/fontset.c | 2 ++ 2 files changed, 7 insertions(+) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 99abda8a884..ce272cc0b53 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2012-11-26 Eli Zaretskii + + * fontset.c (Finternal_char_font): Return nil on non-GUI frames. + (Bug#11964) + 2012-11-24 Paul Eggert Revert recent change for Bug#8855. diff --git a/src/fontset.c b/src/fontset.c index da745b31ca1..ed468d33a15 100644 --- a/src/fontset.c +++ b/src/fontset.c @@ -1879,6 +1879,8 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0, } if (! CHAR_VALID_P (c)) return Qnil; + if (!FRAME_WINDOW_P (f)) + return Qnil; face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c, pos, Qnil); face = FACE_FROM_ID (f, face_id); if (face->font) -- cgit v1.2.1 From 22626a856b520e4b092b2e4132f57adf8aaf7227 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 26 Nov 2012 21:17:07 -0800 Subject: Assume POSIX 1003.1-1988 or later for errno.h. * lib-src/movemail.c (main): Assume EAGAIN and EBUSY. * src/dired.c (directory_files_internal, file_name_completion): Assume EAGAIN and EINTR are defined. * src/fileio.c (Fcopy_file): Assume EISDIR is defined. * src/gmalloc.c (ENOMEM, EINVAL): Assume they're defined. * src/gnutls.c (emacs_gnutls_write): Assume EAGAIN is defined. * src/lread.c (readbyte_from_file): Assume EINTR is defined. * src/process.c (wait_reading_process_output, send_process) [subprocesses]: Assume EIO and EAGAIN are defined. * src/unexcoff.c (write_segment): Assume EFAULT is defined. Fixes: debbugs:12968 --- src/ChangeLog | 13 +++++++++++++ src/dired.c | 42 ++++++++++++++++++------------------------ src/fileio.c | 2 -- src/gmalloc.c | 8 -------- src/gnutls.c | 14 +------------- src/keyboard.c | 5 +---- src/lread.c | 2 -- src/process.c | 13 ++----------- src/unexcoff.c | 6 +----- 9 files changed, 36 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index d841812bceb..0594f73540b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2012-11-27 Paul Eggert + + Assume POSIX 1003.1-1988 or later for errno.h (Bug#12968). + * dired.c (directory_files_internal, file_name_completion): + Assume EAGAIN and EINTR are defined. + * fileio.c (Fcopy_file): Assume EISDIR is defined. + * gmalloc.c (ENOMEM, EINVAL): Assume they're defined. + * gnutls.c (emacs_gnutls_write): Assume EAGAIN is defined. + * lread.c (readbyte_from_file): Assume EINTR is defined. + * process.c (wait_reading_process_output, send_process) [subprocesses]: + Assume EIO and EAGAIN are defined. + * unexcoff.c (write_segment): Assume EFAULT is defined. + 2012-11-27 Eli Zaretskii * fontset.c (Finternal_char_font): Return nil on non-GUI frames. diff --git a/src/dired.c b/src/dired.c index 3530b74ecb4..54bdc083f70 100644 --- a/src/dired.c +++ b/src/dired.c @@ -193,19 +193,15 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, errno = 0; dp = readdir (d); - - if (dp == NULL && (0 -#ifdef EAGAIN - || errno == EAGAIN -#endif -#ifdef EINTR - || errno == EINTR -#endif - )) - { QUIT; continue; } - - if (dp == NULL) - break; + if (!dp) + { + if (errno == EAGAIN || errno == EINTR) + { + QUIT; + continue; + } + break; + } len = dirent_namelen (dp); name = finalname = make_unibyte_string (dp->d_name, len); @@ -480,17 +476,15 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag, errno = 0; dp = readdir (d); - if (dp == NULL && (0 -# ifdef EAGAIN - || errno == EAGAIN -# endif -# ifdef EINTR - || errno == EINTR -# endif - )) - { QUIT; continue; } - - if (!dp) break; + if (!dp) + { + if (errno == EAGAIN || errno == EINTR) + { + QUIT; + continue; + } + break; + } len = dirent_namelen (dp); diff --git a/src/fileio.c b/src/fileio.c index 442c66550d3..98b27035597 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -1995,10 +1995,8 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) { if (!(S_ISREG (st.st_mode)) && !(S_ISLNK (st.st_mode))) { -#if defined (EISDIR) /* Get a better looking error message. */ errno = EISDIR; -#endif /* EISDIR */ report_file_error ("Non-regular file", Fcons (file, Qnil)); } } diff --git a/src/gmalloc.c b/src/gmalloc.c index dc584955661..c325ca79910 100644 --- a/src/gmalloc.c +++ b/src/gmalloc.c @@ -1645,14 +1645,6 @@ memalign (size_t alignment, size_t size) return result; } -#ifndef ENOMEM -#define ENOMEM 12 -#endif - -#ifndef EINVAL -#define EINVAL 22 -#endif - int posix_memalign (void **memptr, size_t alignment, size_t size) { diff --git a/src/gnutls.c b/src/gnutls.c index e3d84a0b61b..03f753fa8cc 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -359,12 +359,7 @@ emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, ptrdiff_t nbyte) if (proc->gnutls_initstage != GNUTLS_STAGE_READY) { -#ifdef EWOULDBLOCK - errno = EWOULDBLOCK; -#endif -#ifdef EAGAIN errno = EAGAIN; -#endif return 0; } @@ -384,14 +379,7 @@ emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, ptrdiff_t nbyte) appropriately so that send_process retries the correct way instead of erroring out. */ if (rtnval == GNUTLS_E_AGAIN) - { -#ifdef EWOULDBLOCK - errno = EWOULDBLOCK; -#endif -#ifdef EAGAIN - errno = EAGAIN; -#endif - } + errno = EAGAIN; break; } } diff --git a/src/keyboard.c b/src/keyboard.c index 0ad6d18c044..60e6d71cdff 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -6960,10 +6960,7 @@ tty_read_avail_input (struct terminal *terminal, an EAGAIN error. Does anybody know of a situation where a retry is actually needed? */ #if 0 - nread < 0 && (errno == EAGAIN -#ifdef EFAULT - || errno == EFAULT -#endif + nread < 0 && (errno == EAGAIN || errno == EFAULT #ifdef EBADSLT || errno == EBADSLT #endif diff --git a/src/lread.c b/src/lread.c index 6d0ff9f780e..6647382a254 100644 --- a/src/lread.c +++ b/src/lread.c @@ -440,7 +440,6 @@ readbyte_from_file (int c, Lisp_Object readcharfun) block_input (); c = getc (instream); -#ifdef EINTR /* Interrupted reads have been observed while reading over the network. */ while (c == EOF && ferror (instream) && errno == EINTR) { @@ -450,7 +449,6 @@ readbyte_from_file (int c, Lisp_Object readcharfun) clearerr (instream); c = getc (instream); } -#endif unblock_input (); diff --git a/src/process.c b/src/process.c index 0036ce595f5..b23f06fd025 100644 --- a/src/process.c +++ b/src/process.c @@ -4432,14 +4432,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, total_nread += nread; got_some_input = 1; } -#ifdef EIO - else if (nread == -1 && EIO == errno) + else if (nread == -1 && (errno == EIO || errno == EAGAIN)) break; -#endif -#ifdef EAGAIN - else if (nread == -1 && EAGAIN == errno) - break; -#endif #ifdef EWOULDBLOCK else if (nread == -1 && EWOULDBLOCK == errno) break; @@ -5517,12 +5511,9 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len, if (rv < 0) { - if (0 + if (errno == EAGAIN #ifdef EWOULDBLOCK || errno == EWOULDBLOCK -#endif -#ifdef EAGAIN - || errno == EAGAIN #endif ) /* Buffer is full. Wait, accepting input; diff --git a/src/unexcoff.c b/src/unexcoff.c index 966dd58cb6e..6e29951a962 100644 --- a/src/unexcoff.c +++ b/src/unexcoff.c @@ -332,11 +332,7 @@ write_segment (int new, const char *ptr, const char *end) a gap between the old text segment and the old data segment. This gap has probably been remapped into part of the text segment. So write zeros for it. */ - if (ret == -1 -#ifdef EFAULT - && errno == EFAULT -#endif - ) + if (ret == -1 && errno == EFAULT) { /* Write only a page of zeros at once, so that we don't overshoot the start -- cgit v1.2.1 From 350e0088e1e8acfccd1f2bc6fefd9bcd47fdd746 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 26 Nov 2012 21:38:42 -0800 Subject: Assume POSIX 1003.1-1988 or later for grp.h, pwd.h. * dired.c (stat_uname, stat_gname): * fileio.c (Fexpand_file_name): Remove no-longer-needed casts. --- src/ChangeLog | 5 +++++ src/dired.c | 4 ++-- src/fileio.c | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 0594f73540b..8e53053e89c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,8 +1,13 @@ 2012-11-27 Paul Eggert + Assume POSIX 1003.1-1988 or later for grp.h, pwd.h. + * dired.c (stat_uname, stat_gname): + * fileio.c (Fexpand_file_name): Remove no-longer-needed casts. + Assume POSIX 1003.1-1988 or later for errno.h (Bug#12968). * dired.c (directory_files_internal, file_name_completion): Assume EAGAIN and EINTR are defined. + * fileio.c (Fcopy_file): Assume EISDIR is defined. * gmalloc.c (ENOMEM, EINVAL): Assume they're defined. * gnutls.c (emacs_gnutls_write): Assume EAGAIN is defined. diff --git a/src/dired.c b/src/dired.c index 54bdc083f70..bdb71c46364 100644 --- a/src/dired.c +++ b/src/dired.c @@ -820,7 +820,7 @@ stat_uname (struct stat *st) #ifdef WINDOWSNT return st->st_uname; #else - struct passwd *pw = (struct passwd *) getpwuid (st->st_uid); + struct passwd *pw = getpwuid (st->st_uid); if (pw) return pw->pw_name; @@ -835,7 +835,7 @@ stat_gname (struct stat *st) #ifdef WINDOWSNT return st->st_gname; #else - struct group *gr = (struct group *) getgrgid (st->st_gid); + struct group *gr = getgrgid (st->st_gid); if (gr) return gr->gr_name; diff --git a/src/fileio.c b/src/fileio.c index 98b27035597..48dbf20b88f 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -1042,7 +1042,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) o [p - nm] = 0; block_input (); - pw = (struct passwd *) getpwnam (o + 1); + pw = getpwnam (o + 1); unblock_input (); if (pw) { -- cgit v1.2.1 From 14d2734642c572b6d0a831efc31223bf68ffc269 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Tue, 27 Nov 2012 15:41:52 -0500 Subject: * src/data.c (Fsymbol_value): Doc fix re lexical-binding. --- src/ChangeLog | 4 ++++ src/data.c | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index ce272cc0b53..dfdf41eafdb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2012-11-27 Glenn Morris + + * data.c (Fsymbol_value): Doc fix re lexical-binding. + 2012-11-26 Eli Zaretskii * fontset.c (Finternal_char_font): Return nil on non-GUI frames. diff --git a/src/data.c b/src/data.c index abcdd4dca0d..ff2c0d94b9d 100644 --- a/src/data.c +++ b/src/data.c @@ -1047,7 +1047,9 @@ find_symbol_value (Lisp_Object symbol) } DEFUN ("symbol-value", Fsymbol_value, Ssymbol_value, 1, 1, 0, - doc: /* Return SYMBOL's value. Error if that is void. */) + doc: /* Return SYMBOL's value. Error if that is void. +Note that if `lexical-binding' is in effect, this returns the +global value outside of any lexical scope. */) (Lisp_Object symbol) { Lisp_Object val; -- cgit v1.2.1 From a9de9f0c05f835c7091086d14d49e16f9927e663 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Tue, 27 Nov 2012 15:45:30 -0500 Subject: * src/data.c (Fboundp): Doc fix re lexical-binding. --- src/ChangeLog | 2 +- src/data.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index dfdf41eafdb..a1d09e683c3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,6 +1,6 @@ 2012-11-27 Glenn Morris - * data.c (Fsymbol_value): Doc fix re lexical-binding. + * data.c (Fboundp, Fsymbol_value): Doc fix re lexical-binding. 2012-11-26 Eli Zaretskii diff --git a/src/data.c b/src/data.c index ff2c0d94b9d..658b88e13b1 100644 --- a/src/data.c +++ b/src/data.c @@ -505,7 +505,9 @@ DEFUN ("setcdr", Fsetcdr, Ssetcdr, 2, 2, 0, /* Extract and set components of symbols. */ DEFUN ("boundp", Fboundp, Sboundp, 1, 1, 0, - doc: /* Return t if SYMBOL's value is not void. */) + doc: /* Return t if SYMBOL's value is not void. +Note that if `lexical-binding' is in effect, this refers to the +global value outside of any lexical scope. */) (register Lisp_Object symbol) { Lisp_Object valcontents; -- cgit v1.2.1 From 60aeceb8c41fffee197d43e7eae2b46d9e3fcc74 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 28 Nov 2012 14:33:35 -0800 Subject: * callproc.c (Fcall_process): Fix vfork portability problems. Do not assume that fd[0], count, filefd, and save_environ survive vfork. Fix bug whereby wrong errno value could be reported for pipe failure. Some minor cleanups, too, as follows. Move buf and bufsize to the context where they're needed. Change new_argv to be of type char **, as this is more convenient and avoids casts. (CALLPROC_BUFFER_SIZE_MIN, CALLPROC_BUFFER_SIZE_MAX): Now local constants, not macros. --- src/ChangeLog | 11 ++++++++ src/callproc.c | 86 ++++++++++++++++++++++++++++++++-------------------------- 2 files changed, 59 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index efa404afc2f..da15a612a19 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,14 @@ +2012-11-28 Paul Eggert + + * callproc.c (Fcall_process): Fix vfork portability problems. + Do not assume that fd[0], count, filefd, and save_environ survive + vfork. Fix bug whereby wrong errno value could be reported for + pipe failure. Some minor cleanups, too, as follows. Move buf and + bufsize to the context where they're needed. Change new_argv to + be of type char **, as this is more convenient and avoids casts. + (CALLPROC_BUFFER_SIZE_MIN, CALLPROC_BUFFER_SIZE_MAX): + Now local constants, not macros. + 2012-11-18 Kenichi Handa * font.c (font_unparse_xlfd): Fix previous change. Keep "const" diff --git a/src/callproc.c b/src/callproc.c index c9a504746b3..bba1c043b4c 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -183,16 +183,11 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) { Lisp_Object infile, buffer, current_dir, path, cleanup_info_tail; bool display_p; - int fd[2]; - int filefd; -#define CALLPROC_BUFFER_SIZE_MIN (16 * 1024) -#define CALLPROC_BUFFER_SIZE_MAX (4 * CALLPROC_BUFFER_SIZE_MIN) - char buf[CALLPROC_BUFFER_SIZE_MAX]; - int bufsize = CALLPROC_BUFFER_SIZE_MIN; + int fd0, fd1, filefd; ptrdiff_t count = SPECPDL_INDEX (); USE_SAFE_ALLOCA; - register const unsigned char **new_argv; + char **new_argv; /* File to use for stderr in the child. t means use same as standard output. */ Lisp_Object error_file; @@ -432,12 +427,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) } UNGCPRO; for (i = 4; i < nargs; i++) - new_argv[i - 3] = SDATA (args[i]); + new_argv[i - 3] = SSDATA (args[i]); new_argv[i - 3] = 0; } else new_argv[1] = 0; - new_argv[0] = SDATA (path); + new_argv[0] = SSDATA (path); #ifdef MSDOS /* MW, July 1993 */ @@ -466,29 +461,35 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) } else outfilefd = fd_output; - fd[0] = filefd; - fd[1] = outfilefd; + fd0 = filefd; + fd1 = outfilefd; #endif /* MSDOS */ if (INTEGERP (buffer)) - fd[1] = emacs_open (NULL_DEVICE, O_WRONLY, 0), fd[0] = -1; + { + fd0 = -1; + fd1 = emacs_open (NULL_DEVICE, O_WRONLY, 0); + } else { #ifndef MSDOS - errno = 0; + int fd[2]; if (pipe (fd) == -1) { + int pipe_errno = errno; emacs_close (filefd); + errno = pipe_errno; report_file_error ("Creating process pipe", Qnil); } + fd0 = fd[0]; + fd1 = fd[1]; #endif } { /* child_setup must clobber environ in systems with true vfork. Protect it from permanent change. */ - register char **save_environ = environ; - register int fd1 = fd[1]; + char **save_environ = environ; int fd_error = fd1; if (fd_output >= 0) @@ -520,8 +521,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) if (fd_error < 0) { emacs_close (filefd); - if (fd[0] != filefd) - emacs_close (fd[0]); + if (fd0 != filefd) + emacs_close (fd0); if (fd1 >= 0) emacs_close (fd1); #ifdef MSDOS @@ -538,8 +539,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) /* Note that on MSDOS `child_setup' actually returns the child process exit status, not its PID, so we assign it to `synch_process_retcode' below. */ - pid = child_setup (filefd, outfilefd, fd_error, (char **) new_argv, - 0, current_dir); + pid = child_setup (filefd, outfilefd, fd_error, new_argv, 0, current_dir); /* Record that the synchronous process exited and note its termination status. */ @@ -559,8 +559,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) { /* Since CRLF is converted to LF within `decode_coding', we can always open a file with binary mode. */ - fd[0] = emacs_open (tempfile, O_RDONLY | O_BINARY, 0); - if (fd[0] < 0) + fd0 = emacs_open (tempfile, O_RDONLY | O_BINARY, 0); + if (fd0 < 0) { unlink (tempfile); emacs_close (filefd); @@ -569,11 +569,10 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) } } else - fd[0] = -1; /* We are not going to read from tempfile. */ + fd0 = -1; /* We are not going to read from tempfile. */ #else /* not MSDOS */ #ifdef WINDOWSNT - pid = child_setup (filefd, fd1, fd_error, (char **) new_argv, - 0, current_dir); + pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); #else /* not WINDOWSNT */ block_input (); @@ -586,11 +585,15 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) bool volatile display_p_volatile = display_p; bool volatile output_to_buffer_volatile = output_to_buffer; bool volatile sa_must_free_volatile = sa_must_free; + int volatile fd0_volatile = fd0; int volatile fd1_volatile = fd1; int volatile fd_error_volatile = fd_error; int volatile fd_output_volatile = fd_output; + int volatile filefd_volatile = filefd; + ptrdiff_t volatile count_volatile = count; ptrdiff_t volatile sa_count_volatile = sa_count; - unsigned char const **volatile new_argv_volatile = new_argv; + char **volatile new_argv_volatile = new_argv; + char **volatile new_save_environ = save_environ; pid = vfork (); @@ -598,27 +601,30 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) coding_systems = coding_systems_volatile; current_dir = current_dir_volatile; display_p = display_p_volatile; + output_to_buffer = output_to_buffer_volatile; + sa_must_free = sa_must_free_volatile; + fd0 = fd0_volatile; fd1 = fd1_volatile; fd_error = fd_error_volatile; fd_output = fd_output_volatile; - output_to_buffer = output_to_buffer_volatile; - sa_must_free = sa_must_free_volatile; + filefd = filefd_volatile; + count = count_volatile; sa_count = sa_count_volatile; new_argv = new_argv_volatile; + save_environ = new_save_environ; } if (pid == 0) { - if (fd[0] >= 0) - emacs_close (fd[0]); + if (fd0 >= 0) + emacs_close (fd0); setsid (); /* Emacs ignores SIGPIPE, but the child should not. */ signal (SIGPIPE, SIG_DFL); - child_setup (filefd, fd1, fd_error, (char **) new_argv, - 0, current_dir); + child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); } unblock_input (); @@ -632,7 +638,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) environ = save_environ; - /* Close most of our fd's, but not fd[0] + /* Close most of our file descriptors, but not fd0 since we will use that to read input from. */ emacs_close (filefd); if (fd_output >= 0) @@ -643,15 +649,15 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) if (pid < 0) { - if (fd[0] >= 0) - emacs_close (fd[0]); + if (fd0 >= 0) + emacs_close (fd0); report_file_error ("Doing vfork", Qnil); } if (INTEGERP (buffer)) { - if (fd[0] >= 0) - emacs_close (fd[0]); + if (fd0 >= 0) + emacs_close (fd0); return Qnil; } @@ -666,7 +672,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) #endif /* not MSDOS */ record_unwind_protect (call_process_cleanup, Fcons (Fcurrent_buffer (), - Fcons (INTEGER_TO_CONS (fd[0]), + Fcons (INTEGER_TO_CONS (fd0), cleanup_info_tail))); if (BUFFERP (buffer)) @@ -723,6 +729,10 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) if (output_to_buffer) { + enum { CALLPROC_BUFFER_SIZE_MIN = 16 * 1024 }; + enum { CALLPROC_BUFFER_SIZE_MAX = 4 * CALLPROC_BUFFER_SIZE_MIN }; + char buf[CALLPROC_BUFFER_SIZE_MAX]; + int bufsize = CALLPROC_BUFFER_SIZE_MIN; int nread; bool first = 1; EMACS_INT total_read = 0; @@ -739,7 +749,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) nread = carryover; while (nread < bufsize - 1024) { - int this_read = emacs_read (fd[0], buf + nread, + int this_read = emacs_read (fd0, buf + nread, bufsize - nread); if (this_read < 0) -- cgit v1.2.1 From 4a9204fe04dee76dd067aaf1b078a777d1bb1a91 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 28 Nov 2012 16:36:22 -0800 Subject: * callproc.c (Fcall_process): Don't misreport vfork failure. --- src/ChangeLog | 4 ++++ src/callproc.c | 3 +++ 2 files changed, 7 insertions(+) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index da15a612a19..b1c3b0025e1 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2012-11-29 Paul Eggert + + * callproc.c (Fcall_process): Don't misreport vfork failure. + 2012-11-28 Paul Eggert * callproc.c (Fcall_process): Fix vfork portability problems. diff --git a/src/callproc.c b/src/callproc.c index bba1c043b4c..167663a45c6 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -199,6 +199,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) #else pid_t pid; #endif + int vfork_errno; int fd_output = -1; struct coding_system process_coding; /* coding-system of process output */ struct coding_system argument_coding; /* coding-system of arguments */ @@ -627,6 +628,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); } + vfork_errno = errno; unblock_input (); #endif /* not WINDOWSNT */ @@ -651,6 +653,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) { if (fd0 >= 0) emacs_close (fd0); + errno = vfork_errno; report_file_error ("Doing vfork", Qnil); } -- cgit v1.2.1 From 3940b924e7c9da1e01ff16b4797ac75ef6ce8df4 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 29 Nov 2012 10:00:21 +0400 Subject: * xdisp.c (window_outdated): Remove eassert since it hits some suspicious corner cases (see Bug#13007 and Bug#13012). (mode_line_update_needed): New function. (redisplay_internal, redisplay_window): Use it. (ensure_selected_frame): New function. (redisplay_internal, unwind_redisplay): Use it. (redisplay_internal): Move comment about buffer_shared... (buffer_shared_and_changed): ...near to its real use. --- src/ChangeLog | 11 +++++++++ src/xdisp.c | 77 +++++++++++++++++++++++++++++------------------------------ 2 files changed, 49 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index b1c3b0025e1..b19ecc926d0 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,14 @@ +2012-11-29 Dmitry Antipov + + * xdisp.c (window_outdated): Remove eassert since it hits + some suspicious corner cases (see Bug#13007 and Bug#13012). + (mode_line_update_needed): New function. + (redisplay_internal, redisplay_window): Use it. + (ensure_selected_frame): New function. + (redisplay_internal, unwind_redisplay): Use it. + (redisplay_internal): Move comment about buffer_shared... + (buffer_shared_and_changed): ...near to its real use. + 2012-11-29 Paul Eggert * callproc.c (Fcall_process): Don't misreport vfork failure. diff --git a/src/xdisp.c b/src/xdisp.c index 3b19d5d14d4..8cca758c47b 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10894,16 +10894,18 @@ echo_area_display (int update_frame_p) static int buffer_shared_and_changed (void) { + /* The variable buffer_shared is set in redisplay_window and + indicates that we redisplay a buffer in different windows. */ return (buffer_shared > 1 && UNCHANGED_MODIFIED < MODIFF); } -/* Nonzero if W doesn't reflect the actual state of - current buffer due to its text or overlays change. */ +/* Nonzero if W doesn't reflect the actual state of current buffer due + to its text or overlays change. FIXME: this may be called when + XBUFFER (w->buffer) != current_buffer, which looks suspicious. */ static int window_outdated (struct window *w) { - eassert (XBUFFER (w->buffer) == current_buffer); return (w->last_modified < MODIFF || w->last_overlay_modified < OVERLAY_MODIFF); } @@ -10923,6 +10925,16 @@ window_buffer_changed (struct window *w) != !NILP (w->region_showing))); } +/* Nonzero if W has %c in its mode line and mode line should be updated. */ + +static int +mode_line_update_needed (struct window *w) +{ + return (!NILP (w->column_number_displayed) + && !(PT == w->last_point && !window_outdated (w)) + && (XFASTINT (w->column_number_displayed) != current_column ())); +} + /*********************************************************************** Mode Lines and Frame Titles ***********************************************************************/ @@ -12967,6 +12979,15 @@ select_frame_for_redisplay (Lisp_Object frame) } while (!EQ (frame, old) && (frame = old, 1)); } +/* Make sure that previously selected OLD_FRAME is selected unless it has been + deleted (by an X connection failure during redisplay, for example). */ + +static void +ensure_selected_frame (Lisp_Object old_frame) +{ + if (!EQ (old_frame, selected_frame) && FRAME_LIVE_P (XFRAME (old_frame))) + select_frame_for_redisplay (old_frame); +} #define STOP_POLLING \ do { if (! polling_stopped_here) stop_polling (); \ @@ -13052,13 +13073,11 @@ redisplay_internal (void) /* Remember the currently selected window. */ sw = w; - if (!EQ (old_frame, selected_frame) - && FRAME_LIVE_P (XFRAME (old_frame))) - /* When running redisplay, we play a bit fast-and-loose and allow e.g. - selected_frame and selected_window to be temporarily out-of-sync so - when we come back here via `goto retry', we need to resync because we - may need to run Elisp code (via prepare_menu_bars). */ - select_frame_for_redisplay (old_frame); + /* When running redisplay, we play a bit fast-and-loose and allow e.g. + selected_frame and selected_window to be temporarily out-of-sync so + when we come back here via `goto retry', we need to resync because we + may need to run Elisp code (via prepare_menu_bars). */ + ensure_selected_frame (old_frame); pending = 0; reconsider_clip_changes (w, current_buffer); @@ -13144,21 +13163,13 @@ redisplay_internal (void) count1 = SPECPDL_INDEX (); specbind (Qinhibit_point_motion_hooks, Qt); - /* If %c is in the mode line, update it if needed. */ - if (!NILP (w->column_number_displayed) - /* This alternative quickly identifies a common case - where no change is needed. */ - && !(PT == w->last_point && !window_outdated (w)) - && (XFASTINT (w->column_number_displayed) != current_column ())) + if (mode_line_update_needed (w)) w->update_mode_line = 1; unbind_to (count1, Qnil); FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1; - /* The variable buffer_shared is set in redisplay_window and - indicates that we redisplay a buffer in different windows. See - there. */ consider_all_windows_p = (update_mode_lines || buffer_shared_and_changed () || cursor_type_changed); @@ -13533,14 +13544,11 @@ redisplay_internal (void) } } - if (!EQ (old_frame, selected_frame) - && FRAME_LIVE_P (XFRAME (old_frame))) - /* We played a bit fast-and-loose above and allowed selected_frame - and selected_window to be temporarily out-of-sync but let's make - sure this stays contained. */ - select_frame_for_redisplay (old_frame); - eassert (EQ (XFRAME (selected_frame)->selected_window, - selected_window)); + /* We played a bit fast-and-loose above and allowed selected_frame + and selected_window to be temporarily out-of-sync but let's make + sure this stays contained. */ + ensure_selected_frame (old_frame); + eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window)); if (!pending) { @@ -13759,17 +13767,13 @@ redisplay_preserve_echo_area (int from_where) /* Function registered with record_unwind_protect in redisplay_internal. - Clear redisplaying_p. Also, select the previously - selected frame, unless it has been deleted (by an X connection - failure during redisplay, for example). */ + Clear redisplaying_p. Also select the previously selected frame. */ static Lisp_Object unwind_redisplay (Lisp_Object old_frame) { redisplaying_p = 0; - if (! EQ (old_frame, selected_frame) - && FRAME_LIVE_P (XFRAME (old_frame))) - select_frame_for_redisplay (old_frame); + ensure_selected_frame (old_frame); return Qnil; } @@ -15565,12 +15569,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) if (BYTEPOS (opoint) < CHARPOS (opoint)) emacs_abort (); - /* If %c is in mode line, update it if needed. */ - if (!NILP (w->column_number_displayed) - /* This alternative quickly identifies a common case - where no change is needed. */ - && !(PT == w->last_point && !window_outdated (w)) - && (XFASTINT (w->column_number_displayed) != current_column ())) + if (mode_line_update_needed (w)) update_mode_line = 1; /* Count number of windows showing the selected buffer. An indirect -- cgit v1.2.1 From cbf8a8c744ce75d416139b5886dc655d01f89b57 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 29 Nov 2012 18:26:25 +0200 Subject: Fix wording of commentary to 'struct face' in dispextern.h. --- src/dispextern.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/dispextern.h b/src/dispextern.h index c5ebb808b05..aa40f019fbe 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1572,12 +1572,12 @@ struct face /* Pixmap width and height. */ unsigned int pixmap_w, pixmap_h; - /* Non-zero means characters in this face have a box that thickness - around them. If it is negative, the absolute value indicates the - thickness, and the horizontal lines of box (top and bottom) are - drawn inside of characters glyph area. The vertical lines of box - (left and right) are drawn as the same way as the case that this - value is positive. */ + /* Non-zero means characters in this face have a box of that + thickness around them. If this value is negative, its absolute + value indicates the thickness, and the horizontal (top and + bottom) borders of box are drawn inside of the character glyphs' + area. The vertical (left and right) borders of the box are drawn + in the same way as when this value is positive. */ int box_line_width; /* Type of box drawn. A value of FACE_NO_BOX means no box is drawn -- cgit v1.2.1 From f43ce1c19768f995566cc8e44512633fead20e1d Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 30 Nov 2012 11:23:15 +0200 Subject: Fix commentary to buffer_shared_and_changed. --- src/xdisp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/xdisp.c b/src/xdisp.c index 8cca758c47b..6199c2a436e 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10888,8 +10888,8 @@ echo_area_display (int update_frame_p) return window_height_changed_p; } -/* Nonzero if the current buffer is shown in more than - one window and was modified since last display. */ +/* Nonzero if the current window's buffer is shown in more than one + window and was modified since last redisplay. */ static int buffer_shared_and_changed (void) -- cgit v1.2.1 From c7b36b9550a66a033d42152741bf7e3f4927cb39 Mon Sep 17 00:00:00 2001 From: Fabrice Popineau Date: Fri, 30 Nov 2012 17:14:22 +0200 Subject: Fix compilation problems with 64-bit MSVC compiler. src/w32fns.c: Remove prototype of atof. (syspage_mask): Declared DWORD_PTR, for compatibility with 64-bit builds. (file_dialog_callback): Declared UINT_PTR. src/w32common.h (syspage_mask): Declare DWORD_PTR, for compatibility with 64-bit builds. src/w32.c (FILE_DEVICE_FILE_SYSTEM, METHOD_BUFFERED) (FILE_ANY_ACCESS, CTL_CODE) [_MSC_VER]: Define only if not already defined. --- src/ChangeLog | 14 ++++++++++++++ src/w32.c | 8 ++++++++ src/w32common.h | 2 +- src/w32fns.c | 5 ++--- 4 files changed, 25 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index a1d09e683c3..48776fcbdc7 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2012-11-30 Fabrice Popineau + + * w32fns.c: Remove prototype of atof. + (syspage_mask): Declared DWORD_PTR, for compatibility with 64-bit + builds. + (file_dialog_callback): Declared UINT_PTR. + + * w32common.h (syspage_mask): Declare DWORD_PTR, for compatibility + with 64-bit builds. + + * w32.c (FILE_DEVICE_FILE_SYSTEM, METHOD_BUFFERED) + (FILE_ANY_ACCESS, CTL_CODE) [_MSC_VER]: Define only if not already + defined. + 2012-11-27 Glenn Morris * data.c (Fboundp, Fsymbol_value): Doc fix re lexical-binding. diff --git a/src/w32.c b/src/w32.c index 1c3331516d4..f5630993d43 100644 --- a/src/w32.c +++ b/src/w32.c @@ -150,10 +150,18 @@ typedef struct _REPARSE_DATA_BUFFER { } DUMMYUNIONNAME; } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; +#ifndef FILE_DEVICE_FILE_SYSTEM #define FILE_DEVICE_FILE_SYSTEM 9 +#endif +#ifndef METHOD_BUFFERED #define METHOD_BUFFERED 0 +#endif +#ifndef FILE_ANY_ACCESS #define FILE_ANY_ACCESS 0x00000000 +#endif +#ifndef CTL_CODE #define CTL_CODE(t,f,m,a) (((t)<<16)|((a)<<14)|((f)<<2)|(m)) +#endif #define FSCTL_GET_REPARSE_POINT \ CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) #endif diff --git a/src/w32common.h b/src/w32common.h index 50724e5553c..5e9b61824ae 100644 --- a/src/w32common.h +++ b/src/w32common.h @@ -34,7 +34,7 @@ along with GNU Emacs. If not, see . extern SYSTEM_INFO sysinfo_cache; extern OSVERSIONINFO osinfo_cache; -extern unsigned long syspage_mask; +extern DWORD_PTR syspage_mask; extern int w32_major_version; extern int w32_minor_version; diff --git a/src/w32fns.c b/src/w32fns.c index d598d66b3a5..8e1ecc1cb00 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -80,7 +80,6 @@ void syms_of_w32fns (void); void globals_of_w32fns (void); extern void free_frame_menubar (struct frame *); -extern double atof (const char *); extern int w32_console_toggle_lock_key (int, Lisp_Object); extern void w32_menu_display_help (HWND, HMENU, UINT, UINT); extern void w32_free_menu_strings (HWND); @@ -221,7 +220,7 @@ SYSTEM_INFO sysinfo_cache; /* This gives us version, build, and platform identification. */ OSVERSIONINFO osinfo_cache; -unsigned long syspage_mask = 0; +DWORD_PTR syspage_mask = 0; /* The major and minor versions of NT. */ int w32_major_version; @@ -6019,7 +6018,7 @@ typedef char guichar_t; read-only when "Directories" is selected in the filter. This allows us to work around the fact that the standard Open File dialog does not support directories. */ -static UINT CALLBACK +static UINT_PTR CALLBACK file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_NOTIFY) -- cgit v1.2.1 From f8aff4c6b87598697d7fc67063037ac69f1c9421 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Fri, 30 Nov 2012 18:27:41 +0100 Subject: src/doc.c: Fix bug#13034. (Fdocumentation): Re-add handling of function-documentation, accidentally removed in 2012-11-09T04:10:16Z!monnier@iro.umontreal.ca. --- src/ChangeLog | 5 +++++ src/doc.c | 8 ++++++++ 2 files changed, 13 insertions(+) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index b19ecc926d0..4b5e56f5dc2 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2012-11-30 Juanma Barranquero + + * doc.c (Fdocumentation): Re-add handling of function-documentation, + accidentally removed in 2012-11-09T04:10:16Z!monnier@iro.umontreal.ca (bug#13034). + 2012-11-29 Dmitry Antipov * xdisp.c (window_outdated): Remove eassert since it hits diff --git a/src/doc.c b/src/doc.c index 1d3d1e64442..76008295add 100644 --- a/src/doc.c +++ b/src/doc.c @@ -338,6 +338,14 @@ string is passed through `substitute-command-keys'. */) doc = Qnil; + if (SYMBOLP (function)) + { + Lisp_Object tem = Fget (function, Qfunction_documentation); + if (!NILP (tem)) + return Fdocumentation_property (function, Qfunction_documentation, + raw); + } + fun = Findirect_function (function, Qnil); if (CONSP (fun) && EQ (XCAR (fun), Qmacro)) fun = XCDR (fun); -- cgit v1.2.1 From a24580314dc15730a931068fa93ed1f263640c5e Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Sat, 1 Dec 2012 09:49:48 +0800 Subject: * fileio.c (Vauto_save_list_file_name): Minor doc fix. --- src/ChangeLog | 4 ++++ src/fileio.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 48776fcbdc7..d3d6d3969c8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2012-12-01 Chong Yidong + + * fileio.c (Vauto_save_list_file_name): Doc fix. + 2012-11-30 Fabrice Popineau * w32fns.c: Remove prototype of atof. diff --git a/src/fileio.c b/src/fileio.c index a04eb8ecea1..490116dbc5c 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -5779,7 +5779,7 @@ This applies only to the operation `inhibit-file-name-operation'. */); DEFVAR_LISP ("auto-save-list-file-name", Vauto_save_list_file_name, doc: /* File name in which we write a list of all auto save file names. This variable is initialized automatically from `auto-save-list-file-prefix' -shortly after Emacs reads your `.emacs' file, if you have not yet given it +shortly after Emacs reads your init file, if you have not yet given it a non-nil value. */); Vauto_save_list_file_name = Qnil; -- cgit v1.2.1 From 75b4f59c279cbab4ad6a056b39f876b9a7518267 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Mitsuharu Date: Sat, 1 Dec 2012 10:38:11 +0800 Subject: Fix drawing of relief rects on X and W32. * xterm.c (x_draw_relief_rect, x_draw_image_relief): Fix relief display for sliced images. * w32term.c (w32_draw_relief_rect, x_draw_image_relief): Likewise. Fixes: debbugs:10500 --- src/ChangeLog | 7 +++++++ src/w32term.c | 34 +++++++++++++++++++--------------- src/xterm.c | 32 +++++++++++++++++++------------- 3 files changed, 45 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 4b5e56f5dc2..a6fabdccdea 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2012-12-01 YAMAMOTO Mitsuharu + + * xterm.c (x_draw_relief_rect, x_draw_image_relief): Fix relief + display for sliced images (Bug#10500). + + * w32term.c (w32_draw_relief_rect, x_draw_image_relief): Likewise. + 2012-11-30 Juanma Barranquero * doc.c (Fdocumentation): Re-add handling of function-documentation, diff --git a/src/w32term.c b/src/w32term.c index ab6afd32c75..84f99c090c8 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -1738,8 +1738,8 @@ w32_draw_relief_rect (struct frame *f, if (left_p) for (i = 0; i < width; ++i) w32_fill_area (f, hdc, gc.foreground, - left_x + i, top_y + i, 1, - bottom_y - top_y - 2 * i + 1); + left_x + i, top_y + (i + 1) * top_p, 1, + bottom_y - top_y - (i + 1) * (bot_p + top_p) + 1); if (raised_p) gc.foreground = f->output_data.w32->black_relief.gc->foreground; @@ -1757,8 +1757,8 @@ w32_draw_relief_rect (struct frame *f, if (right_p) for (i = 0; i < width; ++i) w32_fill_area (f, hdc, gc.foreground, - right_x - i, top_y + i + 1, 1, - bottom_y - top_y - 2 * i - 1); + right_x - i, top_y + (i + 1) * top_p, 1, + bottom_y - top_y - (i + 1) * (bot_p + top_p) + 1); w32_set_clip_rectangle (hdc, NULL); @@ -1952,7 +1952,7 @@ x_draw_image_foreground (struct glyph_string *s) static void x_draw_image_relief (struct glyph_string *s) { - int x0, y0, x1, y1, thick, raised_p; + int x1, y1, thick, raised_p, top_p, bot_p, left_p, right_p; RECT r; int x = s->x; int y = s->ybase - image_ascent (s->img, s->face, &s->slice); @@ -1984,19 +1984,23 @@ x_draw_image_relief (struct glyph_string *s) raised_p = s->img->relief > 0; } - x0 = x - thick; - y0 = y - thick; - x1 = x + s->slice.width + thick - 1; - y1 = y + s->slice.height + thick - 1; + x1 = x + s->slice.width - 1; + y1 = y + s->slice.height - 1; + top_p = bot_p = left_p = right_p = 0; + + if (s->slice.x == 0) + x -= thick, left_p = 1; + if (s->slice.y == 0) + y -= thick, top_p = 1; + if (s->slice.x + s->slice.width == s->img->width) + x1 += thick, right_p = 1; + if (s->slice.y + s->slice.height == s->img->height) + y1 += thick, bot_p = 1; x_setup_relief_colors (s); get_glyph_string_clip_rect (s, &r); - w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, - s->slice.y == 0, - s->slice.y + s->slice.height == s->img->height, - s->slice.x == 0, - s->slice.x + s->slice.width == s->img->width, - &r); + w32_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p, + top_p, bot_p, left_p, right_p, &r); } diff --git a/src/xterm.c b/src/xterm.c index 61e942e10d2..b6bd9e9655a 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -2019,7 +2019,8 @@ x_draw_relief_rect (struct frame *f, for (i = (width > 1 ? 1 : 0); i < width; ++i) XDrawLine (dpy, window, gc, - left_x + i, top_y + i, left_x + i, bottom_y - i + 1); + left_x + i, top_y + (i + 1) * top_p, + left_x + i, bottom_y + 1 - (i + 1) * bot_p); } XSetClipMask (dpy, gc, None); @@ -2061,7 +2062,8 @@ x_draw_relief_rect (struct frame *f, XClearArea (dpy, window, right_x, bottom_y, 1, 1, False); for (i = 0; i < width; ++i) XDrawLine (dpy, window, gc, - right_x - i, top_y + i + 1, right_x - i, bottom_y - i); + right_x - i, top_y + (i + 1) * top_p, + right_x - i, bottom_y + 1 - (i + 1) * bot_p); } XSetClipMask (dpy, gc, None); @@ -2255,7 +2257,7 @@ x_draw_image_foreground (struct glyph_string *s) static void x_draw_image_relief (struct glyph_string *s) { - int x0, y0, x1, y1, thick, raised_p; + int x1, y1, thick, raised_p, top_p, bot_p, left_p, right_p; int extra_x, extra_y; XRectangle r; int x = s->x; @@ -2301,19 +2303,23 @@ x_draw_image_relief (struct glyph_string *s) extra_x = extra_y = XINT (Vtool_bar_button_margin); } - x0 = x - thick - extra_x; - y0 = y - thick - extra_y; - x1 = x + s->slice.width + thick - 1 + extra_x; - y1 = y + s->slice.height + thick - 1 + extra_y; + x1 = x + s->slice.width - 1; + y1 = y + s->slice.height - 1; + top_p = bot_p = left_p = right_p = 0; + + if (s->slice.x == 0) + x -= thick, left_p = 1; + if (s->slice.y == 0) + y -= thick, top_p = 1; + if (s->slice.x + s->slice.width == s->img->width) + x1 += thick, right_p = 1; + if (s->slice.y + s->slice.height == s->img->height) + y1 += thick, bot_p = 1; x_setup_relief_colors (s); get_glyph_string_clip_rect (s, &r); - x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, - s->slice.y == 0, - s->slice.y + s->slice.height == s->img->height, - s->slice.x == 0, - s->slice.x + s->slice.width == s->img->width, - &r); + x_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p, + top_p, bot_p, left_p, right_p, &r); } -- cgit v1.2.1 From 3e5490f7a5d4f527cfc17b12a15a54774a3e3c19 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 1 Dec 2012 17:06:14 -0600 Subject: * xterm.c (x_draw_image_relief): Remove unused locals. Fixes: debbugs:10500 --- src/ChangeLog | 4 ++++ src/xterm.c | 15 --------------- 2 files changed, 4 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index a6fabdccdea..11ddb114006 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2012-12-01 Paul Eggert + + * xterm.c (x_draw_image_relief): Remove unused locals (Bug#10500). + 2012-12-01 YAMAMOTO Mitsuharu * xterm.c (x_draw_relief_rect, x_draw_image_relief): Fix relief diff --git a/src/xterm.c b/src/xterm.c index b6bd9e9655a..bbcff8c752f 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -2258,7 +2258,6 @@ static void x_draw_image_relief (struct glyph_string *s) { int x1, y1, thick, raised_p, top_p, bot_p, left_p, right_p; - int extra_x, extra_y; XRectangle r; int x = s->x; int y = s->ybase - image_ascent (s->img, s->face, &s->slice); @@ -2289,20 +2288,6 @@ x_draw_image_relief (struct glyph_string *s) raised_p = s->img->relief > 0; } - extra_x = extra_y = 0; - if (s->face->id == TOOL_BAR_FACE_ID) - { - if (CONSP (Vtool_bar_button_margin) - && INTEGERP (XCAR (Vtool_bar_button_margin)) - && INTEGERP (XCDR (Vtool_bar_button_margin))) - { - extra_x = XINT (XCAR (Vtool_bar_button_margin)); - extra_y = XINT (XCDR (Vtool_bar_button_margin)); - } - else if (INTEGERP (Vtool_bar_button_margin)) - extra_x = extra_y = XINT (Vtool_bar_button_margin); - } - x1 = x + s->slice.width - 1; y1 = y + s->slice.height - 1; top_p = bot_p = left_p = right_p = 0; -- cgit v1.2.1 From 21e54a94d7527e07ddc37066c8cb488f478339c9 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 2 Dec 2012 11:16:45 -0800 Subject: Use execve to avoid need to munge environ. * callproc.c (Fcall_process): * process.c (create_process): Don't save and restore environ; no longer needed. * callproc.c (child_setup): Use execve, not execvp, to preserve environ. Fixes: debbugs:13054 --- src/ChangeLog | 9 +++++++++ src/callproc.c | 17 +---------------- src/process.c | 15 +-------------- 3 files changed, 11 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 11ddb114006..27453ab8a16 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2012-12-02 Paul Eggert + + Use execve to avoid need to munge environ (Bug#13054). + * callproc.c (Fcall_process): + * process.c (create_process): + Don't save and restore environ; no longer needed. + * callproc.c (child_setup): + Use execve, not execvp, to preserve environ. + 2012-12-01 Paul Eggert * xterm.c (x_draw_image_relief): Remove unused locals (Bug#10500). diff --git a/src/callproc.c b/src/callproc.c index 167663a45c6..0242755eb5f 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -488,9 +488,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) } { - /* child_setup must clobber environ in systems with true vfork. - Protect it from permanent change. */ - char **save_environ = environ; int fd_error = fd1; if (fd_output >= 0) @@ -594,7 +591,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) ptrdiff_t volatile count_volatile = count; ptrdiff_t volatile sa_count_volatile = sa_count; char **volatile new_argv_volatile = new_argv; - char **volatile new_save_environ = save_environ; pid = vfork (); @@ -612,7 +608,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) count = count_volatile; sa_count = sa_count_volatile; new_argv = new_argv_volatile; - save_environ = new_save_environ; } if (pid == 0) @@ -638,8 +633,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) emacs_close (fd_error); #endif /* not MSDOS */ - environ = save_environ; - /* Close most of our file descriptors, but not fd0 since we will use that to read input from. */ emacs_close (filefd); @@ -1092,10 +1085,6 @@ add_env (char **env, char **new_env, char *string) Initialize inferior's priority, pgrp, connected dir and environment. then exec another program based on new_argv. - This function may change environ for the superior process. - Therefore, the superior process must save and restore the value - of environ around the vfork and the call to this function. - If SET_PGRP, put the subprocess into a separate process group. CURRENT_DIR is an elisp string giving the path of the current @@ -1298,11 +1287,7 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, setpgid (0, 0); tcsetpgrp (0, pid); - /* execvp does not accept an environment arg so the only way - to pass this environment is to set environ. Our caller - is responsible for restoring the ambient value of environ. */ - environ = env; - execvp (new_argv[0], new_argv); + execve (new_argv[0], new_argv, env); emacs_write (1, "Can't exec program: ", 20); emacs_write (1, new_argv[0], strlen (new_argv[0])); diff --git a/src/process.c b/src/process.c index b23f06fd025..c6139c9f929 100644 --- a/src/process.c +++ b/src/process.c @@ -1586,9 +1586,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) volatile int pty_flag = 0; volatile Lisp_Object lisp_pty_name = Qnil; volatile Lisp_Object encoded_current_dir; -#if HAVE_WORKING_VFORK - char **volatile save_environ; -#endif inchannel = outchannel = -1; @@ -1688,12 +1685,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) pthread_sigmask (SIG_BLOCK, &blocked, 0); #endif -#if HAVE_WORKING_VFORK - /* child_setup must clobber environ on systems with true vfork. - Protect it from permanent change. */ - save_environ = environ; -#endif - #ifndef WINDOWSNT pid = vfork (); if (pid == 0) @@ -1819,10 +1810,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) /* Back in the parent process. */ -#if HAVE_WORKING_VFORK - environ = save_environ; -#endif - XPROCESS (process)->pid = pid; if (0 <= pid) XPROCESS (process)->alive = 1; @@ -1874,7 +1861,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) /* Wait for child_setup to complete in case that vfork is actually defined as fork. The descriptor wait_child_setup[1] of a pipe is closed at the child side either by close-on-exec - on successful execvp or the _exit call in child_setup. */ + on successful execve or the _exit call in child_setup. */ { char dummy; -- cgit v1.2.1 From 2dd2e62273983693076360e1bc4e59a0f9184c68 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 2 Dec 2012 15:11:42 -0800 Subject: Fix xpalloc confusion after memory is exhausted. * alloc.c (xpalloc): Comment fix. * charset.c (Fdefine_charset_internal): If xpalloc exhausts memory and signals an error, do not clear charset_table_size, as charset_table is still valid. * doprnt.c (evxprintf): Clear *BUF after freeing it. --- src/ChangeLog | 7 +++++++ src/alloc.c | 12 ++++++++---- src/charset.c | 4 +++- src/doprnt.c | 5 ++++- 4 files changed, 22 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 27453ab8a16..d5794b513e6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,12 @@ 2012-12-02 Paul Eggert + Fix xpalloc confusion after memory is exhausted. + * alloc.c (xpalloc): Comment fix. + * charset.c (Fdefine_charset_internal): If xpalloc exhausts memory + and signals an error, do not clear charset_table_size, as + charset_table is still valid. + * doprnt.c (evxprintf): Clear *BUF after freeing it. + Use execve to avoid need to munge environ (Bug#13054). * callproc.c (Fcall_process): * process.c (create_process): diff --git a/src/alloc.c b/src/alloc.c index 28c9b51dab4..e504b3d93ec 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -761,13 +761,17 @@ xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size) infinity. If PA is null, then allocate a new array instead of reallocating - the old one. Thus, to grow an array A without saving its old - contents, invoke xfree (A) immediately followed by xgrowalloc (0, - &NITEMS, ...). + the old one. Block interrupt input as needed. If memory exhaustion occurs, set *NITEMS to zero if PA is null, and signal an error (i.e., do not - return). */ + return). + + Thus, to grow an array A without saving its old contents, do + { xfree (A); A = NULL; A = xpalloc (NULL, &AITEMS, ...); }. + The A = NULL avoids a dangling pointer if xpalloc exhausts memory + and signals an error, and later this code is reexecuted and + attempts to free A. */ void * xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, diff --git a/src/charset.c b/src/charset.c index c9133c780e8..43be0e9c780 100644 --- a/src/charset.c +++ b/src/charset.c @@ -1142,12 +1142,14 @@ usage: (define-charset-internal ...) */) example, the IDs are stuffed into struct coding_system.charbuf[i] entries, which are 'int'. */ int old_size = charset_table_size; + ptrdiff_t new_size = old_size; struct charset *new_table = - xpalloc (0, &charset_table_size, 1, + xpalloc (0, &new_size, 1, min (INT_MAX, MOST_POSITIVE_FIXNUM), sizeof *charset_table); memcpy (new_table, charset_table, old_size * sizeof *new_table); charset_table = new_table; + charset_table_size = new_size; /* FIXME: This leaks memory, as the old charset_table becomes unreachable. If the old charset table is charset_table_init then this leak is intentional; otherwise, it's unclear. diff --git a/src/doprnt.c b/src/doprnt.c index caa56d6ae88..8cab219aafa 100644 --- a/src/doprnt.c +++ b/src/doprnt.c @@ -521,7 +521,10 @@ evxprintf (char **buf, ptrdiff_t *bufsize, if (nbytes < *bufsize - 1) return nbytes; if (*buf != nonheapbuf) - xfree (*buf); + { + xfree (*buf); + *buf = NULL; + } *buf = xpalloc (NULL, bufsize, 1, bufsize_max, 1); } } -- cgit v1.2.1 From 62c2e5ed3a9c991cef2594b44afc74893f6ce26b Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Mon, 3 Dec 2012 12:06:02 +0400 Subject: * alloc.c (free_save_value): New function. (safe_alloca_unwind): Use it. * lisp.h (free_save_value): New prototype. * editfns.c (save_excursion_save): Use Lisp_Misc_Save_Value. Add comment. (save_excursion_restore): Adjust to match saved data structure. Use free_save_value to offload some work from GC. Drop obsolete #if 0 code. --- src/ChangeLog | 11 +++++++++ src/alloc.c | 20 +++++++++++----- src/editfns.c | 77 +++++++++++++++++++++++++++-------------------------------- src/lisp.h | 1 + 4 files changed, 61 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 0808dad2c93..035ef88c485 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,14 @@ +2012-12-03 Dmitry Antipov + + * alloc.c (free_save_value): New function. + (safe_alloca_unwind): Use it. + * lisp.h (free_save_value): New prototype. + * editfns.c (save_excursion_save): Use Lisp_Misc_Save_Value. + Add comment. + (save_excursion_restore): Adjust to match saved data structure. + Use free_save_value to offload some work from GC. Drop obsolete + #if 0 code. + 2012-12-03 Chong Yidong * fileio.c (Vauto_save_list_file_name): Doc fix. diff --git a/src/alloc.c b/src/alloc.c index e504b3d93ec..0f105f87207 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -826,12 +826,7 @@ xstrdup (const char *s) Lisp_Object safe_alloca_unwind (Lisp_Object arg) { - register struct Lisp_Save_Value *p = XSAVE_VALUE (arg); - - p->dogc = 0; - xfree (p->pointer); - p->pointer = 0; - free_misc (arg); + free_save_value (arg); return Qnil; } @@ -3365,6 +3360,19 @@ make_save_value (void *pointer, ptrdiff_t integer) return val; } +/* Free a Lisp_Misc_Save_Value object. */ + +void +free_save_value (Lisp_Object save) +{ + register struct Lisp_Save_Value *p = XSAVE_VALUE (save); + + p->dogc = 0; + xfree (p->pointer); + p->pointer = NULL; + free_misc (save); +} + /* Return a Lisp_Misc_Overlay object with specified START, END and PLIST. */ Lisp_Object diff --git a/src/editfns.c b/src/editfns.c index 8122ffdd0d4..390ce21bbca 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -813,38 +813,43 @@ This function does not move point. */) Qnil, Qt, Qnil); } - +/* Save current buffer state for `save-excursion' special form. + We (ab)use Lisp_Misc_Save_Value to allow explicit free and so + offload some work from GC. */ + Lisp_Object save_excursion_save (void) { - bool visible = (XBUFFER (XWINDOW (selected_window)->buffer) - == current_buffer); + Lisp_Object save, *data = xmalloc (word_size * 4); + + data[0] = Fpoint_marker (); /* Do not copy the mark if it points to nowhere. */ - Lisp_Object mark = (XMARKER (BVAR (current_buffer, mark))->buffer - ? Fcopy_marker (BVAR (current_buffer, mark), Qnil) - : Qnil); - - return Fcons (Fpoint_marker (), - Fcons (mark, - Fcons (visible ? Qt : Qnil, - Fcons (BVAR (current_buffer, mark_active), - selected_window)))); + data[1] = (XMARKER (BVAR (current_buffer, mark))->buffer + ? Fcopy_marker (BVAR (current_buffer, mark), Qnil) + : Qnil); + /* Selected window if current buffer is shown in it, nil otherwise. */ + data[2] = ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer) + ? selected_window : Qnil); + data[3] = BVAR (current_buffer, mark_active); + + save = make_save_value (data, 4); + XSAVE_VALUE (save)->dogc = 1; + return save; } +/* Restore saved buffer before leaving `save-excursion' special form. */ + Lisp_Object save_excursion_restore (Lisp_Object info) { - Lisp_Object tem, tem1, omark, nmark; + Lisp_Object tem, tem1, omark, nmark, *data = XSAVE_VALUE (info)->pointer; struct gcpro gcpro1, gcpro2, gcpro3; - bool visible_p; - tem = Fmarker_buffer (XCAR (info)); - /* If buffer being returned to is now deleted, avoid error */ - /* Otherwise could get error here while unwinding to top level - and crash */ - /* In that case, Fmarker_buffer returns nil now. */ + tem = Fmarker_buffer (data[0]); + /* If we're unwinding to top level, saved buffer may be deleted. This + means that all of its markers are unchained and so tem is nil. */ if (NILP (tem)) - return Qnil; + goto out; omark = nmark = Qnil; GCPRO3 (info, omark, nmark); @@ -852,13 +857,12 @@ save_excursion_restore (Lisp_Object info) Fset_buffer (tem); /* Point marker. */ - tem = XCAR (info); + tem = data[0]; Fgoto_char (tem); unchain_marker (XMARKER (tem)); /* Mark marker. */ - info = XCDR (info); - tem = XCAR (info); + tem = data[1]; omark = Fmarker_position (BVAR (current_buffer, mark)); if (NILP (tem)) unchain_marker (XMARKER (BVAR (current_buffer, mark))); @@ -869,23 +873,8 @@ save_excursion_restore (Lisp_Object info) unchain_marker (XMARKER (tem)); } - /* visible */ - info = XCDR (info); - visible_p = !NILP (XCAR (info)); - -#if 0 /* We used to make the current buffer visible in the selected window - if that was true previously. That avoids some anomalies. - But it creates others, and it wasn't documented, and it is simpler - and cleaner never to alter the window/buffer connections. */ - tem1 = Fcar (tem); - if (!NILP (tem1) - && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer)) - Fswitch_to_buffer (Fcurrent_buffer (), Qnil); -#endif /* 0 */ - - /* Mark active */ - info = XCDR (info); - tem = XCAR (info); + /* Mark active. */ + tem = data[3]; tem1 = BVAR (current_buffer, mark_active); bset_mark_active (current_buffer, tem); @@ -909,8 +898,8 @@ save_excursion_restore (Lisp_Object info) /* If buffer was visible in a window, and a different window was selected, and the old selected window is still showing this buffer, restore point in that window. */ - tem = XCDR (info); - if (visible_p + tem = data[2]; + if (WINDOWP (tem) && !EQ (tem, selected_window) && (tem1 = XWINDOW (tem)->buffer, (/* Window is live... */ @@ -920,6 +909,10 @@ save_excursion_restore (Lisp_Object info) Fset_window_point (tem, make_number (PT)); UNGCPRO; + + out: + + free_save_value (info); return Qnil; } diff --git a/src/lisp.h b/src/lisp.h index 419176d06c8..4dae66eec96 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2963,6 +2963,7 @@ extern Lisp_Object make_float (double); extern void display_malloc_warning (void); extern ptrdiff_t inhibit_garbage_collection (void); extern Lisp_Object make_save_value (void *, ptrdiff_t); +extern void free_save_value (Lisp_Object); extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); extern void free_marker (Lisp_Object); extern void free_cons (struct Lisp_Cons *); -- cgit v1.2.1 From 20edc1c9edbb8c896df0a54769a4da825017de22 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Mon, 3 Dec 2012 18:13:06 +0400 Subject: * lisp.h (modify_region): Rename to... (modify_region_1): ...new prototype. * textprop.c (modify_region): Now static. Adjust users. * insdel.c (modify_region): Rename to... (modify_region_1): ...new function to work with current buffer. Adjust comment and users. Use true and false for boolean arg. --- src/ChangeLog | 9 +++++++++ src/casefiddle.c | 2 +- src/editfns.c | 14 +++++++------- src/insdel.c | 21 +++++++-------------- src/lisp.h | 2 +- src/textprop.c | 24 +++++++++++++++++------- 6 files changed, 42 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 035ef88c485..5bcd89e4ca1 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2012-12-03 Dmitry Antipov + + * lisp.h (modify_region): Rename to... + (modify_region_1): ...new prototype. + * textprop.c (modify_region): Now static. Adjust users. + * insdel.c (modify_region): Rename to... + (modify_region_1): ...new function to work with current buffer. + Adjust comment and users. Use true and false for booleans. + 2012-12-03 Dmitry Antipov * alloc.c (free_save_value): New function. diff --git a/src/casefiddle.c b/src/casefiddle.c index e3654627576..d9c6a078973 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c @@ -213,7 +213,7 @@ casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e) validate_region (&b, &e); start = XFASTINT (b); end = XFASTINT (e); - modify_region (current_buffer, start, end, 0); + modify_region_1 (start, end, false); record_change (start, end - start); start_byte = CHAR_TO_BYTE (start); diff --git a/src/editfns.c b/src/editfns.c index 390ce21bbca..d60f417e561 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2922,7 +2922,7 @@ Both characters must have the same length of multi-byte form. */) else if (!changed) { changed = -1; - modify_region (current_buffer, pos, XINT (end), 0); + modify_region_1 (pos, XINT (end), false); if (! NILP (noundo)) { @@ -3098,7 +3098,7 @@ It returns the number of characters changed. */) pos = XINT (start); pos_byte = CHAR_TO_BYTE (pos); end_pos = XINT (end); - modify_region (current_buffer, pos, end_pos, 0); + modify_region_1 (pos, end_pos, false); cnt = 0; for (; pos < end_pos; ) @@ -4622,7 +4622,7 @@ Transposing beyond buffer boundaries is an error. */) if (end1 == start2) /* adjacent regions */ { - modify_region (current_buffer, start1, end2, 0); + modify_region_1 (start1, end2, false); record_change (start1, len1 + len2); tmp_interval1 = copy_intervals (cur_intv, start1, len1); @@ -4681,8 +4681,8 @@ Transposing beyond buffer boundaries is an error. */) { USE_SAFE_ALLOCA; - modify_region (current_buffer, start1, end1, 0); - modify_region (current_buffer, start2, end2, 0); + modify_region_1 (start1, end1, false); + modify_region_1 (start2, end2, false); record_change (start1, len1); record_change (start2, len2); tmp_interval1 = copy_intervals (cur_intv, start1, len1); @@ -4715,7 +4715,7 @@ Transposing beyond buffer boundaries is an error. */) { USE_SAFE_ALLOCA; - modify_region (current_buffer, start1, end2, 0); + modify_region_1 (start1, end2, false); record_change (start1, (end2 - start1)); tmp_interval1 = copy_intervals (cur_intv, start1, len1); tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); @@ -4748,7 +4748,7 @@ Transposing beyond buffer boundaries is an error. */) USE_SAFE_ALLOCA; record_change (start1, (end2 - start1)); - modify_region (current_buffer, start1, end2, 0); + modify_region_1 (start1, end2, false); tmp_interval1 = copy_intervals (cur_intv, start1, len1); tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); diff --git a/src/insdel.c b/src/insdel.c index 87010cd8251..892ca3d5216 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -1755,9 +1755,9 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte, return deletion; } - -/* Call this if you're about to change the region of BUFFER from - character positions START to END. This checks the read-only + +/* Call this if you're about to change the region of current buffer + from character positions START to END. This checks the read-only properties of the region, calls the necessary modification hooks, and warns the next redisplay that it should pay attention to that area. @@ -1766,16 +1766,11 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte, Otherwise set CHARS_MODIFF to the new value of MODIFF. */ void -modify_region (struct buffer *buffer, ptrdiff_t start, ptrdiff_t end, - bool preserve_chars_modiff) +modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff) { - struct buffer *old_buffer = current_buffer; - - set_buffer_internal (buffer); - prepare_to_modify_buffer (start, end, NULL); - BUF_COMPUTE_UNCHANGED (buffer, start - 1, end); + BUF_COMPUTE_UNCHANGED (current_buffer, start - 1, end); if (MODIFF <= SAVE_MODIFF) record_first_change (); @@ -1783,11 +1778,9 @@ modify_region (struct buffer *buffer, ptrdiff_t start, ptrdiff_t end, if (! preserve_chars_modiff) CHARS_MODIFF = MODIFF; - bset_point_before_scroll (buffer, Qnil); - - set_buffer_internal (old_buffer); + bset_point_before_scroll (current_buffer, Qnil); } - + /* Check that it is okay to modify the buffer between START and END, which are char positions. diff --git a/src/lisp.h b/src/lisp.h index 4dae66eec96..9ce90c8a3f7 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2796,7 +2796,7 @@ extern void del_range_byte (ptrdiff_t, ptrdiff_t, bool); extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); -extern void modify_region (struct buffer *, ptrdiff_t, ptrdiff_t, bool); +extern void modify_region_1 (ptrdiff_t, ptrdiff_t, bool); extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *); extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, diff --git a/src/textprop.c b/src/textprop.c index 379eafb73f7..1ce44ad60ac 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -85,8 +85,18 @@ text_read_only (Lisp_Object propval) xsignal0 (Qtext_read_only); } +/* Prepare to modify the region of BUFFER from START to END. */ + +static void +modify_region (Lisp_Object buffer, Lisp_Object start, Lisp_Object end) +{ + struct buffer *buf = XBUFFER (buffer), *old = current_buffer; + + set_buffer_internal (buf); + modify_region_1 (XINT (start), XINT (end), true); + set_buffer_internal (old); +} - /* Extract the interval at the position pointed to by BEGIN from OBJECT, a string or buffer. Additionally, check that the positions pointed to by BEGIN and END are within the bounds of OBJECT, and @@ -1164,7 +1174,7 @@ Return t if any property value actually changed, nil otherwise. */) } if (BUFFERP (object)) - modify_region (XBUFFER (object), XINT (start), XINT (end), 1); + modify_region (object, start, end); /* We are at the beginning of interval I, with LEN chars to scan. */ for (;;) @@ -1302,7 +1312,7 @@ set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, } if (BUFFERP (object) && !NILP (coherent_change_p)) - modify_region (XBUFFER (object), XINT (start), XINT (end), 1); + modify_region (object, start, end); set_text_properties_1 (start, end, properties, object, i); @@ -1451,7 +1461,7 @@ Use `set-text-properties' if you want to remove all text properties. */) } if (BUFFERP (object)) - modify_region (XBUFFER (object), XINT (start), XINT (end), 1); + modify_region (object, start, end); /* We are at the beginning of an interval, with len to scan */ for (;;) @@ -1565,7 +1575,7 @@ Return t if any property was actually removed, nil otherwise. */) else if (LENGTH (i) == len) { if (!modified && BUFFERP (object)) - modify_region (XBUFFER (object), XINT (start), XINT (end), 1); + modify_region (object, start, end); remove_properties (Qnil, properties, i, object); if (BUFFERP (object)) signal_after_change (XINT (start), XINT (end) - XINT (start), @@ -1578,7 +1588,7 @@ Return t if any property was actually removed, nil otherwise. */) i = split_interval_left (i, len); copy_properties (unchanged, i); if (!modified && BUFFERP (object)) - modify_region (XBUFFER (object), XINT (start), XINT (end), 1); + modify_region (object, start, end); remove_properties (Qnil, properties, i, object); if (BUFFERP (object)) signal_after_change (XINT (start), XINT (end) - XINT (start), @@ -1589,7 +1599,7 @@ Return t if any property was actually removed, nil otherwise. */) if (interval_has_some_properties_list (properties, i)) { if (!modified && BUFFERP (object)) - modify_region (XBUFFER (object), XINT (start), XINT (end), 1); + modify_region (object, start, end); remove_properties (Qnil, properties, i, object); modified = 1; } -- cgit v1.2.1 From 005c8d1340722a2a34b447a2ade4e4bf5bd077d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Dj=C3=A4rv?= Date: Mon, 3 Dec 2012 20:16:17 +0100 Subject: * gtkutil.c (my_log_handler): New function. (xg_set_geometry): Set log handler to my_log_handler. Fixes: debbugs:11177 --- src/ChangeLog | 5 +++++ src/gtkutil.c | 15 +++++++++++++++ 2 files changed, 20 insertions(+) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 5bcd89e4ca1..f2b65db257d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2012-12-03 Jan Djärv + + * gtkutil.c (my_log_handler): New function. + (xg_set_geometry): Set log handler to my_log_handler (Bug#11177). + 2012-12-03 Dmitry Antipov * lisp.h (modify_region): Rename to... diff --git a/src/gtkutil.c b/src/gtkutil.c index 4367b534cb9..52a6c37b0d5 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -813,6 +813,14 @@ xg_hide_tooltip (FRAME_PTR f) General functions for creating widgets, resizing, events, e.t.c. ***********************************************************************/ +static void +my_log_handler (const gchar *log_domain, GLogLevelFlags log_level, + const gchar *msg, gpointer user_data) +{ + if (!strstr (msg, "visible children")) + fprintf (stderr, "XX %s-WARNING **: %s\n", log_domain, msg); +} + /* Make a geometry string and pass that to GTK. It seems this is the only way to get geometry position right if the user explicitly asked for a position when starting Emacs. @@ -828,6 +836,7 @@ xg_set_geometry (FRAME_PTR f) int top = f->top_pos; int yneg = f->size_hint_flags & YNegative; char geom_str[sizeof "=x--" + 4 * INT_STRLEN_BOUND (int)]; + guint id; if (xneg) left = -left; @@ -840,9 +849,15 @@ xg_set_geometry (FRAME_PTR f) (xneg ? '-' : '+'), left, (yneg ? '-' : '+'), top); + /* Silence warning about visible children. */ + id = g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL + | G_LOG_FLAG_RECURSION, my_log_handler, NULL); + if (!gtk_window_parse_geometry (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), geom_str)) fprintf (stderr, "Failed to parse: '%s'\n", geom_str); + + g_log_remove_handler ("Gtk", id); } } -- cgit v1.2.1 From 3cf3c60796b2dbff6f7300d64210acd1029a17c4 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 3 Dec 2012 22:48:12 +0200 Subject: Fix bug #13055 with cursor positioning inside scroll-margin. src/xdisp.c (redisplay_window): If the cursor is visible, but inside the scroll margin, move point outside the margin. --- src/ChangeLog | 5 +++++ src/xdisp.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index f2b65db257d..20ed5a99a1a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2012-12-03 Eli Zaretskii + + * xdisp.c (redisplay_window): If the cursor is visible, but inside + the scroll margin, move point outside the margin. (Bug#13055) + 2012-12-03 Jan Djärv * gtkutil.c (my_log_handler): New function. diff --git a/src/xdisp.c b/src/xdisp.c index 6199c2a436e..5f6d69dea3a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -15717,6 +15717,35 @@ redisplay_window (Lisp_Object window, int just_this_one_p) Move it back to a fully-visible line. */ new_vpos = window_box_height (w); } + else if (w->cursor.vpos >=0) + { + /* Some people insist on not letting point enter the scroll + margin, even though this part handles windows that didn't + scroll at all. */ + struct frame *f = XFRAME (w->frame); + int margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4); + int pixel_margin = margin * FRAME_LINE_HEIGHT (f); + bool header_line = WINDOW_WANTS_HEADER_LINE_P (w); + + /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop + below, which finds the row to move point to, advances by + the Y coordinate of the _next_ row, see the definition of + MATRIX_ROW_BOTTOM_Y. */ + if (w->cursor.vpos < margin + header_line) + new_vpos + = pixel_margin + (header_line + ? CURRENT_HEADER_LINE_HEIGHT (w) + : 0) + FRAME_LINE_HEIGHT (f); + else + { + int window_height = window_box_height (w); + + if (header_line) + window_height += CURRENT_HEADER_LINE_HEIGHT (w); + if (w->cursor.y >= window_height - pixel_margin) + new_vpos = window_height - pixel_margin; + } + } /* If we need to move point for either of the above reasons, now actually do it. */ -- cgit v1.2.1 From bc9dbce6ee527ded152682c98f5f82e42c33dde9 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 3 Dec 2012 13:07:47 -0800 Subject: * bytecode.c, lisp.h (Qbytecode): Remove. No longer needed after 2012-11-20 interactive-p changes. --- src/ChangeLog | 5 +++++ src/bytecode.c | 4 ---- src/lisp.h | 1 - 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 20ed5a99a1a..019caf306b7 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2012-12-03 Paul Eggert + + * bytecode.c, lisp.h (Qbytecode): Remove. + No longer needed after 2012-11-20 interactive-p changes. + 2012-12-03 Eli Zaretskii * xdisp.c (redisplay_window): If the cursor is visible, but inside diff --git a/src/bytecode.c b/src/bytecode.c index 3267c7c8c76..4c5ac151de1 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -87,8 +87,6 @@ Lisp_Object Qbyte_code_meter; #endif /* BYTE_CODE_METER */ -Lisp_Object Qbytecode; - /* Byte codes: */ #define BYTE_CODES \ @@ -1963,8 +1961,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, void syms_of_bytecode (void) { - DEFSYM (Qbytecode, "byte-code"); - defsubr (&Sbyte_code); #ifdef BYTE_CODE_METER diff --git a/src/lisp.h b/src/lisp.h index 9ce90c8a3f7..6bf54ed721b 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3394,7 +3394,6 @@ extern void syms_of_doc (void); extern int read_bytecode_char (bool); /* Defined in bytecode.c. */ -extern Lisp_Object Qbytecode; extern void syms_of_bytecode (void); extern struct byte_stack *byte_stack_list; #if BYTE_MARK_STACK -- cgit v1.2.1 From bb5f74ee84398a56435baa2ef15e12d8a35e5e03 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 3 Dec 2012 13:42:12 -0800 Subject: Don't let call-process be a zombie factory. Fixing this bug required some cleanup of the signal-handling code. As a side effect, this change also fixes a longstanding rare race condition whereby Emacs could mistakenly kill unrelated processes, and it fixes a bug where a second C-g does not kill a recalcitrant synchronous process in GNU/Linux and similar platforms. The patch should also fix the last vestiges of Bug#9488, a bug which has mostly been fixed on the trunk by other changes. * callproc.c, process.h (synch_process_alive, synch_process_death) (synch_process_termsig, sync_process_retcode): Remove. All uses removed, to simplify analysis and so that less consing is done inside critical sections. * callproc.c (call_process_exited): Remove. All uses replaced with !synch_process_pid. * callproc.c (synch_process_pid, synch_process_fd): New static vars. These take the role of what used to be in unwind-protect arg. All uses changed. (block_child_signal, unblock_child_signal): New functions, to avoid races that could kill innocent-victim processes. (call_process_kill, call_process_cleanup, Fcall_process): Use them. (call_process_kill): Record killed processes as deleted, so that zombies do not clutter up the system. Do this inside a critical section, to avoid a race that would allow the clutter. (call_process_cleanup): Fix code so that the second C-g works again on common platforms such as GNU/Linux. (Fcall_process): Create the child process in a critical section, to fix a race condition. If creating an asynchronous process, record it as deleted so that zombies do not clutter up the system. Do unwind-protect for WINDOWSNT too, as that's simpler in the light of these changes. Omit unnecessary call to emacs_close before failure, as the unwind-protect code does that. * callproc.c (call_process_cleanup): * w32proc.c (waitpid): Simplify now that synch_process_alive is gone. * process.c (record_deleted_pid): New function, containing code refactored out of Fdelete_process. (Fdelete_process): Use it. (process_status_retrieved): Remove. All callers changed to use child_status_change. (record_child_status_change): Remove, folding its contents into ... (handle_child_signal): ... this signal handler. Now, this function is purely a handler for SIGCHLD, and is not called after a synchronous waitpid returns; the synchronous code is moved to wait_for_termination. There is no need to worry about reaping more than one child now. * sysdep.c (get_child_status, child_status_changed): New functions. (wait_for_termination): Now takes int * status and bool interruptible arguments, too. Do not record child status change; that's now the caller's responsibility. All callers changed. Reimplement in terms of get_child_status. (wait_for_termination_1, interruptible_wait_for_termination): Remove. All callers changed to use wait_for_termination. * syswait.h: Include , for bool. (record_child_status_change, interruptible_wait_for_termination): Remove decls. (record_deleted_pid, child_status_changed): New decls. (wait_for_termination): Adjust to API changes noted above. Fixes: debbugs:12980 --- src/ChangeLog | 57 ++++++++++++++ src/callproc.c | 238 +++++++++++++++++++++++++++++++-------------------------- src/process.c | 136 +++++++++++++-------------------- src/process.h | 17 ----- src/sysdep.c | 80 ++++++++++++------- src/syswait.h | 7 +- src/w32proc.c | 28 +------ 7 files changed, 296 insertions(+), 267 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 019caf306b7..1a91eb0f1a3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,62 @@ 2012-12-03 Paul Eggert + Don't let call-process be a zombie factory (Bug#12980). + Fixing this bug required some cleanup of the signal-handling code. + As a side effect, this change also fixes a longstanding rare race + condition whereby Emacs could mistakenly kill unrelated processes, + and it fixes a bug where a second C-g does not kill a recalcitrant + synchronous process in GNU/Linux and similar platforms. + The patch should also fix the last vestiges of Bug#9488, + a bug which has mostly been fixed on the trunk by other changes. + * callproc.c, process.h (synch_process_alive, synch_process_death) + (synch_process_termsig, sync_process_retcode): + Remove. All uses removed, to simplify analysis and so that + less consing is done inside critical sections. + * callproc.c (call_process_exited): Remove. All uses replaced + with !synch_process_pid. + * callproc.c (synch_process_pid, synch_process_fd): New static vars. + These take the role of what used to be in unwind-protect arg. + All uses changed. + (block_child_signal, unblock_child_signal): + New functions, to avoid races that could kill innocent-victim processes. + (call_process_kill, call_process_cleanup, Fcall_process): Use them. + (call_process_kill): Record killed processes as deleted, so that + zombies do not clutter up the system. Do this inside a critical + section, to avoid a race that would allow the clutter. + (call_process_cleanup): Fix code so that the second C-g works again + on common platforms such as GNU/Linux. + (Fcall_process): Create the child process in a critical section, + to fix a race condition. If creating an asynchronous process, + record it as deleted so that zombies do not clutter up the system. + Do unwind-protect for WINDOWSNT too, as that's simpler in the + light of these changes. Omit unnecessary call to emacs_close + before failure, as the unwind-protect code does that. + * callproc.c (call_process_cleanup): + * w32proc.c (waitpid): Simplify now that synch_process_alive is gone. + * process.c (record_deleted_pid): New function, containing + code refactored out of Fdelete_process. + (Fdelete_process): Use it. + (process_status_retrieved): Remove. All callers changed to use + child_status_change. + (record_child_status_change): Remove, folding its contents into ... + (handle_child_signal): ... this signal handler. Now, this + function is purely a handler for SIGCHLD, and is not called after + a synchronous waitpid returns; the synchronous code is moved to + wait_for_termination. There is no need to worry about reaping + more than one child now. + * sysdep.c (get_child_status, child_status_changed): New functions. + (wait_for_termination): Now takes int * status and bool + interruptible arguments, too. Do not record child status change; + that's now the caller's responsibility. All callers changed. + Reimplement in terms of get_child_status. + (wait_for_termination_1, interruptible_wait_for_termination): + Remove. All callers changed to use wait_for_termination. + * syswait.h: Include , for bool. + (record_child_status_change, interruptible_wait_for_termination): + Remove decls. + (record_deleted_pid, child_status_changed): New decls. + (wait_for_termination): Adjust to API changes noted above. + * bytecode.c, lisp.h (Qbytecode): Remove. No longer needed after 2012-11-20 interactive-p changes. diff --git a/src/callproc.c b/src/callproc.c index 0242755eb5f..21c52d09e6b 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -67,88 +67,110 @@ along with GNU Emacs. If not, see . */ /* Pattern used by call-process-region to make temp files. */ static Lisp_Object Vtemp_file_name_pattern; -/* True if we are about to fork off a synchronous process or if we - are waiting for it. */ -bool synch_process_alive; - -/* Nonzero => this is a string explaining death of synchronous subprocess. */ -const char *synch_process_death; +/* The next two variables are valid only while record-unwind-protect + is in place during call-process for a synchronous subprocess. At + other times, their contents are irrelevant. Doing this via static + C variables is more convenient than putting them into the arguments + of record-unwind-protect, as they need to be updated at randomish + times in the code, and Lisp cannot always store these values as + Emacs integers. It's safe to use static variables here, as the + code is never invoked reentrantly. */ + +/* If nonzero, a process-ID that has not been reaped. */ +static pid_t synch_process_pid; + +/* If nonnegative, a file descriptor that has not been closed. */ +static int synch_process_fd; + +/* Block SIGCHLD. */ -/* Nonzero => this is the signal number that terminated the subprocess. */ -int synch_process_termsig; +static void +block_child_signal (void) +{ +#ifdef SIGCHLD + sigset_t blocked; + sigemptyset (&blocked); + sigaddset (&blocked, SIGCHLD); + pthread_sigmask (SIG_BLOCK, &blocked, 0); +#endif +} -/* If synch_process_death is zero, - this is exit code of synchronous subprocess. */ -int synch_process_retcode; +/* Unblock SIGCHLD. */ - -/* Clean up when exiting Fcall_process. - On MSDOS, delete the temporary file on any kind of termination. - On Unix, kill the process and any children on termination by signal. */ +static void +unblock_child_signal (void) +{ +#ifdef SIGCHLD + pthread_sigmask (SIG_SETMASK, &empty_mask, 0); +#endif +} -/* True if this is termination due to exit. */ -static bool call_process_exited; +/* Clean up when exiting call_process_cleanup. */ static Lisp_Object -call_process_kill (Lisp_Object fdpid) +call_process_kill (Lisp_Object ignored) { - int fd; - pid_t pid; - CONS_TO_INTEGER (Fcar (fdpid), int, fd); - CONS_TO_INTEGER (Fcdr (fdpid), pid_t, pid); - emacs_close (fd); - EMACS_KILLPG (pid, SIGKILL); - synch_process_alive = 0; + if (0 <= synch_process_fd) + emacs_close (synch_process_fd); + + /* If PID is reapable, kill it and record it as a deleted process. + Do this in a critical section. Unless PID is wedged it will be + reaped on receipt of the first SIGCHLD after the critical section. */ + if (synch_process_pid) + { + block_child_signal (); + record_deleted_pid (synch_process_pid); + EMACS_KILLPG (synch_process_pid, SIGKILL); + unblock_child_signal (); + } + return Qnil; } +/* Clean up when exiting Fcall_process. + On MSDOS, delete the temporary file on any kind of termination. + On Unix, kill the process and any children on termination by signal. */ + static Lisp_Object call_process_cleanup (Lisp_Object arg) { - Lisp_Object fdpid = Fcdr (arg); - int fd; -#if defined (MSDOS) - Lisp_Object file; +#ifdef MSDOS + Lisp_Object buffer = Fcar (arg); + Lisp_Object file = Fcdr (arg); #else - pid_t pid; + Lisp_Object buffer = arg; #endif - Fset_buffer (Fcar (arg)); - CONS_TO_INTEGER (Fcar (fdpid), int, fd); - -#if defined (MSDOS) - /* for MSDOS fdpid is really (fd . tempfile) */ - file = Fcdr (fdpid); - /* FD is -1 and FILE is "" when we didn't actually create a - temporary file in call-process. */ - if (fd >= 0) - emacs_close (fd); - if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0')) - unlink (SDATA (file)); -#else /* not MSDOS */ - CONS_TO_INTEGER (Fcdr (fdpid), pid_t, pid); + Fset_buffer (buffer); - if (call_process_exited) - { - emacs_close (fd); - return Qnil; - } - - if (EMACS_KILLPG (pid, SIGINT) == 0) +#ifndef MSDOS + /* If the process still exists, kill its process group. */ + if (synch_process_pid) { ptrdiff_t count = SPECPDL_INDEX (); - record_unwind_protect (call_process_kill, fdpid); + EMACS_KILLPG (synch_process_pid, SIGINT); + record_unwind_protect (call_process_kill, make_number (0)); message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); immediate_quit = 1; QUIT; - wait_for_termination (pid); + wait_for_termination (synch_process_pid, 0, 1); + synch_process_pid = 0; immediate_quit = 0; specpdl_ptr = specpdl + count; /* Discard the unwind protect. */ message1 ("Waiting for process to die...done"); } - synch_process_alive = 0; - emacs_close (fd); -#endif /* not MSDOS */ +#endif + + if (0 <= synch_process_fd) + emacs_close (synch_process_fd); + +#ifdef MSDOS + /* FILE is "" when we didn't actually create a temporary file in + call-process. */ + if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0')) + unlink (SDATA (file)); +#endif + return Qnil; } @@ -181,9 +203,10 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) (ptrdiff_t nargs, Lisp_Object *args) { - Lisp_Object infile, buffer, current_dir, path, cleanup_info_tail; + Lisp_Object infile, buffer, current_dir, path; bool display_p; int fd0, fd1, filefd; + int status; ptrdiff_t count = SPECPDL_INDEX (); USE_SAFE_ALLOCA; @@ -199,7 +222,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) #else pid_t pid; #endif - int vfork_errno; + int child_errno; int fd_output = -1; struct coding_system process_coding; /* coding-system of process output */ struct coding_system argument_coding; /* coding-system of arguments */ @@ -493,16 +516,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) if (fd_output >= 0) fd1 = fd_output; - /* Record that we're about to create a synchronous process. */ - synch_process_alive = 1; - - /* These vars record information from process termination. - Clear them now before process can possibly terminate, - to avoid timing error if process terminates soon. */ - synch_process_death = 0; - synch_process_retcode = 0; - synch_process_termsig = 0; - if (NILP (error_file)) fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); else if (STRINGP (error_file)) @@ -535,23 +548,21 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) #ifdef MSDOS /* MW, July 1993 */ /* Note that on MSDOS `child_setup' actually returns the child process - exit status, not its PID, so we assign it to `synch_process_retcode' - below. */ + exit status, not its PID, so assign it to status below. */ pid = child_setup (filefd, outfilefd, fd_error, new_argv, 0, current_dir); - - /* Record that the synchronous process exited and note its - termination status. */ - synch_process_alive = 0; - synch_process_retcode = pid; - if (synch_process_retcode < 0) /* means it couldn't be exec'ed */ - { - synchronize_system_messages_locale (); - synch_process_death = strerror (errno); - } + child_errno = errno; emacs_close (outfilefd); if (fd_error != outfilefd) emacs_close (fd_error); + if (pid < 0) + { + synchronize_system_messages_locale (); + return + code_convert_string_norecord (build_string (strerror (child_errno)), + Vlocale_coding_system, 0); + } + status = pid; fd1 = -1; /* No harm in closing that one! */ if (tempfile) { @@ -569,12 +580,21 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) else fd0 = -1; /* We are not going to read from tempfile. */ #else /* not MSDOS */ + + /* Do the unwind-protect now, even though the pid is not known, so + that no storage allocation is done in the critical section. + The actual PID will be filled in during the critical section. */ + synch_process_pid = 0; + synch_process_fd = fd0; + record_unwind_protect (call_process_cleanup, Fcurrent_buffer ()); + + block_input (); + block_child_signal (); + #ifdef WINDOWSNT pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); #else /* not WINDOWSNT */ - block_input (); - /* vfork, and prevent local vars from being clobbered by the vfork. */ { Lisp_Object volatile buffer_volatile = buffer; @@ -593,6 +613,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) char **volatile new_argv_volatile = new_argv; pid = vfork (); + child_errno = errno; buffer = buffer_volatile; coding_systems = coding_systems_volatile; @@ -612,6 +633,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) if (pid == 0) { + unblock_child_signal (); + if (fd0 >= 0) emacs_close (fd0); @@ -623,11 +646,21 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); } - vfork_errno = errno; - unblock_input (); - #endif /* not WINDOWSNT */ + child_errno = errno; + + if (0 < pid) + { + if (INTEGERP (buffer)) + record_deleted_pid (pid); + else + synch_process_pid = pid; + } + + unblock_child_signal (); + unblock_input (); + /* The MSDOS case did this already. */ if (fd_error >= 0) emacs_close (fd_error); @@ -644,9 +677,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) if (pid < 0) { - if (fd0 >= 0) - emacs_close (fd0); - errno = vfork_errno; + errno = child_errno; report_file_error ("Doing vfork", Qnil); } @@ -657,19 +688,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) return Qnil; } - /* Enable sending signal if user quits below. */ - call_process_exited = 0; - #if defined (MSDOS) /* MSDOS needs different cleanup information. */ - cleanup_info_tail = build_string (tempfile ? tempfile : ""); -#else - cleanup_info_tail = INTEGER_TO_CONS (pid); -#endif /* not MSDOS */ record_unwind_protect (call_process_cleanup, Fcons (Fcurrent_buffer (), - Fcons (INTEGER_TO_CONS (fd0), - cleanup_info_tail))); + build_string (tempfile ? tempfile : ""))); +#endif if (BUFFERP (buffer)) Fset_buffer (buffer); @@ -856,38 +880,34 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) #ifndef MSDOS /* Wait for it to terminate, unless it already has. */ - if (output_to_buffer) - wait_for_termination (pid); - else - interruptible_wait_for_termination (pid); + wait_for_termination (pid, &status, !output_to_buffer); #endif immediate_quit = 0; /* Don't kill any children that the subprocess may have left behind when exiting. */ - call_process_exited = 1; + synch_process_pid = 0; SAFE_FREE (); unbind_to (count, Qnil); - if (synch_process_termsig) + if (WIFSIGNALED (status)) { const char *signame; synchronize_system_messages_locale (); - signame = strsignal (synch_process_termsig); + signame = strsignal (WTERMSIG (status)); if (signame == 0) signame = "unknown"; - synch_process_death = signame; + return code_convert_string_norecord (build_string (signame), + Vlocale_coding_system, 0); } - if (synch_process_death) - return code_convert_string_norecord (build_string (synch_process_death), - Vlocale_coding_system, 0); - return make_number (synch_process_retcode); + eassert (WIFEXITED (status)); + return make_number (WEXITSTATUS (status)); } static Lisp_Object diff --git a/src/process.c b/src/process.c index c6139c9f929..27009882c99 100644 --- a/src/process.c +++ b/src/process.c @@ -777,10 +777,23 @@ get_process (register Lisp_Object name) /* Fdelete_process promises to immediately forget about the process, but in reality, Emacs needs to remember those processes until they have been treated by the SIGCHLD handler and waitpid has been invoked on them; - otherwise they might fill up the kernel's process table. */ + otherwise they might fill up the kernel's process table. + + Some processes created by call-process are also put onto this list. */ static Lisp_Object deleted_pid_list; #endif +void +record_deleted_pid (pid_t pid) +{ +#ifdef SIGCHLD + deleted_pid_list = Fcons (make_fixnum_or_float (pid), + /* GC treated elements set to nil. */ + Fdelq (Qnil, deleted_pid_list)); + +#endif +} + DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0, doc: /* Delete PROCESS: kill it and forget about it immediately. PROCESS may be a process, a buffer, the name of a process or buffer, or @@ -807,9 +820,7 @@ nil, indicating the current buffer's process. */) pid_t pid = p->pid; /* No problem storing the pid here, as it is still in Vprocess_alist. */ - deleted_pid_list = Fcons (make_fixnum_or_float (pid), - /* GC treated elements set to nil. */ - Fdelq (Qnil, deleted_pid_list)); + record_deleted_pid (pid); /* If the process has already signaled, remove it from the list. */ if (p->raw_status_new) update_status (p); @@ -6147,35 +6158,37 @@ process has been transmitted to the serial port. */) return process; } -/* If the status of the process DESIRED has changed, return true and - set *STATUS to its exit status; otherwise, return false. - If HAVE is nonnegative, assume that HAVE = waitpid (HAVE, STATUS, ...) - has already been invoked, and do not invoke waitpid again. */ +#ifdef SIGCHLD -static bool -process_status_retrieved (pid_t desired, pid_t have, int *status) -{ - if (have < 0) - { - /* Invoke waitpid only with a known process ID; do not invoke - waitpid with a nonpositive argument. Otherwise, Emacs might - reap an unwanted process by mistake. For example, invoking - waitpid (-1, ...) can mess up glib by reaping glib's subprocesses, - so that another thread running glib won't find them. */ - do - have = waitpid (desired, status, WNOHANG | WUNTRACED); - while (have < 0 && errno == EINTR); - } +/* The main Emacs thread records child processes in three places: - return have == desired; -} + - Vprocess_alist, for asynchronous subprocesses, which are child + processes visible to Lisp. + + - deleted_pid_list, for child processes invisible to Lisp, + typically because of delete-process. These are recorded so that + the processes can be reaped when they exit, so that the operating + system's process table is not cluttered by zombies. -/* If PID is nonnegative, the child process PID with wait status W has - changed its status; record this and return true. + - the local variable PID in Fcall_process, call_process_cleanup and + call_process_kill, for synchronous subprocesses. + record_unwind_protect is used to make sure this process is not + forgotten: if the user interrupts call-process and the child + process refuses to exit immediately even with two C-g's, + call_process_kill adds PID's contents to deleted_pid_list before + returning. - If PID is negative, ignore W, and look for known child processes - of Emacs whose status have changed. For each one found, record its new - status. + The main Emacs thread invokes waitpid only on child processes that + it creates and that have not been reaped. This avoid races on + platforms such as GTK, where other threads create their own + subprocesses which the main thread should not reap. For example, + if the main thread attempted to reap an already-reaped child, it + might inadvertently reap a GTK-created process that happened to + have the same process ID. */ + +/* Handle a SIGCHLD signal by looking for known child processes of + Emacs whose status have changed. For each one found, record its + new status. All we do is change the status; we do not run sentinels or print notifications. That is saved for the next time keyboard input is @@ -6198,20 +6211,15 @@ process_status_retrieved (pid_t desired, pid_t have, int *status) ** Malloc WARNING: This should never call malloc either directly or indirectly; if it does, that is a bug */ -void -record_child_status_change (pid_t pid, int w) +static void +handle_child_signal (int sig) { -#ifdef SIGCHLD - - /* Record at most one child only if we already know one child that - has exited. */ - bool record_at_most_one_child = 0 <= pid; - Lisp_Object tail; /* Find the process that signaled us, and record its status. */ - /* The process can have been deleted by Fdelete_process. */ + /* The process can have been deleted by Fdelete_process, or have + been started asynchronously by Fcall_process. */ for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail)) { bool all_pids_are_fixnums @@ -6225,12 +6233,8 @@ record_child_status_change (pid_t pid, int w) deleted_pid = XINT (xpid); else deleted_pid = XFLOAT_DATA (xpid); - if (process_status_retrieved (deleted_pid, pid, &w)) - { - XSETCAR (tail, Qnil); - if (record_at_most_one_child) - return; - } + if (child_status_changed (deleted_pid, 0, 0)) + XSETCAR (tail, Qnil); } } @@ -6239,15 +6243,17 @@ record_child_status_change (pid_t pid, int w) { Lisp_Object proc = XCDR (XCAR (tail)); struct Lisp_Process *p = XPROCESS (proc); - if (p->alive && process_status_retrieved (p->pid, pid, &w)) + int status; + + if (p->alive && child_status_changed (p->pid, &status, WUNTRACED)) { /* Change the status of the process that was found. */ p->tick = ++process_tick; - p->raw_status = w; + p->raw_status = status; p->raw_status_new = 1; /* If process has terminated, stop waiting for its output. */ - if (WIFSIGNALED (w) || WIFEXITED (w)) + if (WIFSIGNALED (status) || WIFEXITED (status)) { int clear_desc_flag = 0; p->alive = 0; @@ -6261,44 +6267,8 @@ record_child_status_change (pid_t pid, int w) FD_CLR (p->infd, &non_keyboard_wait_mask); } } - - /* Tell wait_reading_process_output that it needs to wake up and - look around. */ - if (input_available_clear_time) - *input_available_clear_time = make_emacs_time (0, 0); - - if (record_at_most_one_child) - return; } } - - if (0 <= pid) - { - /* The caller successfully waited for a pid but no asynchronous - process was found for it, so this is a synchronous process. */ - - synch_process_alive = 0; - - /* Report the status of the synchronous process. */ - if (WIFEXITED (w)) - synch_process_retcode = WEXITSTATUS (w); - else if (WIFSIGNALED (w)) - synch_process_termsig = WTERMSIG (w); - - /* Tell wait_reading_process_output that it needs to wake up and - look around. */ - if (input_available_clear_time) - *input_available_clear_time = make_emacs_time (0, 0); - } -#endif -} - -#ifdef SIGCHLD - -static void -handle_child_signal (int sig) -{ - record_child_status_change (-1, 0); } static void diff --git a/src/process.h b/src/process.h index 74d1a124060..4fa22747ca9 100644 --- a/src/process.h +++ b/src/process.h @@ -185,23 +185,6 @@ pset_gnutls_cred_type (struct Lisp_Process *p, Lisp_Object val) } #endif -/* True if we are about to fork off a synchronous process or if we - are waiting for it. */ -extern bool synch_process_alive; - -/* Communicate exit status of sync process to from sigchld_handler - to Fcall_process. */ - -/* Nonzero => this is a string explaining death of synchronous subprocess. */ -extern const char *synch_process_death; - -/* Nonzero => this is the signal number that terminated the subprocess. */ -extern int synch_process_termsig; - -/* If synch_process_death is zero, - this is exit code of synchronous subprocess. */ -extern int synch_process_retcode; - /* Nonzero means don't run process sentinels. This is used when exiting. */ extern int inhibit_sentinels; diff --git a/src/sysdep.c b/src/sysdep.c index 1a3834f0379..7068a4f0977 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -266,45 +266,71 @@ init_baud_rate (int fd) #ifndef MSDOS -static void -wait_for_termination_1 (pid_t pid, int interruptible) +/* Wait for the subprocess with process id CHILD to terminate or change status. + CHILD must be a child process that has not been reaped. + If STATUS is non-null, store the waitpid-style exit status into *STATUS + and tell wait_reading_process_output that it needs to look around. + Use waitpid-style OPTIONS when waiting. + If INTERRUPTIBLE, this function is interruptible by a signal. + + Return CHILD if successful, 0 if no status is available; + the latter is possible only when options & NOHANG. */ +static pid_t +get_child_status (pid_t child, int *status, int options, bool interruptible) { - while (1) + pid_t pid; + + /* Invoke waitpid only with a known process ID; do not invoke + waitpid with a nonpositive argument. Otherwise, Emacs might + reap an unwanted process by mistake. For example, invoking + waitpid (-1, ...) can mess up glib by reaping glib's subprocesses, + so that another thread running glib won't find them. */ + eassert (0 < child); + + while ((pid = waitpid (child, status, options)) < 0) { - int status; - int wait_result = waitpid (pid, &status, 0); - if (wait_result < 0) - { - if (errno != EINTR) - break; - } - else - { - record_child_status_change (wait_result, status); - break; - } + /* CHILD must be a child process that has not been reaped, and + STATUS and OPTIONS must be valid. */ + eassert (errno == EINTR); /* Note: the MS-Windows emulation of waitpid calls QUIT internally. */ if (interruptible) QUIT; } -} -/* Wait for subprocess with process id `pid' to terminate and - make sure it will get eliminated (not remain forever as a zombie) */ + /* If successful and status is requested, tell wait_reading_process_output + that it needs to wake up and look around. */ + if (pid && status && input_available_clear_time) + *input_available_clear_time = make_emacs_time (0, 0); + return pid; +} + +/* Wait for the subprocess with process id CHILD to terminate. + CHILD must be a child process that has not been reaped. + If STATUS is non-null, store the waitpid-style exit status into *STATUS + and tell wait_reading_process_output that it needs to look around. + If INTERRUPTIBLE, this function is interruptible by a signal. */ void -wait_for_termination (pid_t pid) +wait_for_termination (pid_t child, int *status, bool interruptible) { - wait_for_termination_1 (pid, 0); + get_child_status (child, status, 0, interruptible); } -/* Like the above, but allow keyboard interruption. */ -void -interruptible_wait_for_termination (pid_t pid) +/* Report whether the subprocess with process id CHILD has changed status. + Termination counts as a change of status. + CHILD must be a child process that has not been reaped. + If STATUS is non-null, store the waitpid-style exit status into *STATUS + and tell wait_reading_process_output that it needs to look around. + Use waitpid-style OPTIONS to check status, but do not wait. + + Return CHILD if successful, 0 if no status is available because + the process's state has not changed. */ +pid_t +child_status_changed (pid_t child, int *status, int options) { - wait_for_termination_1 (pid, 1); + return get_child_status (child, status, WNOHANG | options, 0); } /* @@ -454,6 +480,7 @@ sys_subshell (void) char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */ #endif pid_t pid; + int status; struct save_signal saved_handlers[5]; Lisp_Object dir; unsigned char *volatile str_volatile = 0; @@ -491,7 +518,6 @@ sys_subshell (void) #ifdef DOS_NT pid = 0; save_signal_handlers (saved_handlers); - synch_process_alive = 1; #else pid = vfork (); if (pid == -1) @@ -560,14 +586,12 @@ sys_subshell (void) /* Do this now if we did not do it before. */ #ifndef MSDOS save_signal_handlers (saved_handlers); - synch_process_alive = 1; #endif #ifndef DOS_NT - wait_for_termination (pid); + wait_for_termination (pid, &status, 0); #endif restore_signal_handlers (saved_handlers); - synch_process_alive = 0; } static void diff --git a/src/syswait.h b/src/syswait.h index aa4c4bcf527..360407d558e 100644 --- a/src/syswait.h +++ b/src/syswait.h @@ -23,6 +23,7 @@ along with GNU Emacs. If not, see . */ #ifndef EMACS_SYSWAIT_H #define EMACS_SYSWAIT_H +#include #include #ifdef HAVE_SYS_WAIT_H /* We have sys/wait.h with POSIXoid definitions. */ @@ -52,10 +53,10 @@ along with GNU Emacs. If not, see . */ #endif /* Defined in process.c. */ -extern void record_child_status_change (pid_t, int); +extern void record_deleted_pid (pid_t); /* Defined in sysdep.c. */ -extern void wait_for_termination (pid_t); -extern void interruptible_wait_for_termination (pid_t); +extern void wait_for_termination (pid_t, int *, bool); +extern pid_t child_status_changed (pid_t, int *, int); #endif /* EMACS_SYSWAIT_H */ diff --git a/src/w32proc.c b/src/w32proc.c index 9b111b40e36..87af8682390 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -1274,33 +1274,7 @@ waitpid (pid_t pid, int *status, int options) #endif if (status) - { - *status = retval; - } - else if (synch_process_alive) - { - synch_process_alive = 0; - - /* Report the status of the synchronous process. */ - if (WIFEXITED (retval)) - synch_process_retcode = WEXITSTATUS (retval); - else if (WIFSIGNALED (retval)) - { - int code = WTERMSIG (retval); - const char *signame; - - synchronize_system_messages_locale (); - signame = strsignal (code); - - if (signame == 0) - signame = "unknown"; - - synch_process_death = signame; - } - - reap_subprocess (cp); - } - + *status = retval; reap_subprocess (cp); return pid; -- cgit v1.2.1 From 350f51adaca06e0b52800faf88ec5341c723bef7 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 4 Dec 2012 19:15:30 +0400 Subject: * lisp.h (Mouse_HLInfo): Remove set-but-unused mouse_face_image_state member. Adjust users. Convert mouse_face_past_end, mouse_face_defer and mouse_face_hidden members to a bitfields. * frame.h (struct frame): Remove set-but-not-used space_width member. (FRAME_SPACE_WIDTH): Remove. * nsterm.m, w32term.c, xterm.c: Adjust users. * termchar.h (struct tty_display_info): Remove set-but-unused se_is_so member. Adjust users. Convert term_initted, delete_in_insert_mode, costs_set, insert_mode, standout_mode, cursor_hidden and flow_control members to a bitfields. --- src/ChangeLog | 13 +++++++++++++ src/frame.h | 8 -------- src/lisp.h | 11 ++++++----- src/nsterm.m | 1 - src/term.c | 4 ---- src/termchar.h | 20 +++++++------------- src/w32term.c | 1 - src/xdisp.c | 4 ---- src/xterm.c | 1 - 9 files changed, 26 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 1a91eb0f1a3..37c8647d65f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2012-12-04 Dmitry Antipov + + * lisp.h (Mouse_HLInfo): Remove set-but-unused mouse_face_image_state + member. Adjust users. Convert mouse_face_past_end, mouse_face_defer + and mouse_face_hidden members to a bitfields. + * frame.h (struct frame): Remove set-but-not-used space_width member. + (FRAME_SPACE_WIDTH): Remove. + * nsterm.m, w32term.c, xterm.c: Adjust users. + * termchar.h (struct tty_display_info): Remove set-but-unused se_is_so + member. Adjust users. Convert term_initted, delete_in_insert_mode, + costs_set, insert_mode, standout_mode, cursor_hidden and flow_control + members to a bitfields. + 2012-12-03 Paul Eggert Don't let call-process be a zombie factory (Bug#12980). diff --git a/src/frame.h b/src/frame.h index 5ebfc2f7ec3..e8241fea88f 100644 --- a/src/frame.h +++ b/src/frame.h @@ -301,9 +301,6 @@ struct frame /* Canonical X unit. Width of default font, in pixels. */ int column_width; - /* Width of space glyph of default font, in pixels. */ - int space_width; - /* Canonical Y unit. Height of a line, in pixels. */ int line_height; @@ -1000,11 +997,6 @@ extern Lisp_Object selected_frame; #define FRAME_COLUMN_WIDTH(F) ((F)->column_width) -/* Space glyph width of the default font of frame F. */ - -#define FRAME_SPACE_WIDTH(F) ((F)->space_width) - - /* Pixel width of areas used to display truncation marks, continuation marks, overlay arrows. This is 0 for terminal frames. */ diff --git a/src/lisp.h b/src/lisp.h index 6bf54ed721b..172a32e92a9 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1644,7 +1644,6 @@ typedef struct { int mouse_face_beg_x, mouse_face_beg_y; int mouse_face_end_row, mouse_face_end_col; int mouse_face_end_x, mouse_face_end_y; - int mouse_face_past_end; Lisp_Object mouse_face_window; int mouse_face_face_id; Lisp_Object mouse_face_overlay; @@ -1654,13 +1653,15 @@ typedef struct { struct frame *mouse_face_mouse_frame; int mouse_face_mouse_x, mouse_face_mouse_y; + /* Nonzero if part of the text currently shown in + its mouse-face is beyond the window end. */ + unsigned mouse_face_past_end : 1; + /* Nonzero means defer mouse-motion highlighting. */ - int mouse_face_defer; + unsigned mouse_face_defer : 1; /* Nonzero means that the mouse highlight should not be shown. */ - int mouse_face_hidden; - - int mouse_face_image_state; + unsigned mouse_face_hidden : 1; } Mouse_HLInfo; /* Data type checking. */ diff --git a/src/nsterm.m b/src/nsterm.m index 25eb7ebc495..55a106b7e03 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -6954,7 +6954,6 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset) FRAME_BASELINE_OFFSET (f) = font->baseline_offset; FRAME_COLUMN_WIDTH (f) = font->average_width; - FRAME_SPACE_WIDTH (f) = font->space_width; FRAME_LINE_HEIGHT (f) = font->height; compute_fringe_widths (f, 1); diff --git a/src/term.c b/src/term.c index 481a3423989..241875de52f 100644 --- a/src/term.c +++ b/src/term.c @@ -3362,10 +3362,6 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ = tty->TS_delete_mode && tty->TS_insert_mode && !strcmp (tty->TS_delete_mode, tty->TS_insert_mode); - tty->se_is_so = (tty->TS_standout_mode - && tty->TS_end_standout_mode - && !strcmp (tty->TS_standout_mode, tty->TS_end_standout_mode)); - UseTabs (tty) = tabs_safe_p (fileno (tty->input)) && TabWidth (tty) == 8; terminal->scroll_region_ok diff --git a/src/termchar.h b/src/termchar.h index 5c57593c04f..8bffd3e546b 100644 --- a/src/termchar.h +++ b/src/termchar.h @@ -50,8 +50,7 @@ struct tty_display_info struct emacs_tty *old_tty; /* The initial tty mode bits */ - int term_initted; /* 1 if we have been through init_sys_modes. */ - + unsigned term_initted : 1; /* 1 if we have been through init_sys_modes. */ int reference_count; /* Number of frames that are on this display. */ @@ -164,17 +163,12 @@ struct tty_display_info int RPov; /* # chars to start a TS_repeat */ - int delete_in_insert_mode; /* delete mode == insert mode */ - - int se_is_so; /* 1 if same string both enters and leaves - standout mode */ - - int costs_set; /* Nonzero if costs have been calculated. */ - - int insert_mode; /* Nonzero when in insert mode. */ - int standout_mode; /* Nonzero when in standout mode. */ + unsigned delete_in_insert_mode : 1; /* delete mode == insert mode */ + unsigned costs_set : 1; /* Nonzero if costs have been calculated. */ + unsigned insert_mode : 1; /* Nonzero when in insert mode. */ + unsigned standout_mode : 1; /* Nonzero when in standout mode. */ /* 1 if should obey 0200 bit in input chars as "Meta", 2 if should keep 0200 bit in input chars. 0 to ignore the 0200 bit. */ @@ -192,11 +186,11 @@ struct tty_display_info /* Flag used in tty_show/hide_cursor. */ - int cursor_hidden; + unsigned cursor_hidden : 1; /* Nonzero means use ^S/^Q for flow control. */ - int flow_control; + unsigned flow_control : 1; }; /* A chain of structures for all tty devices currently in use. */ diff --git a/src/w32term.c b/src/w32term.c index 84f99c090c8..e26777543fb 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -5348,7 +5348,6 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset) FRAME_FONT (f) = font; FRAME_BASELINE_OFFSET (f) = font->baseline_offset; FRAME_COLUMN_WIDTH (f) = font->average_width; - FRAME_SPACE_WIDTH (f) = font->space_width; FRAME_LINE_HEIGHT (f) = font->height; compute_fringe_widths (f, 1); diff --git a/src/xdisp.c b/src/xdisp.c index 5f6d69dea3a..9464e87b362 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -12265,7 +12265,6 @@ handle_tool_bar_click (struct frame *f, int x, int y, int down_p, { /* Show item in pressed state. */ show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN); - hlinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN; last_tool_bar_item = prop_idx; } else @@ -12276,7 +12275,6 @@ handle_tool_bar_click (struct frame *f, int x, int y, int down_p, /* Show item in released state. */ show_mouse_face (hlinfo, DRAW_IMAGE_RAISED); - hlinfo->mouse_face_image_state = DRAW_IMAGE_RAISED; key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY); @@ -12345,7 +12343,6 @@ note_tool_bar_highlight (struct frame *f, int x, int y) && last_tool_bar_item != prop_idx) return; - hlinfo->mouse_face_image_state = DRAW_NORMAL_TEXT; draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED; /* If tool-bar item is not enabled, don't highlight it. */ @@ -12374,7 +12371,6 @@ note_tool_bar_highlight (struct frame *f, int x, int y) /* Display it as active. */ show_mouse_face (hlinfo, draw); - hlinfo->mouse_face_image_state = draw; } set_help_echo: diff --git a/src/xterm.c b/src/xterm.c index bbcff8c752f..8acd1d7843e 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -7902,7 +7902,6 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset) FRAME_FONT (f) = font; FRAME_BASELINE_OFFSET (f) = font->baseline_offset; FRAME_COLUMN_WIDTH (f) = font->average_width; - FRAME_SPACE_WIDTH (f) = font->space_width; FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (font); compute_fringe_widths (f, 1); -- cgit v1.2.1 From 2e7cddd30317b7951c5425a5769ac9f33136f72f Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 4 Dec 2012 20:48:01 +0200 Subject: Fix another instance of bug #12933 with non-ASCII file names on Windows. src/fileio.c (file_name_as_directory, directory_file_name) [DOS_NT]: Encode the file name before passing it to dostounix_filename, in case it will downcase it (under w32-downcase-file-names). --- src/ChangeLog | 7 +++++++ src/fileio.c | 22 ++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index d3d6d3969c8..6d2cd720672 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2012-12-04 Eli Zaretskii + + * fileio.c (file_name_as_directory, directory_file_name) [DOS_NT]: + Encode the file name before passing it to dostounix_filename, in + case it will downcase it (under w32-downcase-file-names). + (Bug#12933) + 2012-12-01 Chong Yidong * fileio.c (Vauto_save_list_file_name): Doc fix. diff --git a/src/fileio.c b/src/fileio.c index 490116dbc5c..77700ff5a5f 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -455,7 +455,7 @@ get a current directory to run processes in. */) /* Convert from file name SRC of length SRCLEN to directory name in DST. On UNIX, just make sure there is a terminating /. - Return the length of DST. */ + Return the length of DST in bytes. */ static ptrdiff_t file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen) @@ -477,7 +477,14 @@ file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen) srclen++; } #ifdef DOS_NT - dostounix_filename (dst); + { + Lisp_Object tem_fn = make_specified_string (dst, -1, srclen, 1); + + tem_fn = ENCODE_FILE (tem_fn); + dostounix_filename (SSDATA (tem_fn)); + tem_fn = DECODE_FILE (tem_fn); + memcpy (dst, SSDATA (tem_fn), (srclen = SBYTES (tem_fn)) + 1); + } #endif return srclen; } @@ -519,7 +526,7 @@ For a Unix-syntax file name, just appends a slash. */) /* Convert from directory name SRC of length SRCLEN to file name in DST. On UNIX, just make sure there isn't - a terminating /. Return the length of DST. */ + a terminating /. Return the length of DST in bytes. */ static ptrdiff_t directory_file_name (char *dst, char *src, ptrdiff_t srclen) @@ -538,7 +545,14 @@ directory_file_name (char *dst, char *src, ptrdiff_t srclen) srclen--; } #ifdef DOS_NT - dostounix_filename (dst); + { + Lisp_Object tem_fn = make_specified_string (dst, -1, srclen, 1); + + tem_fn = ENCODE_FILE (tem_fn); + dostounix_filename (SSDATA (tem_fn)); + tem_fn = DECODE_FILE (tem_fn); + memcpy (dst, SSDATA (tem_fn), (srclen = SBYTES (tem_fn)) + 1); + } #endif return srclen; } -- cgit v1.2.1 From 396376f1aeb072d20f1a8271ee47620b2ba9c15b Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Tue, 4 Dec 2012 22:18:37 +0100 Subject: * callproc.c (Fcall_process): Fix specpdl nesting for asynchronous processes. --- src/ChangeLog | 5 +++++ src/callproc.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 37c8647d65f..ef67df9d792 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2012-12-04 Andreas Schwab + + * callproc.c (Fcall_process): Fix specpdl nesting for asynchronous + processes. + 2012-12-04 Dmitry Antipov * lisp.h (Mouse_HLInfo): Remove set-but-unused mouse_face_image_state diff --git a/src/callproc.c b/src/callproc.c index 21c52d09e6b..2cc395428f8 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -685,7 +685,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) { if (fd0 >= 0) emacs_close (fd0); - return Qnil; + return unbind_to (count, Qnil); } #if defined (MSDOS) -- cgit v1.2.1 From d3cefd1358e021cc4d510afb18916b067e6b1419 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 5 Dec 2012 19:10:00 +0200 Subject: Fix one part of bug #13079 with temporary files in call-process-region. src/callproc.c (Fcall_process_region) [!HAVE_MKSTEMP]: If mktemp fails, signal an error instead of continuing with an empty string. --- src/ChangeLog | 6 ++++++ src/callproc.c | 8 ++++++++ 2 files changed, 14 insertions(+) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 6d2cd720672..e71667f7dcf 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2012-12-05 Eli Zaretskii + + * callproc.c (Fcall_process_region) [!HAVE_MKSTEMP]: If mktemp + fails, signal an error instead of continuing with an empty + string. (Bug#13079) + 2012-12-04 Eli Zaretskii * fileio.c (file_name_as_directory, directory_file_name) [DOS_NT]: diff --git a/src/callproc.c b/src/callproc.c index c236f22fc86..ce3b11af696 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -977,7 +977,15 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r close (fd); } #else + errno = 0; mktemp (tempfile); + if (!*tempfile) + { + if (!errno) + errno = EEXIST; + report_file_error ("Failed to open temporary file using pattern", + Fcons (pattern, Qnil)); + } #endif filename_string = build_string (tempfile); -- cgit v1.2.1 From 7c2fcf9bad2bed6c0198875384dc2bdb7cbd7e99 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 5 Dec 2012 19:39:39 +0200 Subject: Don't pass un-encoded file name to mkstemp. src/callproc.c (Fcall_process_region): Encode expanded temp file pattern before passing it to mkstemp or mktemp. --- src/ChangeLog | 2 ++ src/callproc.c | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index e71667f7dcf..106333ac8ed 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -3,6 +3,8 @@ * callproc.c (Fcall_process_region) [!HAVE_MKSTEMP]: If mktemp fails, signal an error instead of continuing with an empty string. (Bug#13079) + Encode expanded temp file pattern before passing it to mkstemp or + mktemp. 2012-12-04 Eli Zaretskii diff --git a/src/callproc.c b/src/callproc.c index ce3b11af696..d152da19f7b 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -959,8 +959,9 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r { USE_SAFE_ALLOCA; Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); - char *tempfile = SAFE_ALLOCA (SBYTES (pattern) + 1); - memcpy (tempfile, SDATA (pattern), SBYTES (pattern) + 1); + Lisp_Object encoded_tem = ENCODE_FILE (pattern); + char *tempfile = SAFE_ALLOCA (SBYTES (encoded_tem) + 1); + memcpy (tempfile, SDATA (encoded_tem), SBYTES (encoded_tem) + 1); coding_systems = Qt; #ifdef HAVE_MKSTEMP -- cgit v1.2.1 From 644d3f0dbf38eca7a746e0fb5a7a0dd20d214949 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 5 Dec 2012 10:29:52 -0800 Subject: Minor call-process cleanups. * callproc.c (Fcall_process): Do record-unwind-protect on MSDOS at the same time as other platforms, to simplify analysis. No need for fd0_volatile since we have synch_process_fd. Avoid needless emacs_close; arg is always negative. --- src/ChangeLog | 8 ++++++++ src/callproc.c | 26 +++++++++++--------------- 2 files changed, 19 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index ef67df9d792..a6ba03a0069 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2012-12-05 Paul Eggert + + Minor call-process cleanups. + * callproc.c (Fcall_process): Do record-unwind-protect on MSDOS + at the same time as other platforms, to simplify analysis. + No need for fd0_volatile since we have synch_process_fd. + Avoid needless emacs_close; arg is always negative. + 2012-12-04 Andreas Schwab * callproc.c (Fcall_process): Fix specpdl nesting for asynchronous diff --git a/src/callproc.c b/src/callproc.c index 2cc395428f8..2c3d31ba052 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -579,13 +579,20 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) } else fd0 = -1; /* We are not going to read from tempfile. */ -#else /* not MSDOS */ +#endif /* MSDOS */ /* Do the unwind-protect now, even though the pid is not known, so that no storage allocation is done in the critical section. The actual PID will be filled in during the critical section. */ synch_process_pid = 0; synch_process_fd = fd0; + +#ifdef MSDOS + /* MSDOS needs different cleanup information. */ + record_unwind_protect (call_process_cleanup, + Fcons (Fcurrent_buffer (), + build_string (tempfile ? tempfile : ""))); +#else record_unwind_protect (call_process_cleanup, Fcurrent_buffer ()); block_input (); @@ -603,7 +610,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) bool volatile display_p_volatile = display_p; bool volatile output_to_buffer_volatile = output_to_buffer; bool volatile sa_must_free_volatile = sa_must_free; - int volatile fd0_volatile = fd0; int volatile fd1_volatile = fd1; int volatile fd_error_volatile = fd_error; int volatile fd_output_volatile = fd_output; @@ -621,7 +627,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) display_p = display_p_volatile; output_to_buffer = output_to_buffer_volatile; sa_must_free = sa_must_free_volatile; - fd0 = fd0_volatile; fd1 = fd1_volatile; fd_error = fd_error_volatile; fd_output = fd_output_volatile; @@ -629,6 +634,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) count = count_volatile; sa_count = sa_count_volatile; new_argv = new_argv_volatile; + + fd0 = synch_process_fd; } if (pid == 0) @@ -682,18 +689,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) } if (INTEGERP (buffer)) - { - if (fd0 >= 0) - emacs_close (fd0); - return unbind_to (count, Qnil); - } - -#if defined (MSDOS) - /* MSDOS needs different cleanup information. */ - record_unwind_protect (call_process_cleanup, - Fcons (Fcurrent_buffer (), - build_string (tempfile ? tempfile : ""))); -#endif + return unbind_to (count, Qnil); if (BUFFERP (buffer)) Fset_buffer (buffer); -- cgit v1.2.1 From 565212e5983cdcc478ed34bcdbd63f154e5e418f Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 6 Dec 2012 10:23:51 +0400 Subject: Avoid code duplication between prev_frame and next_frame. * frame.c (candidate_frame): New function. Add comment. (prev_frame, next_frame): Use it. Adjust comment. --- src/ChangeLog | 6 +++ src/frame.c | 162 ++++++++++++++++++++++------------------------------------ 2 files changed, 68 insertions(+), 100 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 795582c802b..d9e566eae69 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2012-12-06 Dmitry Antipov + + Avoid code duplication between prev_frame and next_frame. + * frame.c (candidate_frame): New function. Add comment. + (prev_frame, next_frame): Use it. Adjust comment. + 2012-12-06 Eli Zaretskii * callproc.c (Fcall_process_region) [!HAVE_MKSTEMP]: If mktemp diff --git a/src/frame.c b/src/frame.c index 3501fc36675..d94164e0c14 100644 --- a/src/frame.c +++ b/src/frame.c @@ -895,13 +895,58 @@ DEFUN ("frame-list", Fframe_list, Sframe_list, return frames; } -/* Return the next frame in the frame list after FRAME. - If MINIBUF is nil, exclude minibuffer-only frames. - If MINIBUF is a window, include only its own frame - and any frame now using that window as the minibuffer. - If MINIBUF is `visible', include all visible frames. - If MINIBUF is 0, include all visible and iconified frames. - Otherwise, include all frames. */ +/* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the + same tty (for tty frames) or among frames which uses FRAME's keyboard. + If MINIBUF is nil, do not consider minibuffer-only candidate. + If MINIBUF is `visible', do not consider an invisible candidate. + If MINIBUF is a window, consider only its own frame and candidate now + using that window as the minibuffer. + If MINIBUF is 0, consider candidate if it is visible or iconified. + Otherwise consider any candidate and return nil if CANDIDATE is not + acceptable. */ + +static Lisp_Object +candidate_frame (Lisp_Object candidate, Lisp_Object frame, Lisp_Object minibuf) +{ + struct frame *c = XFRAME (candidate), *f = XFRAME (frame); + + if ((!FRAME_TERMCAP_P (c) && !FRAME_TERMCAP_P (f) + && FRAME_KBOARD (c) == FRAME_KBOARD (f)) + || (FRAME_TERMCAP_P (c) && FRAME_TERMCAP_P (f) + && FRAME_TTY (c) == FRAME_TTY (f))) + { + if (NILP (minibuf)) + { + if (!FRAME_MINIBUF_ONLY_P (c)) + return candidate; + } + else if (EQ (minibuf, Qvisible)) + { + FRAME_SAMPLE_VISIBILITY (c); + if (FRAME_VISIBLE_P (c)) + return candidate; + } + else if (WINDOWP (minibuf)) + { + if (EQ (FRAME_MINIBUF_WINDOW (c), minibuf) + || EQ (WINDOW_FRAME (XWINDOW (minibuf)), candidate) + || EQ (WINDOW_FRAME (XWINDOW (minibuf)), + FRAME_FOCUS_FRAME (c))) + return candidate; + } + else if (XFASTINT (minibuf) == 0) + { + FRAME_SAMPLE_VISIBILITY (c); + if (FRAME_VISIBLE_P (c) || FRAME_ICONIFIED_P (c)) + return candidate; + } + else + return candidate; + } + return Qnil; +} + +/* Return the next frame in the frame list after FRAME. */ static Lisp_Object next_frame (Lisp_Object frame, Lisp_Object minibuf) @@ -910,72 +955,24 @@ next_frame (Lisp_Object frame, Lisp_Object minibuf) int passed = 0; /* There must always be at least one frame in Vframe_list. */ - if (! CONSP (Vframe_list)) - emacs_abort (); - - /* If this frame is dead, it won't be in Vframe_list, and we'll loop - forever. Forestall that. */ - CHECK_LIVE_FRAME (frame); + eassert (CONSP (Vframe_list)); - while (1) + while (passed < 2) FOR_EACH_FRAME (tail, f) { - if (passed - && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame)) - && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame))) - || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame)) - && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame))))) + if (passed) { - /* Decide whether this frame is eligible to be returned. */ - - /* If we've looped all the way around without finding any - eligible frames, return the original frame. */ - if (EQ (f, frame)) - return f; - - /* Let minibuf decide if this frame is acceptable. */ - if (NILP (minibuf)) - { - if (! FRAME_MINIBUF_ONLY_P (XFRAME (f))) - return f; - } - else if (EQ (minibuf, Qvisible)) - { - FRAME_SAMPLE_VISIBILITY (XFRAME (f)); - if (FRAME_VISIBLE_P (XFRAME (f))) - return f; - } - else if (INTEGERP (minibuf) && XINT (minibuf) == 0) - { - FRAME_SAMPLE_VISIBILITY (XFRAME (f)); - if (FRAME_VISIBLE_P (XFRAME (f)) - || FRAME_ICONIFIED_P (XFRAME (f))) - return f; - } - else if (WINDOWP (minibuf)) - { - if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf) - || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f) - || EQ (WINDOW_FRAME (XWINDOW (minibuf)), - FRAME_FOCUS_FRAME (XFRAME (f)))) - return f; - } - else + f = candidate_frame (f, frame, minibuf); + if (!NILP (f)) return f; } - if (EQ (frame, f)) passed++; } + return frame; } -/* Return the previous frame in the frame list before FRAME. - If MINIBUF is nil, exclude minibuffer-only frames. - If MINIBUF is a window, include only its own frame - and any frame now using that window as the minibuffer. - If MINIBUF is `visible', include all visible frames. - If MINIBUF is 0, include all visible and iconified frames. - Otherwise, include all frames. */ +/* Return the previous frame in the frame list before FRAME. */ static Lisp_Object prev_frame (Lisp_Object frame, Lisp_Object minibuf) @@ -989,43 +986,9 @@ prev_frame (Lisp_Object frame, Lisp_Object minibuf) { if (EQ (frame, f) && !NILP (prev)) return prev; - - if ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame)) - && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame))) - || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame)) - && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame)))) - { - /* Decide whether this frame is eligible to be returned, - according to minibuf. */ - if (NILP (minibuf)) - { - if (! FRAME_MINIBUF_ONLY_P (XFRAME (f))) - prev = f; - } - else if (WINDOWP (minibuf)) - { - if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf) - || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f) - || EQ (WINDOW_FRAME (XWINDOW (minibuf)), - FRAME_FOCUS_FRAME (XFRAME (f)))) - prev = f; - } - else if (EQ (minibuf, Qvisible)) - { - FRAME_SAMPLE_VISIBILITY (XFRAME (f)); - if (FRAME_VISIBLE_P (XFRAME (f))) - prev = f; - } - else if (XFASTINT (minibuf) == 0) - { - FRAME_SAMPLE_VISIBILITY (XFRAME (f)); - if (FRAME_VISIBLE_P (XFRAME (f)) - || FRAME_ICONIFIED_P (XFRAME (f))) - prev = f; - } - else - prev = f; - } + f = candidate_frame (f, frame, minibuf); + if (!NILP (f)) + prev = f; } /* We've scanned the entire list. */ @@ -1056,7 +1019,6 @@ Otherwise, include all frames. */) { if (NILP (frame)) frame = selected_frame; - CHECK_LIVE_FRAME (frame); return next_frame (frame, miniframe); } -- cgit v1.2.1 From 35fb8050457a0edc6a09f38fb1dd84a9c7732352 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 5 Dec 2012 23:31:58 -0800 Subject: Fix a recently-introduced delete-process race condition. * callproc.c, process.h (record_kill_process): New function, containing part of the old call_process_kill. (call_process_kill): Use it. This does not change call_process_kill's behavior. * process.c (Fdelete_process): Use record_kill_process to fix a race condition that could cause Emacs to lose track of a child. --- src/ChangeLog | 10 ++++++++++ src/callproc.c | 30 +++++++++++++++++++++++------- src/process.c | 36 ++++++++++++++---------------------- src/process.h | 6 ++++++ 4 files changed, 53 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index d9e566eae69..542b2c0174a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,13 @@ +2012-12-06 Paul Eggert + + Fix a recently-introduced delete-process race condition. + * callproc.c, process.h (record_kill_process): + New function, containing part of the old call_process_kill. + (call_process_kill): Use it. + This does not change call_process_kill's behavior. + * process.c (Fdelete_process): Use record_kill_process to fix a + race condition that could cause Emacs to lose track of a child. + 2012-12-06 Dmitry Antipov Avoid code duplication between prev_frame and next_frame. diff --git a/src/callproc.c b/src/callproc.c index 6153bc1b6c6..e0528a791ea 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -105,6 +105,25 @@ unblock_child_signal (void) #endif } +/* 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. */ + +void +record_kill_process (struct Lisp_Process *p) +{ + block_child_signal (); + + if (p->alive) + { + p->alive = 0; + record_deleted_pid (p->pid); + EMACS_KILLPG (p->pid, SIGKILL); + } + + unblock_child_signal (); +} + /* Clean up when exiting call_process_cleanup. */ static Lisp_Object @@ -113,15 +132,12 @@ call_process_kill (Lisp_Object ignored) if (0 <= synch_process_fd) emacs_close (synch_process_fd); - /* If PID is reapable, kill it and record it as a deleted process. - Do this in a critical section. Unless PID is wedged it will be - reaped on receipt of the first SIGCHLD after the critical section. */ if (synch_process_pid) { - block_child_signal (); - record_deleted_pid (synch_process_pid); - EMACS_KILLPG (synch_process_pid, SIGKILL); - unblock_child_signal (); + struct Lisp_Process proc; + proc.alive = 1; + proc.pid = synch_process_pid; + record_kill_process (&proc); } return Qnil; diff --git a/src/process.c b/src/process.c index 27009882c99..007a07942e6 100644 --- a/src/process.c +++ b/src/process.c @@ -813,30 +813,22 @@ nil, indicating the current buffer's process. */) status_notify (p); redisplay_preserve_echo_area (13); } - else if (p->infd >= 0) + else { -#ifdef SIGCHLD - Lisp_Object symbol; - pid_t pid = p->pid; - - /* No problem storing the pid here, as it is still in Vprocess_alist. */ - record_deleted_pid (pid); - /* If the process has already signaled, remove it from the list. */ - if (p->raw_status_new) - update_status (p); - symbol = p->status; - if (CONSP (p->status)) - symbol = XCAR (p->status); - if (EQ (symbol, Qsignal) || EQ (symbol, Qexit)) - deleted_pid_list - = Fdelete (make_fixnum_or_float (pid), deleted_pid_list); - else -#endif + if (p->alive) + record_kill_process (p); + + if (p->infd >= 0) { - Fkill_process (process, Qnil); - /* Do this now, since remove_process will make the - SIGCHLD handler do nothing. */ - pset_status (p, Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil))); + /* Update P's status, since record_kill_process will make the + SIGCHLD handler update deleted_pid_list, not *P. */ + Lisp_Object symbol; + if (p->raw_status_new) + update_status (p); + symbol = CONSP (p->status) ? XCAR (p->status) : p->status; + if (! (EQ (symbol, Qsignal) || EQ (symbol, Qexit))) + pset_status (p, list2 (Qsignal, make_number (SIGKILL))); + p->tick = ++process_tick; status_notify (p); redisplay_preserve_echo_area (13); diff --git a/src/process.h b/src/process.h index 4fa22747ca9..a0521689abf 100644 --- a/src/process.h +++ b/src/process.h @@ -198,6 +198,12 @@ extern Lisp_Object QCspeed; extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven; extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary; +/* Defined in callproc.c. */ + +extern void record_kill_process (struct Lisp_Process *); + +/* Defined in process.c. */ + extern Lisp_Object list_system_processes (void); extern Lisp_Object system_process_attributes (Lisp_Object); -- cgit v1.2.1 From 1700db3c71ec3fde2e263b3325a5b5f5315a4ef9 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 6 Dec 2012 17:48:11 +0400 Subject: * frame.h (x_char_width, x_char_height): Remove prototypes. * w32term.h (x_char_width, x_char_height): Likewise. * xfns.c (x_char_width, x_char_height): Remove. * w32fns.c (x_char_width, x_char_height): Likewise. * nsfns.c (x_char_width, x_char_height): Likewise. * frame.c (Fframe_char_width): Use FRAME_COLUMN_WIDTH for all window frames. (Fframe_char_height): Likewise with FRAME_LINE_HEIGHT. * keyboard.c (command_loop_1): Remove prototype. (command_loop_2, top_level_1): Add static to match prototype. --- src/ChangeLog | 13 +++++++++++++ src/frame.c | 4 ++-- src/frame.h | 2 -- src/keyboard.c | 7 +++---- src/nsfns.m | 14 -------------- src/w32fns.c | 12 ------------ src/w32term.h | 2 -- src/xfns.c | 14 -------------- 8 files changed, 18 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 542b2c0174a..2fefef1275b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2012-12-06 Dmitry Antipov + + * frame.h (x_char_width, x_char_height): Remove prototypes. + * w32term.h (x_char_width, x_char_height): Likewise. + * xfns.c (x_char_width, x_char_height): Remove. + * w32fns.c (x_char_width, x_char_height): Likewise. + * nsfns.c (x_char_width, x_char_height): Likewise. + * frame.c (Fframe_char_width): Use FRAME_COLUMN_WIDTH for + all window frames. + (Fframe_char_height): Likewise with FRAME_LINE_HEIGHT. + * keyboard.c (command_loop_1): Remove prototype. + (command_loop_2, top_level_1): Add static to match prototype. + 2012-12-06 Paul Eggert Fix a recently-introduced delete-process race condition. diff --git a/src/frame.c b/src/frame.c index d94164e0c14..ce9ae45eb90 100644 --- a/src/frame.c +++ b/src/frame.c @@ -2276,7 +2276,7 @@ For a terminal frame, the value is always 1. */) struct frame *f = decode_any_frame (frame); if (FRAME_WINDOW_P (f)) - return make_number (x_char_height (f)); + return make_number (FRAME_LINE_HEIGHT (f)); else #endif return make_number (1); @@ -2295,7 +2295,7 @@ For a terminal screen, the value is always 1. */) struct frame *f = decode_any_frame (frame); if (FRAME_WINDOW_P (f)) - return make_number (x_char_width (f)); + return make_number (FRAME_COLUMN_WIDTH (f)); else #endif return make_number (1); diff --git a/src/frame.h b/src/frame.h index e8241fea88f..589b45fc0ff 100644 --- a/src/frame.h +++ b/src/frame.h @@ -1255,8 +1255,6 @@ extern void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y); extern void x_make_frame_visible (struct frame *f); extern void x_make_frame_invisible (struct frame *f); extern void x_iconify_frame (struct frame *f); -extern int x_char_width (struct frame *f); -extern int x_char_height (struct frame *f); extern int x_pixel_width (struct frame *f); extern int x_pixel_height (struct frame *f); extern void x_set_frame_alpha (struct frame *f); diff --git a/src/keyboard.c b/src/keyboard.c index 60e6d71cdff..1bb4c85dd7b 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1116,8 +1116,7 @@ cmd_error_internal (Lisp_Object data, const char *context) Vsignaling_function = Qnil; } - -Lisp_Object command_loop_1 (void); + static Lisp_Object command_loop_2 (Lisp_Object); static Lisp_Object top_level_1 (Lisp_Object); @@ -1154,7 +1153,7 @@ command_loop (void) value to us. A value of nil means that command_loop_1 itself returned due to end of file (or end of kbd macro). */ -Lisp_Object +static Lisp_Object command_loop_2 (Lisp_Object ignore) { register Lisp_Object val; @@ -1172,7 +1171,7 @@ top_level_2 (void) return Feval (Vtop_level, Qnil); } -Lisp_Object +static Lisp_Object top_level_1 (Lisp_Object ignore) { /* On entry to the outer level, run the startup file */ diff --git a/src/nsfns.m b/src/nsfns.m index e8bf696e7f5..428cfcb9a10 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -2242,20 +2242,6 @@ x_pixel_height (struct frame *f) } -int -x_char_width (struct frame *f) -{ - return FRAME_COLUMN_WIDTH (f); -} - - -int -x_char_height (struct frame *f) -{ - return FRAME_LINE_HEIGHT (f); -} - - int x_screen_planes (struct frame *f) { diff --git a/src/w32fns.c b/src/w32fns.c index 044c377f496..6801fc68054 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -4865,18 +4865,6 @@ x_pixel_height (register struct frame *f) return FRAME_PIXEL_HEIGHT (f); } -int -x_char_width (register struct frame *f) -{ - return FRAME_COLUMN_WIDTH (f); -} - -int -x_char_height (register struct frame *f) -{ - return FRAME_LINE_HEIGHT (f); -} - int x_screen_planes (register struct frame *f) { diff --git a/src/w32term.h b/src/w32term.h index 28d4ca6c490..af1a79e21c9 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -217,8 +217,6 @@ extern void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y); extern void x_make_frame_visible (struct frame *f); extern void x_make_frame_invisible (struct frame *f); extern void x_iconify_frame (struct frame *f); -extern int x_char_width (struct frame *f); -extern int x_char_height (struct frame *f); extern int x_pixel_width (struct frame *f); extern int x_pixel_height (struct frame *f); extern void x_set_frame_alpha (struct frame *f); diff --git a/src/xfns.c b/src/xfns.c index 1f98e9fc8c7..7e832c3a95f 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -3848,20 +3848,6 @@ x_pixel_height (register struct frame *f) return FRAME_PIXEL_HEIGHT (f); } -int -x_char_width (register struct frame *f) -{ - return FRAME_COLUMN_WIDTH (f); -} - -int -x_char_height (register struct frame *f) -{ - return FRAME_LINE_HEIGHT (f); -} - - - /************************************************************************ X Displays ************************************************************************/ -- cgit v1.2.1 From e86f51344b4bc58f8342b360eaf3d2b2ca0c470a Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 6 Dec 2012 20:36:22 +0200 Subject: Avoid busy-waiting for child processes on Windows. (Bug#13086) src/w32proc.c (waitpid): Avoid busy-waiting when called with WNOHANG if the child process is still running. Instead, exit the wait loop and return zero. --- src/ChangeLog | 6 ++++++ src/w32proc.c | 11 ++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 2fefef1275b..2a138bfcf65 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2012-12-06 Eli Zaretskii + + * w32proc.c (waitpid): Avoid busy-waiting when called with WNOHANG + if the child process is still running. Instead, exit the wait + loop and return zero. (Bug#13086) + 2012-12-06 Dmitry Antipov * frame.h (x_char_width, x_char_height): Remove prototypes. diff --git a/src/w32proc.c b/src/w32proc.c index 87af8682390..0b36804b0e8 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -1220,13 +1220,22 @@ waitpid (pid_t pid, int *status, int options) { QUIT; active = WaitForMultipleObjects (nh, wait_hnd, FALSE, timeout_ms); - } while (active == WAIT_TIMEOUT); + } while (active == WAIT_TIMEOUT && !dont_wait); if (active == WAIT_FAILED) { errno = EBADF; return -1; } + else if (active == WAIT_TIMEOUT && dont_wait) + { + /* PID specifies our subprocess, but it didn't exit yet, so its + status is not yet available. */ +#ifdef FULL_DEBUG + DebPrint (("Wait: PID %d not reap yet\n", cp->pid)); +#endif + return 0; + } else if (active >= WAIT_OBJECT_0 && active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS) { -- cgit v1.2.1 From ed08365b9e2756208b0cd2724715b47df6bf5320 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Fri, 7 Dec 2012 11:16:32 +0400 Subject: Convenient macro to check whether the buffer is hidden. * buffer.h (BUFFER_HIDDEN_P): New macro. * frame.c (make_frame): Use it. Adjust comment. * buffer.c (candidate_buffer): New function. (Fother_buffer, other_buffer_safely): Use it. --- src/ChangeLog | 8 ++++++++ src/buffer.c | 25 ++++++++++++++----------- src/buffer.h | 5 +++++ src/frame.c | 8 +++----- 4 files changed, 30 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 2a138bfcf65..5c92d94ee64 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2012-12-07 Dmitry Antipov + + Convenient macro to check whether the buffer is hidden. + * buffer.h (BUFFER_HIDDEN_P): New macro. + * frame.c (make_frame): Use it. Adjust comment. + * buffer.c (candidate_buffer): New function. + (Fother_buffer, other_buffer_safely): Use it. + 2012-12-06 Eli Zaretskii * w32proc.c (waitpid): Avoid busy-waiting when called with WNOHANG diff --git a/src/buffer.c b/src/buffer.c index 619a729a859..6e2191dc22f 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1529,6 +1529,16 @@ This does not change the name of the visited file (if any). */) return BVAR (current_buffer, name); } +/* True if B can be used as 'other-than-BUFFER' buffer. */ + +static bool +candidate_buffer (Lisp_Object b, Lisp_Object buffer) +{ + return (BUFFERP (b) && !EQ (b, buffer) + && BUFFER_LIVE_P (XBUFFER (b)) + && !BUFFER_HIDDEN_P (XBUFFER (b))); +} + DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0, doc: /* Return most recently selected buffer other than BUFFER. Buffers not visible in windows are preferred to visible buffers, unless @@ -1550,9 +1560,7 @@ exists, return the buffer `*scratch*' (creating it if necessary). */) for (; CONSP (tail); tail = XCDR (tail)) { buf = XCAR (tail); - if (BUFFERP (buf) && !EQ (buf, buffer) - && BUFFER_LIVE_P (XBUFFER (buf)) - && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ') + if (candidate_buffer (buf, buffer) /* If the frame has a buffer_predicate, disregard buffers that don't fit the predicate. */ && (NILP (pred) || !NILP (call1 (pred, buf)))) @@ -1570,9 +1578,7 @@ exists, return the buffer `*scratch*' (creating it if necessary). */) for (; CONSP (tail); tail = XCDR (tail)) { buf = Fcdr (XCAR (tail)); - if (BUFFERP (buf) && !EQ (buf, buffer) - && BUFFER_LIVE_P (XBUFFER (buf)) - && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ') + if (candidate_buffer (buf, buffer) /* If the frame has a buffer_predicate, disregard buffers that don't fit the predicate. */ && (NILP (pred) || !NILP (call1 (pred, buf)))) @@ -1608,13 +1614,10 @@ other_buffer_safely (Lisp_Object buffer) { Lisp_Object tail, buf; - tail = Vbuffer_alist; - for (; CONSP (tail); tail = XCDR (tail)) + for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) { buf = Fcdr (XCAR (tail)); - if (BUFFERP (buf) && !EQ (buf, buffer) - && BUFFER_LIVE_P (XBUFFER (buf)) - && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ')) + if (candidate_buffer (buf, buffer)) return buf; } diff --git a/src/buffer.h b/src/buffer.h index fbbbf1b8434..1129840bd47 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -982,6 +982,11 @@ bset_width_table (struct buffer *b, Lisp_Object val) #define BUFFER_LIVE_P(b) (!NILP (BVAR (b, name))) +/* Convenient check whether buffer B is hidden (i.e. its name + starts with a space). Caller must ensure that B is live. */ + +#define BUFFER_HIDDEN_P(b) (SREF (BVAR (b, name), 0) == ' ') + /* Verify indirection counters. */ #define BUFFER_CHECK_INDIRECTION(b) \ diff --git a/src/frame.c b/src/frame.c index ce9ae45eb90..87b21d0a41c 100644 --- a/src/frame.c +++ b/src/frame.c @@ -346,13 +346,11 @@ make_frame (int mini_p) /* Choose a buffer for the frame's root window. */ { - Lisp_Object buf; + Lisp_Object buf = Fcurrent_buffer (); wset_buffer (XWINDOW (root_window), Qt); - buf = Fcurrent_buffer (); - /* If buf is a 'hidden' buffer (i.e. one whose name starts with - a space), try to find another one. */ - if (SREF (Fbuffer_name (buf), 0) == ' ') + /* If current buffer is hidden, try to find another one. */ + if (BUFFER_HIDDEN_P (XBUFFER (buf))) buf = other_buffer_safely (buf); /* Use set_window_buffer, not Fset_window_buffer, and don't let -- cgit v1.2.1 From 822995f8b9776a3bcd3794eb7c362bed0f21c4a1 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Fri, 7 Dec 2012 12:13:49 +0400 Subject: * frame.c (make_frame): Do not set window's buffer to t. * window.c (Fsplit_window_internal): Likewise. Previously it was used to indicate that the window is being set up. Now we use set_window_buffer for all new windows, so the condition in ... (Fset_window_buffer): ... is always true and can be removed. --- src/ChangeLog | 8 ++++++++ src/frame.c | 14 +++++--------- src/window.c | 4 +--- 3 files changed, 14 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 5c92d94ee64..a8be140ca0e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2012-12-07 Dmitry Antipov + + * frame.c (make_frame): Do not set window's buffer to t. + * window.c (Fsplit_window_internal): Likewise. Previously it was + used to indicate that the window is being set up. Now we use + set_window_buffer for all new windows, so the condition in ... + (Fset_window_buffer): ... is always true and can be removed. + 2012-12-07 Dmitry Antipov Convenient macro to check whether the buffer is hidden. diff --git a/src/frame.c b/src/frame.c index 87b21d0a41c..5cefad6ca46 100644 --- a/src/frame.c +++ b/src/frame.c @@ -348,7 +348,6 @@ make_frame (int mini_p) { Lisp_Object buf = Fcurrent_buffer (); - wset_buffer (XWINDOW (root_window), Qt); /* If current buffer is hidden, try to find another one. */ if (BUFFER_HIDDEN_P (XBUFFER (buf))) buf = other_buffer_safely (buf); @@ -364,14 +363,11 @@ make_frame (int mini_p) } if (mini_p) - { - wset_buffer (XWINDOW (mini_window), Qt); - set_window_buffer (mini_window, - (NILP (Vminibuffer_list) - ? get_minibuffer (0) - : Fcar (Vminibuffer_list)), - 0, 0); - } + set_window_buffer (mini_window, + (NILP (Vminibuffer_list) + ? get_minibuffer (0) + : Fcar (Vminibuffer_list)), + 0, 0); fset_root_window (f, root_window); fset_selected_window (f, root_window); diff --git a/src/window.c b/src/window.c index 9f3474fcd53..d7c2e8b236e 100644 --- a/src/window.c +++ b/src/window.c @@ -3250,8 +3250,7 @@ This function runs `window-scroll-functions' before running tem = w->buffer; if (NILP (tem)) error ("Window is deleted"); - else if (!EQ (tem, Qt)) - /* w->buffer is t when the window is first being set up. */ + else { if (!EQ (tem, buffer)) { @@ -3914,7 +3913,6 @@ set correctly. See the code of `split-window' for how this is done. */) wset_next (o, new); } - wset_buffer (n, Qt); wset_window_end_valid (n, Qnil); memset (&n->last_cursor, 0, sizeof n->last_cursor); -- cgit v1.2.1 From 2cec368c81f0056f7d3f4ce9aa247ef56d3053a7 Mon Sep 17 00:00:00 2001 From: Martin Rudalics Date: Fri, 7 Dec 2012 10:45:03 +0100 Subject: Reword doc-string of Fcompare_buffer_substrings. * editfns.c (Fcompare_buffer_substrings): Reword doc-string. --- src/ChangeLog | 4 ++++ src/editfns.c | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 106333ac8ed..f9edb039b1c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2012-12-07 Martin Rudalics + + * editfns.c (Fcompare_buffer_substrings): Reword doc-string. + 2012-12-05 Eli Zaretskii * callproc.c (Fcall_process_region) [!HAVE_MKSTEMP]: If mktemp diff --git a/src/editfns.c b/src/editfns.c index 8122ffdd0d4..f0f380329cf 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2650,10 +2650,10 @@ They default to the values of (point-min) and (point-max) in BUFFER. */) DEFUN ("compare-buffer-substrings", Fcompare_buffer_substrings, Scompare_buffer_substrings, 6, 6, 0, doc: /* Compare two substrings of two buffers; return result as number. -the value is -N if first string is less after N-1 chars, -+N if first string is greater after N-1 chars, or 0 if strings match. -Each substring is represented as three arguments: BUFFER, START and END. -That makes six args in all, three for each substring. +Return -N if first string is less after N-1 chars, +N if first string is +greater after N-1 chars, or 0 if strings match. Each substring is +represented as three arguments: BUFFER, START and END. That makes six +args in all, three for each substring. The value of `case-fold-search' in the current buffer determines whether case is significant or ignored. */) -- cgit v1.2.1 From 81d8cc5377be3560177ee576d314fe4331e275c3 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 7 Dec 2012 17:28:20 +0200 Subject: Fix bug #13108 introduced by the fix to bug #12930. src/indent.c (Fvertical_motion): If a display string will be displayed on the left or the right margin, don't consider it as a factor in cursor positioning. --- src/ChangeLog | 6 ++++++ src/indent.c | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index f9edb039b1c..1cca404d2aa 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2012-12-07 Eli Zaretskii + + * indent.c (Fvertical_motion): If a display string will be + displayed on the left or the right margin, don't consider it as a + factor in cursor positioning. (Bug#13108) + 2012-12-07 Martin Rudalics * editfns.c (Fcompare_buffer_substrings): Reword doc-string. diff --git a/src/indent.c b/src/indent.c index 33322287c9d..eb105806542 100644 --- a/src/indent.c +++ b/src/indent.c @@ -2034,7 +2034,11 @@ whether or not it is currently displayed in some window. */) const char *s = SSDATA (it.string); const char *e = s + SBYTES (it.string); - disp_string_at_start_p = it.string_from_display_prop_p; + /* If it.area is anything but TEXT_AREA, we need not bother + about the display string, as it doesn't affect cursor + positioning. */ + disp_string_at_start_p = + it.string_from_display_prop_p && it.area == TEXT_AREA; while (s < e) { if (*s++ == '\n') -- cgit v1.2.1 From 9cdde1e2dfdd7b1a4e52294bca1467dc7a48c77a Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 7 Dec 2012 09:53:17 -0800 Subject: * sysdep.c (get_child_status): Abort on internal error (Bug#13086). This will cause a production Emacs to dump core instead of infinite-looping. --- src/ChangeLog | 6 ++++++ src/sysdep.c | 9 ++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index a8be140ca0e..edd6924af50 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2012-12-07 Paul Eggert + + * sysdep.c (get_child_status): Abort on internal error (Bug#13086). + This will cause a production Emacs to dump core instead of + infinite-looping. + 2012-12-07 Dmitry Antipov * frame.c (make_frame): Do not set window's buffer to t. diff --git a/src/sysdep.c b/src/sysdep.c index 7068a4f0977..9c904850401 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -289,9 +289,12 @@ get_child_status (pid_t child, int *status, int options, bool interruptible) while ((pid = waitpid (child, status, options)) < 0) { - /* CHILD must be a child process that has not been reaped, and - STATUS and OPTIONS must be valid. */ - eassert (errno == EINTR); + /* Check that CHILD is a child process that has not been reaped, + and that STATUS and OPTIONS are valid. Otherwise abort, + as continuing after this internal error could cause Emacs to + become confused and kill innocent-victim processes. */ + if (errno != EINTR) + emacs_abort (); /* Note: the MS-Windows emulation of waitpid calls QUIT internally. */ -- cgit v1.2.1 From d983a10b9a070fd8f6d4f48ec44e5514b62feaa6 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 7 Dec 2012 18:30:51 -0800 Subject: Assume POSIX 1003.1-1988 or later for signal.h. Exceptions: do not assume SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGUSR1, SIGUSR2, as Microsoft platforms lack these. * admin/CPP-DEFINES (SIGALRM, SIGCHLD, SIGHUP, SIGKILL, SIGPIPE, SIGQUIT): Remove. (SIGTRAP): Remove this one too, as config.h no longer defines it. * admin/merge-gnulib (GNULIB_MODULES): Add sig2str. * configure.ac (PTY_OPEN, PTY_TTY_NAME_SPRINTF): Use SIGCHLD rather than SIGCLD. * lib/sig2str.c, lib/sig2str.h, m4/sig2str.m4: New files, from gnulib. * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * lib/makefile.w32-in (GNULIBOBJS): Add $(BUILD)/sig2str.$(O). * src/process.c [subprocesses]: Include , . (deleted_pid_list, Fdelete_process, create_process) (record_child_status_change, handle_child_signal, deliver_child_signal) (init_process_emacs, syms_of_process): Assume SIGCHLD is defined. (parse_signal): Remove. All uses removed. (abbr_to_signal): New static function. (Fsignal_process): Use it to convert signal names to ints. * src/sysdep.c (sys_suspend) [!DOS_NT]: Use kill (0, ...) rather than kill (getpgrp (), ...). (emacs_sigaction_init): Assume SIGCHLD is defined. (init_signals): Assume SIGALRM, SIGCHLD, SIGHUP, SIGKILL, SIGPIPE, and SIGQUIT are defined. Do not worry about SIGCLD any more. * src/syssignal.h (EMACS_KILLPG): Remove. All uses replaced by 'kill' with a negative pid. (SIGCHLD): Remove definition, as we now assume SIGCHLD. * src/w32proc.c (sys_kill): Support negative pids compatibly with POSIX. Fixes: debbugs:13026 --- src/ChangeLog | 23 +++++++++ src/callproc.c | 8 +-- src/keyboard.c | 2 +- src/process.c | 156 +++++++++++++------------------------------------------- src/sysdep.c | 30 ++--------- src/syssignal.h | 20 -------- src/w32proc.c | 4 ++ 7 files changed, 70 insertions(+), 173 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index edd6924af50..2b283a609e3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,26 @@ +2012-12-08 Paul Eggert + + Assume POSIX 1003.1-1988 or later for signal.h (Bug#13026). + Exceptions: do not assume SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, + SIGTTOU, SIGUSR1, SIGUSR2, as Microsoft platforms lack these. + * process.c [subprocesses]: Include , . + (deleted_pid_list, Fdelete_process, create_process) + (record_child_status_change, handle_child_signal, deliver_child_signal) + (init_process_emacs, syms_of_process): + Assume SIGCHLD is defined. + (parse_signal): Remove. All uses removed. + (abbr_to_signal): New static function. + (Fsignal_process): Use it to convert signal names to ints. + * sysdep.c (sys_suspend) [!DOS_NT]: Use kill (0, ...) rather than + kill (getpgrp (), ...). + (emacs_sigaction_init): Assume SIGCHLD is defined. + (init_signals): Assume SIGALRM, SIGCHLD, SIGHUP, SIGKILL, + SIGPIPE, and SIGQUIT are defined. Do not worry about SIGCLD any more. + * syssignal.h (EMACS_KILLPG): Remove. + All uses replaced by 'kill' with a negative pid. + (SIGCHLD): Remove definition, as we now assume SIGCHLD. + * w32proc.c (sys_kill): Support negative pids compatibly with POSIX. + 2012-12-07 Paul Eggert * sysdep.c (get_child_status): Abort on internal error (Bug#13086). diff --git a/src/callproc.c b/src/callproc.c index e0528a791ea..70e349d0d3a 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -87,12 +87,10 @@ static int synch_process_fd; static void block_child_signal (void) { -#ifdef SIGCHLD sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); -#endif } /* Unblock SIGCHLD. */ @@ -100,9 +98,7 @@ block_child_signal (void) static void unblock_child_signal (void) { -#ifdef SIGCHLD pthread_sigmask (SIG_SETMASK, &empty_mask, 0); -#endif } /* If P is reapable, record it as a deleted process and kill it. @@ -118,7 +114,7 @@ record_kill_process (struct Lisp_Process *p) { p->alive = 0; record_deleted_pid (p->pid); - EMACS_KILLPG (p->pid, SIGKILL); + kill (- p->pid, SIGKILL); } unblock_child_signal (); @@ -164,7 +160,7 @@ call_process_cleanup (Lisp_Object arg) if (synch_process_pid) { ptrdiff_t count = SPECPDL_INDEX (); - EMACS_KILLPG (synch_process_pid, SIGINT); + kill (-synch_process_pid, SIGINT); record_unwind_protect (call_process_kill, make_number (0)); message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); immediate_quit = 1; diff --git a/src/keyboard.c b/src/keyboard.c index 1bb4c85dd7b..fc155c5a5f7 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -10688,7 +10688,7 @@ handle_interrupt (bool in_signal_handler) fflush (stdout); reset_all_sys_modes (); -#ifdef SIGTSTP /* Support possible in later USG versions */ +#ifdef SIGTSTP /* * On systems which can suspend the current process and return to the original * shell, this command causes the user to end up back at the shell. diff --git a/src/process.c b/src/process.c index 007a07942e6..7b21d060cf8 100644 --- a/src/process.c +++ b/src/process.c @@ -91,6 +91,9 @@ along with GNU Emacs. If not, see . */ #include #endif +#include +#include + #endif /* subprocesses */ #include "systime.h" @@ -773,7 +776,6 @@ get_process (register Lisp_Object name) } -#ifdef SIGCHLD /* Fdelete_process promises to immediately forget about the process, but in reality, Emacs needs to remember those processes until they have been treated by the SIGCHLD handler and waitpid has been invoked on them; @@ -781,17 +783,14 @@ get_process (register Lisp_Object name) Some processes created by call-process are also put onto this list. */ static Lisp_Object deleted_pid_list; -#endif void record_deleted_pid (pid_t pid) { -#ifdef SIGCHLD deleted_pid_list = Fcons (make_fixnum_or_float (pid), /* GC treated elements set to nil. */ Fdelq (Qnil, deleted_pid_list)); -#endif } DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0, @@ -1581,9 +1580,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) #ifndef WINDOWSNT int wait_child_setup[2]; #endif -#ifdef SIGCHLD sigset_t blocked; -#endif /* Use volatile to protect variables from being clobbered by vfork. */ volatile int forkin, forkout; volatile int pty_flag = 0; @@ -1680,13 +1677,11 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) block_input (); -#ifdef SIGCHLD /* Block SIGCHLD until we have a chance to store the new fork's pid in its process structure. */ sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); -#endif #ifndef WINDOWSNT pid = vfork (); @@ -1794,10 +1789,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) /* Emacs ignores SIGPIPE, but the child should not. */ signal (SIGPIPE, SIG_DFL); -#ifdef SIGCHLD /* Stop blocking signals in the child. */ pthread_sigmask (SIG_SETMASK, &empty_mask, 0); -#endif if (pty_flag) child_setup_tty (xforkout); @@ -1818,9 +1811,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) XPROCESS (process)->alive = 1; /* Stop blocking signals in the parent. */ -#ifdef SIGCHLD pthread_sigmask (SIG_SETMASK, &empty_mask, 0); -#endif unblock_input (); if (pid < 0) @@ -4612,7 +4603,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, yielding EBADF here or at select() call above. So, SIGHUP is ignored (see def of PTY_TTY_NAME_SPRINTF in m/ibmrt-aix.h), and here we just ignore the select error. - Cleanup occurs c/o status_notify after SIGCLD. */ + Cleanup occurs c/o status_notify after SIGCHLD. */ no_avail = 1; /* Cannot depend on values returned */ #else emacs_abort (); @@ -4810,10 +4801,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, #endif /* HAVE_PTYS */ /* If we can detect process termination, don't consider the process gone just because its pipe is closed. */ -#ifdef SIGCHLD else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc)) ; -#endif else { /* Preserve status of processes already terminated. */ @@ -5676,7 +5665,7 @@ return t unconditionally. */) If we can, we try to signal PROCESS by sending control characters down the pty. This allows us to signal inferiors who have changed - their uid, for which killpg would return an EPERM error. */ + their uid, for which kill would return an EPERM error. */ static void process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, @@ -5814,7 +5803,7 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, if (!NILP (current_group)) { if (ioctl (p->infd, TIOCSIGSEND, signo) == -1) - EMACS_KILLPG (gid, signo); + kill (-gid, signo); } else { @@ -5822,7 +5811,7 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, kill (gid, signo); } #else /* ! defined (TIOCSIGSEND) */ - EMACS_KILLPG (gid, signo); + kill (-gid, signo); #endif /* ! defined (TIOCSIGSEND) */ } @@ -5927,6 +5916,27 @@ traffic. */) return process; } +/* Return the integer value of the signal whose abbreviation is ABBR, + or a negative number if there is no such signal. */ +static int +abbr_to_signal (char const *name) +{ + int i, signo; + char sigbuf[20]; /* Large enough for all valid signal abbreviations. */ + + if (!strncmp (name, "SIG", 3) || !strncmp (name, "sig", 3)) + name += 3; + + for (i = 0; i < sizeof sigbuf; i++) + { + sigbuf[i] = c_toupper (name[i]); + if (! sigbuf[i]) + return str2sig (sigbuf, &signo) == 0 ? signo : -1; + } + + return -1; +} + DEFUN ("signal-process", Fsignal_process, Ssignal_process, 2, 2, "sProcess (name or number): \nnSignal code: ", doc: /* Send PROCESS the signal with code SIGCODE. @@ -5937,6 +5947,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */) (Lisp_Object process, Lisp_Object sigcode) { pid_t pid; + int signo; if (STRINGP (process)) { @@ -5966,12 +5977,11 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */) error ("Cannot signal process %s", SDATA (XPROCESS (process)->name)); } -#define parse_signal(NAME, VALUE) \ - else if (!xstrcasecmp (name, NAME)) \ - XSETINT (sigcode, VALUE) - if (INTEGERP (sigcode)) - CHECK_TYPE_RANGED_INTEGER (int, sigcode); + { + CHECK_TYPE_RANGED_INTEGER (int, sigcode); + signo = XINT (sigcode); + } else { char *name; @@ -5979,96 +5989,12 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */) CHECK_SYMBOL (sigcode); name = SSDATA (SYMBOL_NAME (sigcode)); - if (!strncmp (name, "SIG", 3) || !strncmp (name, "sig", 3)) - name += 3; - - if (0) - ; -#ifdef SIGUSR1 - parse_signal ("usr1", SIGUSR1); -#endif -#ifdef SIGUSR2 - parse_signal ("usr2", SIGUSR2); -#endif - parse_signal ("term", SIGTERM); -#ifdef SIGHUP - parse_signal ("hup", SIGHUP); -#endif - parse_signal ("int", SIGINT); -#ifdef SIGQUIT - parse_signal ("quit", SIGQUIT); -#endif - parse_signal ("ill", SIGILL); - parse_signal ("abrt", SIGABRT); -#ifdef SIGEMT - parse_signal ("emt", SIGEMT); -#endif -#ifdef SIGKILL - parse_signal ("kill", SIGKILL); -#endif - parse_signal ("fpe", SIGFPE); -#ifdef SIGBUS - parse_signal ("bus", SIGBUS); -#endif - parse_signal ("segv", SIGSEGV); -#ifdef SIGSYS - parse_signal ("sys", SIGSYS); -#endif -#ifdef SIGPIPE - parse_signal ("pipe", SIGPIPE); -#endif -#ifdef SIGALRM - parse_signal ("alrm", SIGALRM); -#endif -#ifdef SIGURG - parse_signal ("urg", SIGURG); -#endif -#ifdef SIGSTOP - parse_signal ("stop", SIGSTOP); -#endif -#ifdef SIGTSTP - parse_signal ("tstp", SIGTSTP); -#endif -#ifdef SIGCONT - parse_signal ("cont", SIGCONT); -#endif -#ifdef SIGCHLD - parse_signal ("chld", SIGCHLD); -#endif -#ifdef SIGTTIN - parse_signal ("ttin", SIGTTIN); -#endif -#ifdef SIGTTOU - parse_signal ("ttou", SIGTTOU); -#endif -#ifdef SIGIO - parse_signal ("io", SIGIO); -#endif -#ifdef SIGXCPU - parse_signal ("xcpu", SIGXCPU); -#endif -#ifdef SIGXFSZ - parse_signal ("xfsz", SIGXFSZ); -#endif -#ifdef SIGVTALRM - parse_signal ("vtalrm", SIGVTALRM); -#endif -#ifdef SIGPROF - parse_signal ("prof", SIGPROF); -#endif -#ifdef SIGWINCH - parse_signal ("winch", SIGWINCH); -#endif -#ifdef SIGINFO - parse_signal ("info", SIGINFO); -#endif - else + signo = abbr_to_signal (name); + if (signo < 0) error ("Undefined signal name %s", name); } -#undef parse_signal - - return make_number (kill (pid, XINT (sigcode))); + return make_number (kill (pid, signo)); } DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0, @@ -6150,8 +6076,6 @@ process has been transmitted to the serial port. */) return process; } -#ifdef SIGCHLD - /* The main Emacs thread records child processes in three places: - Vprocess_alist, for asynchronous subprocesses, which are child @@ -6268,8 +6192,6 @@ deliver_child_signal (int sig) { deliver_process_signal (sig, handle_child_signal); } - -#endif /* SIGCHLD */ static Lisp_Object @@ -7118,7 +7040,6 @@ init_process_emacs (void) inhibit_sentinels = 0; -#ifdef SIGCHLD #ifndef CANNOT_DUMP if (! noninteractive || initialized) #endif @@ -7127,7 +7048,6 @@ init_process_emacs (void) emacs_sigaction_init (&action, deliver_child_signal); sigaction (SIGCHLD, &action, 0); } -#endif FD_ZERO (&input_wait_mask); FD_ZERO (&non_keyboard_wait_mask); @@ -7154,9 +7074,7 @@ init_process_emacs (void) #endif Vprocess_alist = Qnil; -#ifdef SIGCHLD deleted_pid_list = Qnil; -#endif for (i = 0; i < MAXDESC; i++) { chan_process[i] = Qnil; @@ -7283,9 +7201,7 @@ syms_of_process (void) DEFSYM (Qlast_nonmenu_event, "last-nonmenu-event"); staticpro (&Vprocess_alist); -#ifdef SIGCHLD staticpro (&deleted_pid_list); -#endif #endif /* subprocesses */ diff --git a/src/sysdep.c b/src/sysdep.c index 9c904850401..5291c5d59aa 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -457,20 +457,15 @@ static void restore_signal_handlers (struct save_signal *); void sys_suspend (void) { -#if defined (SIGTSTP) && !defined (MSDOS) - - { - pid_t pgrp = getpgrp (); - EMACS_KILLPG (pgrp, SIGTSTP); - } - -#else /* No SIGTSTP */ +#ifndef DOS_NT + kill (0, SIGTSTP); +#else /* On a system where suspending is not implemented, instead fork a subshell and let it talk directly to the terminal while we wait. */ sys_subshell (); -#endif /* no SIGTSTP */ +#endif } /* Fork a subshell. */ @@ -1518,9 +1513,7 @@ emacs_sigaction_init (struct sigaction *action, signal_handler_t handler) /* When handling a signal, block nonfatal system signals that are caught by Emacs. This makes race conditions less likely. */ sigaddset (&action->sa_mask, SIGALRM); -#ifdef SIGCHLD sigaddset (&action->sa_mask, SIGCHLD); -#endif #ifdef SIGDANGER sigaddset (&action->sa_mask, SIGDANGER); #endif @@ -1700,18 +1693,11 @@ init_signals (bool dumping) # ifdef SIGAIO sys_siglist[SIGAIO] = "LAN I/O interrupt"; # endif -# ifdef SIGALRM sys_siglist[SIGALRM] = "Alarm clock"; -# endif # ifdef SIGBUS sys_siglist[SIGBUS] = "Bus error"; # endif -# ifdef SIGCLD - sys_siglist[SIGCLD] = "Child status changed"; -# endif -# ifdef SIGCHLD sys_siglist[SIGCHLD] = "Child status changed"; -# endif # ifdef SIGCONT sys_siglist[SIGCONT] = "Continued"; # endif @@ -1731,9 +1717,7 @@ init_signals (bool dumping) # ifdef SIGGRANT sys_siglist[SIGGRANT] = "Monitor mode granted"; # endif -# ifdef SIGHUP sys_siglist[SIGHUP] = "Hangup"; -# endif sys_siglist[SIGILL] = "Illegal instruction"; sys_siglist[SIGINT] = "Interrupt"; # ifdef SIGIO @@ -1745,9 +1729,7 @@ init_signals (bool dumping) # ifdef SIGIOT sys_siglist[SIGIOT] = "IOT trap"; # endif -# ifdef SIGKILL sys_siglist[SIGKILL] = "Killed"; -# endif # ifdef SIGLOST sys_siglist[SIGLOST] = "Resource lost"; # endif @@ -1760,9 +1742,7 @@ init_signals (bool dumping) # ifdef SIGPHONE sys_siglist[SIGWIND] = "SIGPHONE"; # endif -# ifdef SIGPIPE sys_siglist[SIGPIPE] = "Broken pipe"; -# endif # ifdef SIGPOLL sys_siglist[SIGPOLL] = "Pollable event occurred"; # endif @@ -1775,9 +1755,7 @@ init_signals (bool dumping) # ifdef SIGPWR sys_siglist[SIGPWR] = "Power-fail restart"; # endif -# ifdef SIGQUIT sys_siglist[SIGQUIT] = "Quit"; -# endif # ifdef SIGRETRACT sys_siglist[SIGRETRACT] = "Need to relinquish monitor mode"; # endif diff --git a/src/syssignal.h b/src/syssignal.h index 2bf2f046aa5..8f9b5f0546a 100644 --- a/src/syssignal.h +++ b/src/syssignal.h @@ -54,26 +54,6 @@ char const *safe_strsignal (int) ATTRIBUTE_CONST; # define emacs_raise(sig) raise (sig) #endif -/* On bsd, [man says] kill does not accept a negative number to kill a pgrp. - Must do that using the killpg call. */ -#ifdef BSD_SYSTEM -#define EMACS_KILLPG(gid, signo) (killpg ( (gid), (signo))) -#else -#ifdef WINDOWSNT -#define EMACS_KILLPG(gid, signo) (kill (gid, signo)) -#else -#define EMACS_KILLPG(gid, signo) (kill (-(gid), (signo))) -#endif -#endif - -/* Define SIGCHLD as an alias for SIGCLD. There are many conditionals - testing SIGCHLD. */ -#ifdef SIGCLD -#ifndef SIGCHLD -#define SIGCHLD SIGCLD -#endif /* SIGCHLD */ -#endif /* ! defined (SIGCLD) */ - #ifndef HAVE_STRSIGNAL # define strsignal(sig) safe_strsignal (sig) #endif diff --git a/src/w32proc.c b/src/w32proc.c index 0b36804b0e8..d888200c556 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -2122,6 +2122,10 @@ sys_kill (int pid, int sig) int need_to_free = 0; int rc = 0; + /* Each process is in its own process group. */ + if (pid < 0) + pid = -pid; + /* Only handle signals that will result in the process dying */ if (sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP) { -- cgit v1.2.1 From 76b92feef1ce7919484065b0ee66e8bb891aff51 Mon Sep 17 00:00:00 2001 From: Christopher Schmidt Date: Sat, 8 Dec 2012 11:16:45 +0800 Subject: * lread.c (Vload_source_file_function): Doc fix. Fixes: debbugs:11647 --- src/ChangeLog | 4 ++++ src/lread.c | 16 ++++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 1cca404d2aa..427f729730f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2012-12-08 Christopher Schmidt + + * lread.c (Vload_source_file_function): Doc fix (Bug#11647). + 2012-12-07 Eli Zaretskii * indent.c (Fvertical_motion): If a display string will be diff --git a/src/lread.c b/src/lread.c index 94744620279..be7b44e603b 100644 --- a/src/lread.c +++ b/src/lread.c @@ -4518,12 +4518,16 @@ The default is nil, which means use the function `read'. */); Vload_read_function = Qnil; DEFVAR_LISP ("load-source-file-function", Vload_source_file_function, - doc: /* Function called in `load' for loading an Emacs Lisp source file. -This function is for doing code conversion before reading the source file. -If nil, loading is done without any code conversion. -Arguments are FULLNAME, FILE, NOERROR, NOMESSAGE, where - FULLNAME is the full name of FILE. -See `load' for the meaning of the remaining arguments. */); + doc: /* Function called in `load' to load an Emacs Lisp source file. +The value should be a function for doing code conversion before +reading a source file. It can also be nil, in which case loading is +done without any code conversion. + +If the value is a function, it is called with four arguments, +FULLNAME, FILE, NOERROR, NOMESSAGE. FULLNAME is the absolute name of +the file to load, FILE is the non-absolute name (for messages etc.), +and NOERROR and NOMESSAGE are the corresponding arguments passed to +`load'. The function should return t if the file was loaded. */); Vload_source_file_function = Qnil; DEFVAR_BOOL ("load-force-doc-strings", load_force_doc_strings, -- cgit v1.2.1 From 7be78020e3baaa73d047af75675ea6c92c1c1fda Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 7 Dec 2012 22:56:26 -0800 Subject: Simplify get_lim_data. * admin/CPP-DEFINES (ULIMIT_BREAK_VALUE): Remove. * configure.ac (ULIMIT_BREAK_VALUE): Remove. * src/vm-limit.c (get_lim_data): Combine RLIMIT_AS and RLIMIT_DATA methods. Remove USG and vlimit methods; no longer used these days. Add #error catchall just in case. --- src/ChangeLog | 5 ++++ src/vm-limit.c | 75 ++++++++++++---------------------------------------------- 2 files changed, 20 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 2b283a609e3..218dd425a2d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,10 @@ 2012-12-08 Paul Eggert + Simplify get_lim_data. + * vm-limit.c (get_lim_data): Combine RLIMIT_AS and RLIMIT_DATA methods. + Remove USG and vlimit methods; no longer used these days. + Add #error catchall just in case. + Assume POSIX 1003.1-1988 or later for signal.h (Bug#13026). Exceptions: do not assume SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGUSR1, SIGUSR2, as Microsoft platforms lack these. diff --git a/src/vm-limit.c b/src/vm-limit.c index 2a71e88695a..befc01d400f 100644 --- a/src/vm-limit.c +++ b/src/vm-limit.c @@ -44,46 +44,26 @@ static POINTER data_space_start; static size_t lim_data; -#if defined (HAVE_GETRLIMIT) && defined (RLIMIT_AS) -static void -get_lim_data (void) -{ - struct rlimit rlimit; - - getrlimit (RLIMIT_AS, &rlimit); - if (rlimit.rlim_cur == RLIM_INFINITY) - lim_data = -1; - else - lim_data = rlimit.rlim_cur; -} +#ifdef HAVE_GETRLIMIT -#else /* not HAVE_GETRLIMIT */ - -#ifdef USG +# ifndef RLIMIT_AS +# define RLIMIT_AS RLIMIT_DATA +# endif static void get_lim_data (void) { - extern long ulimit (); - - lim_data = -1; - - /* Use the ulimit call, if we seem to have it. */ -#if !defined (ULIMIT_BREAK_VALUE) || defined (GNU_LINUX) - lim_data = ulimit (3, 0); -#endif - - /* If that didn't work, just use the macro's value. */ -#ifdef ULIMIT_BREAK_VALUE - if (lim_data == -1) - lim_data = ULIMIT_BREAK_VALUE; -#endif - - lim_data -= (long) data_space_start; + /* Set LIM_DATA to the minimum of the maximum object size and the + maximum address space. Don't bother to check for values like + RLIM_INFINITY since in practice they are not much less than SIZE_MAX. */ + struct rlimit rlimit; + lim_data + = (getrlimit (RLIMIT_AS, &rlimit) == 0 && rlimit.rlim_cur <= SIZE_MAX + ? rlimit.rlim_cur + : SIZE_MAX); } -#else /* not USG */ -#ifdef WINDOWSNT +#elif defined WINDOWSNT #include "w32heap.h" @@ -94,10 +74,8 @@ get_lim_data (void) lim_data = reserved_heap_size; } -#else -#if !defined (BSD4_2) && !defined (CYGWIN) +#elif defined MSDOS -#ifdef MSDOS void get_lim_data (void) { @@ -135,32 +113,9 @@ ret_lim_data (void) get_lim_data (); return lim_data; } -#else /* not MSDOS */ -static void -get_lim_data (void) -{ - lim_data = vlimit (LIM_DATA, -1); -} -#endif /* not MSDOS */ - -#else /* BSD4_2 || CYGWIN */ - -static void -get_lim_data (void) -{ - struct rlimit XXrlimit; - - getrlimit (RLIMIT_DATA, &XXrlimit); -#ifdef RLIM_INFINITY - lim_data = XXrlimit.rlim_cur & RLIM_INFINITY; /* soft limit */ #else - lim_data = XXrlimit.rlim_cur; /* soft limit */ +# error "get_lim_data not implemented on this machine" #endif -} -#endif /* BSD4_2 */ -#endif /* not WINDOWSNT */ -#endif /* not USG */ -#endif /* not HAVE_GETRLIMIT */ /* Verify amount of memory available, complaining if we're near the end. */ -- cgit v1.2.1 From 1b6dbfeb19ef1b17341e24b1bdba3b86d2defe61 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Sat, 8 Dec 2012 19:05:39 +0800 Subject: * src/editfns.c (Finsert_char): Make the error message more informative. Fixes: debbugs:12992 --- src/ChangeLog | 5 +++++ src/editfns.c | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 218dd425a2d..8e1e422d154 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2012-12-08 Chong Yidong + + * editfns.c (Finsert_char): Make the error message more + informative (Bug#12992). + 2012-12-08 Paul Eggert Simplify get_lim_data. diff --git a/src/editfns.c b/src/editfns.c index d60f417e561..ffb9a38909b 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2351,9 +2351,10 @@ usage: (insert-before-markers-and-inherit &rest ARGS) */) } DEFUN ("insert-char", Finsert_char, Sinsert_char, 1, 3, - "(list (read-char-by-name \"Insert character (Unicode name or hex): \")\ - (prefix-numeric-value current-prefix-arg)\ - t))", + "(list (or (read-char-by-name \"Insert character (Unicode name or hex): \")\ + (error \"You did not specify a valid character\"))\ + (prefix-numeric-value current-prefix-arg)\ + t))", doc: /* Insert COUNT copies of CHARACTER. Interactively, prompt for CHARACTER. You can specify CHARACTER in one of these ways: -- cgit v1.2.1 From 75ceee05671c1698e27e5188487e7e74c490f201 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 8 Dec 2012 13:32:10 +0200 Subject: Provide unsetenv for MS-Windows and make putenv Posix-compatible. src/w32.c (unsetenv, sys_putenv): New functions. nt/inc/ms-w32.h (putenv): Redirect to sys_putenv. nt/config.nt (HAVE_UNSETENV): Define to 1. Fixes: debbugs:13070 --- src/ChangeLog | 4 ++++ src/w32.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 8e1e422d154..3e8b8519ba3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2012-12-08 Eli Zaretskii + + * w32.c (unsetenv, sys_putenv): New functions. + 2012-12-08 Chong Yidong * editfns.c (Finsert_char): Make the error message more diff --git a/src/w32.c b/src/w32.c index e81fc7b4f3e..203c5cd40ff 100644 --- a/src/w32.c +++ b/src/w32.c @@ -1544,6 +1544,50 @@ is_unc_volume (const char *filename) return 1; } +/* Emulate the Posix unsetenv. */ +int +unsetenv (const char *name) +{ + char *var; + size_t name_len; + int retval; + + if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) + { + errno = EINVAL; + return -1; + } + name_len = strlen (name); + /* MS docs says an environment variable cannot be longer than 32K. */ + if (name_len > 32767) + { + errno = ENOMEM; + return -1; + } + /* It is safe to use 'alloca' with 32K size, since the stack is at + least 2MB, and we set it to 8MB in the link command line. */ + var = alloca (name_len + 2); + var[name_len++] = '='; + var[name_len] = '\0'; + return _putenv (var); +} + +/* MS _putenv doesn't support removing a variable when the argument + does not include the '=' character, so we fix that here. */ +int +sys_putenv (char *str) +{ + const char *const name_end = strchr (str, '='); + + if (name_end == NULL) + { + /* Remove the variable from the environment. */ + return unsetenv (str); + } + + return _putenv (str); +} + #define REG_ROOT "SOFTWARE\\GNU\\Emacs" LPBYTE -- cgit v1.2.1 From cb576b5cd0d5899b73ce92c2d7d58535c60bb1d2 Mon Sep 17 00:00:00 2001 From: Fabrice Popineau Date: Sat, 8 Dec 2012 14:06:46 +0200 Subject: Fix incompatibilities with 64-bit Windows builds. src/w32fns.c (cache_system_info): Cast sysinfo_cache.dwPageSize to DWORD_PTR, for compatibility with 64-bit builds. src/w32.c (_PROCESS_MEMORY_COUNTERS_EX): (GetProcessWorkingSetSize_Proc, get_process_working_set_size) (system_process_attributes): Use SIZE_T rather than DWORD, for compatibility with 64-bit builds. --- src/ChangeLog | 10 ++++++++++ src/w32.c | 36 ++++++++++++++++++------------------ src/w32fns.c | 2 +- 3 files changed, 29 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 427f729730f..f3af852f9e9 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,13 @@ +2012-12-08 Fabrice Popineau + + * w32fns.c (cache_system_info): Cast sysinfo_cache.dwPageSize to + DWORD_PTR, for compatibility with 64-bit builds. + + * w32.c (_PROCESS_MEMORY_COUNTERS_EX): + (GetProcessWorkingSetSize_Proc, get_process_working_set_size) + (system_process_attributes): Use SIZE_T rather than DWORD, for + compatibility with 64-bit builds. + 2012-12-08 Christopher Schmidt * lread.c (Vload_source_file_function): Doc fix (Bug#11647). diff --git a/src/w32.c b/src/w32.c index f5630993d43..fc97b0b490b 100644 --- a/src/w32.c +++ b/src/w32.c @@ -101,17 +101,17 @@ typedef struct _MEMORY_STATUS_EX { _WIN32_WINNT than what we use. w32api supplied with MinGW 3.15 defines it in psapi.h */ typedef struct _PROCESS_MEMORY_COUNTERS_EX { - DWORD cb; - DWORD PageFaultCount; - DWORD PeakWorkingSetSize; - DWORD WorkingSetSize; - DWORD QuotaPeakPagedPoolUsage; - DWORD QuotaPagedPoolUsage; - DWORD QuotaPeakNonPagedPoolUsage; - DWORD QuotaNonPagedPoolUsage; - DWORD PagefileUsage; - DWORD PeakPagefileUsage; - DWORD PrivateUsage; + DWORD cb; + DWORD PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; + SIZE_T PrivateUsage; } PROCESS_MEMORY_COUNTERS_EX,*PPROCESS_MEMORY_COUNTERS_EX; #endif @@ -351,8 +351,8 @@ typedef BOOL (WINAPI * GetProcessMemoryInfo_Proc) ( DWORD cb); typedef BOOL (WINAPI * GetProcessWorkingSetSize_Proc) ( HANDLE hProcess, - DWORD * lpMinimumWorkingSetSize, - DWORD * lpMaximumWorkingSetSize); + PSIZE_T lpMinimumWorkingSetSize, + PSIZE_T lpMaximumWorkingSetSize); typedef BOOL (WINAPI * GlobalMemoryStatus_Proc) ( LPMEMORYSTATUS lpBuffer); typedef BOOL (WINAPI * GlobalMemoryStatusEx_Proc) ( @@ -4620,8 +4620,8 @@ get_process_memory_info (HANDLE h_proc, static BOOL WINAPI get_process_working_set_size (HANDLE h_proc, - DWORD *minrss, - DWORD *maxrss) + PSIZE_T minrss, + PSIZE_T maxrss) { static GetProcessWorkingSetSize_Proc s_pfn_Get_Process_Working_Set_Size = NULL; @@ -4866,7 +4866,7 @@ system_process_attributes (Lisp_Object pid) unsigned egid; PROCESS_MEMORY_COUNTERS mem; PROCESS_MEMORY_COUNTERS_EX mem_ex; - DWORD minrss, maxrss; + SIZE_T minrss, maxrss; MEMORYSTATUS memst; MEMORY_STATUS_EX memstex; double totphys = 0.0; @@ -5094,7 +5094,7 @@ system_process_attributes (Lisp_Object pid) && get_process_memory_info (h_proc, (PROCESS_MEMORY_COUNTERS *)&mem_ex, sizeof (mem_ex))) { - DWORD rss = mem_ex.WorkingSetSize / 1024; + SIZE_T rss = mem_ex.WorkingSetSize / 1024; attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (mem_ex.PageFaultCount)), @@ -5109,7 +5109,7 @@ system_process_attributes (Lisp_Object pid) else if (h_proc && get_process_memory_info (h_proc, &mem, sizeof (mem))) { - DWORD rss = mem_ex.WorkingSetSize / 1024; + SIZE_T rss = mem_ex.WorkingSetSize / 1024; attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (mem.PageFaultCount)), diff --git a/src/w32fns.c b/src/w32fns.c index 8e1ecc1cb00..de5cee1d7a7 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -7032,7 +7032,7 @@ cache_system_info (void) /* Cache page size, allocation unit, processor type, etc. */ GetSystemInfo (&sysinfo_cache); - syspage_mask = sysinfo_cache.dwPageSize - 1; + syspage_mask = (DWORD_PTR)sysinfo_cache.dwPageSize - 1; /* Cache os info. */ osinfo_cache.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); -- cgit v1.2.1 From c56efa40745336c8067f047fe8f736821ddb3791 Mon Sep 17 00:00:00 2001 From: Fabrice Popineau Date: Sat, 8 Dec 2012 14:11:29 +0200 Subject: w32fns.c (emacs_abort): Don't do arithmetics on void pointers. --- src/ChangeLog | 4 ++++ src/w32fns.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 3e8b8519ba3..54985d33b59 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2012-12-08 Fabrice Popineau + + * w32fns.c (emacs_abort): Don't do arithmetics on void pointers. + 2012-12-08 Eli Zaretskii * w32.c (unsetenv, sys_putenv): New functions. diff --git a/src/w32fns.c b/src/w32fns.c index 6801fc68054..1a181079c82 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -7784,7 +7784,7 @@ emacs_abort (void) /* stack[] gives the return addresses, whereas we want the address of the call, so decrease each address by approximate size of 1 CALL instruction. */ - sprintf (buf, "0x%p\r\n", stack[j] - sizeof(void *)); + sprintf (buf, "0x%p\r\n", (char *)stack[j] - sizeof(void *)); if (stderr_fd >= 0) write (stderr_fd, buf, strlen (buf)); if (errfile_fd >= 0) -- cgit v1.2.1 From 5745a7df2b4abe06d032820f6ec7ddbac9ad5028 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 8 Dec 2012 09:19:51 -0800 Subject: Use putenv+unsetenv instead of modifying environ directly. * admin/merge-gnulib (GNULIB_MODULES): Add putenv, unsetenv. * lib/putenv.c, lib/unsetenv.c, m4/putenv.m4, m4/setenv.m4: New files, copied automatically from gnulib. * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * src/alloc.c (xputenv): New function. * src/dbusbind.c (Fdbus_init_bus): * src/emacs.c (main): * src/xterm.c (x_term_init): Use xputenv instead of setenv or putenv, to detect memory exhaustion. * src/editfns.c (initial_tz): Move static var decl up. (tzvalbuf_in_environ): New static var. (init_editfns): Initialize these two static vars. (Fencode_time): Don't assume arbitrary limit on EMACS_INT width. Save old TZ value on stack, if it's small. (Fencode_time, set_time_zone_rule): Don't modify 'environ' directly; instead, use xputenv+unsetenv to set and restore TZ. (environbuf): Remove static var. All uses removed. (Fset_time_zone_rule): Do not save TZ and environ; no longer needed here. (set_time_zone_rule_tz1, set_time_zone_rule_tz2) [LOCALTIME_CACHE]: Move to inside set_time_zone_rule; they don't need file scope any more. (set_time_zone_rule): Maintain the TZ=value string separately. (syms_of_editfns): Don't initialize initial_tz; init_editfns now does it. * src/emacs.c (dump_tz) [HAVE_TZSET]: Now const. * src/lisp.h (xputenv): New decl. Fixes: debbugs:13070 --- src/ChangeLog | 26 ++++++++ src/alloc.c | 9 +++ src/dbusbind.c | 2 +- src/editfns.c | 204 +++++++++++++++++++++++++++------------------------------ src/emacs.c | 9 ++- src/lisp.h | 1 + src/xterm.c | 5 +- 7 files changed, 138 insertions(+), 118 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 54985d33b59..0be3eee6726 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,29 @@ +2012-12-08 Paul Eggert + + Use putenv+unsetenv instead of modifying environ directly (Bug#13070). + * alloc.c (xputenv): New function. + * dbusbind.c (Fdbus_init_bus): + * emacs.c (main): + * xterm.c (x_term_init): + Use xputenv instead of setenv or putenv, to detect memory exhaustion. + * editfns.c (initial_tz): Move static var decl up. + (tzvalbuf_in_environ): New static var. + (init_editfns): Initialize these two static vars. + (Fencode_time): Don't assume arbitrary limit on EMACS_INT width. + Save old TZ value on stack, if it's small. + (Fencode_time, set_time_zone_rule): Don't modify 'environ' directly; + instead, use xputenv+unsetenv to set and restore TZ. + (environbuf): Remove static var. All uses removed. + (Fset_time_zone_rule): Do not save TZ and environ; + no longer needed here. + (set_time_zone_rule_tz1, set_time_zone_rule_tz2) [LOCALTIME_CACHE]: + Move to inside set_time_zone_rule; they don't need file scope any more. + (set_time_zone_rule): Maintain the TZ=value string separately. + (syms_of_editfns): Don't initialize initial_tz; + init_editfns now does it. + * emacs.c (dump_tz) [HAVE_TZSET]: Now const. + * lisp.h (xputenv): New decl. + 2012-12-08 Fabrice Popineau * w32fns.c (emacs_abort): Don't do arithmetics on void pointers. diff --git a/src/alloc.c b/src/alloc.c index 0f105f87207..5a3ba465d81 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -820,6 +820,15 @@ xstrdup (const char *s) return p; } +/* Like putenv, but (1) use the equivalent of xmalloc and (2) the + argument is a const pointer. */ + +void +xputenv (char const *string) +{ + if (putenv ((char *) string) != 0) + memory_full (0); +} /* Unwind for SAFE_ALLOCA */ diff --git a/src/dbusbind.c b/src/dbusbind.c index 80086946fc4..da8bbb1e5d7 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c @@ -1203,7 +1203,7 @@ this connection to those buses. */) xd_registered_buses = Fcons (Fcons (bus, val), xd_registered_buses); /* We do not want to abort. */ - putenv ((char *) "DBUS_FATAL_WARNINGS=0"); + xputenv ("DBUS_FATAL_WARNINGS=0"); /* Cleanup. */ dbus_error_free (&derror); diff --git a/src/editfns.c b/src/editfns.c index ffb9a38909b..7d179c8566a 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -78,6 +78,15 @@ Lisp_Object Qfield; static Lisp_Object Qboundary; +/* The startup value of the TZ environment variable so it can be + restored if the user calls set-time-zone-rule with a nil + argument. If null, the TZ environment variable was unset. */ +static char const *initial_tz; + +/* True if the static variable tzvalbuf (defined in + set_time_zone_rule) is part of 'environ'. */ +static bool tzvalbuf_in_environ; + void init_editfns (void) @@ -96,6 +105,9 @@ init_editfns (void) return; #endif /* not CANNOT_DUMP */ + initial_tz = getenv ("TZ"); + tzvalbuf_in_environ = 0; + pw = getpwuid (getuid ()); #ifdef MSDOS /* We let the real user name default to "root" because that's quite @@ -1900,9 +1912,11 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */) } else { - char tzbuf[100]; + static char const tzbuf_format[] = "XXX%s%"pI"d:%02d:%02d"; + char tzbuf[sizeof tzbuf_format + INT_STRLEN_BOUND (EMACS_INT)]; + char *old_tzstring; const char *tzstring; - char **oldenv = environ, **newenv; + USE_SAFE_ALLOCA; if (EQ (zone, Qt)) tzstring = "UTC0"; @@ -1914,13 +1928,20 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */) EMACS_INT zone_hr = abszone / (60*60); int zone_min = (abszone/60) % 60; int zone_sec = abszone % 60; - sprintf (tzbuf, "XXX%s%"pI"d:%02d:%02d", "-" + (XINT (zone) < 0), + sprintf (tzbuf, tzbuf_format, "-" + (XINT (zone) < 0), zone_hr, zone_min, zone_sec); tzstring = tzbuf; } else error ("Invalid time zone specification"); + old_tzstring = getenv ("TZ"); + if (old_tzstring) + { + char *buf = SAFE_ALLOCA (strlen (old_tzstring) + 1); + old_tzstring = strcpy (buf, old_tzstring); + } + block_input (); /* Set TZ before calling mktime; merely adjusting mktime's returned @@ -1929,15 +1950,12 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */) value = mktime (&tm); - /* Restore TZ to previous value. */ - newenv = environ; - environ = oldenv; + set_time_zone_rule (old_tzstring); #ifdef LOCALTIME_CACHE tzset (); #endif unblock_input (); - - xfree (newenv); + SAFE_FREE (); } if (value == (time_t) -1) @@ -2067,16 +2085,6 @@ the data it can't find. */) return list2 (zone_offset, zone_name); } -/* This holds the value of `environ' produced by the previous - call to Fset_time_zone_rule, or 0 if Fset_time_zone_rule - has never been called. */ -static char **environbuf; - -/* This holds the startup value of the TZ environment variable so it - can be restored if the user calls set-time-zone-rule with a nil - argument. */ -static char *initial_tz; - DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0, doc: /* Set the local time zone using TZ, a string specifying a time zone rule. If TZ is nil, use implementation-defined default time zone information. @@ -2089,18 +2097,10 @@ only the former. */) (Lisp_Object tz) { const char *tzstring; - char **old_environbuf; if (! (NILP (tz) || EQ (tz, Qt))) CHECK_STRING (tz); - block_input (); - - /* When called for the first time, save the original TZ. */ - old_environbuf = environbuf; - if (!old_environbuf) - initial_tz = (char *) getenv ("TZ"); - if (NILP (tz)) tzstring = initial_tz; else if (EQ (tz, Qt)) @@ -2108,106 +2108,97 @@ only the former. */) else tzstring = SSDATA (tz); + block_input (); set_time_zone_rule (tzstring); - environbuf = environ; - unblock_input (); - xfree (old_environbuf); return Qnil; } -#ifdef LOCALTIME_CACHE - -/* These two values are known to load tz files in buggy implementations, - i.e. Solaris 1 executables running under either Solaris 1 or Solaris 2. - Their values shouldn't matter in non-buggy implementations. - We don't use string literals for these strings, - since if a string in the environment is in readonly - storage, it runs afoul of bugs in SVR4 and Solaris 2.3. - See Sun bugs 1113095 and 1114114, ``Timezone routines - improperly modify environment''. */ - -static char set_time_zone_rule_tz1[] = "TZ=GMT+0"; -static char set_time_zone_rule_tz2[] = "TZ=GMT+1"; - -#endif - /* Set the local time zone rule to TZSTRING. - This allocates memory into `environ', which it is the caller's - responsibility to free. */ + + This function is not thread-safe, partly because putenv, unsetenv + and tzset are not, and partly because of the static storage it + updates. Other threads that invoke localtime etc. may be adversely + affected while this function is executing. */ void set_time_zone_rule (const char *tzstring) { - ptrdiff_t envptrs; - char **from, **to, **newenv; + /* A buffer holding a string of the form "TZ=value", intended + to be part of the environment. */ + static char *tzvalbuf; + static ptrdiff_t tzvalbufsize; - /* Make the ENVIRON vector longer with room for TZSTRING. */ - for (from = environ; *from; from++) - continue; - envptrs = from - environ + 2; - newenv = to = xmalloc (envptrs * sizeof *newenv - + (tzstring ? strlen (tzstring) + 4 : 0)); + int tzeqlen = sizeof "TZ=" - 1; + +#ifdef LOCALTIME_CACHE + /* These two values are known to load tz files in buggy implementations, + i.e., Solaris 1 executables running under either Solaris 1 or Solaris 2. + Their values shouldn't matter in non-buggy implementations. + We don't use string literals for these strings, + since if a string in the environment is in readonly + storage, it runs afoul of bugs in SVR4 and Solaris 2.3. + See Sun bugs 1113095 and 1114114, ``Timezone routines + improperly modify environment''. */ + + static char set_time_zone_rule_tz[][sizeof "TZ=GMT+0"] + = { "TZ=GMT+0", "TZ=GMT+1" }; + + /* In SunOS 4.1.3_U1 and 4.1.4, if TZ has a value like + "US/Pacific" that loads a tz file, then changes to a value like + "XXX0" that does not load a tz file, and then changes back to + its original value, the last change is (incorrectly) ignored. + Also, if TZ changes twice in succession to values that do + not load a tz file, tzset can dump core (see Sun bug#1225179). + The following code works around these bugs. */ - /* Add TZSTRING to the end of environ, as a value for TZ. */ if (tzstring) { - char *t = (char *) (to + envptrs); - strcpy (t, "TZ="); - strcat (t, tzstring); - *to++ = t; + /* Temporarily set TZ to a value that loads a tz file + and that differs from tzstring. */ + bool eq0 = strcmp (tzstring, set_time_zone_rule_tz[0] + tzeqlen) == 0; + xputenv (set_time_zone_rule_tz[eq0]); } + else + { + /* The implied tzstring is unknown, so temporarily set TZ to + two different values that each load a tz file. */ + xputenv (set_time_zone_rule_tz[0]); + tzset (); + xputenv (set_time_zone_rule_tz[1]); + } + tzset (); +#endif - /* Copy the old environ vector elements into NEWENV, - but don't copy the TZ variable. - So we have only one definition of TZ, which came from TZSTRING. */ - for (from = environ; *from; from++) - if (strncmp (*from, "TZ=", 3) != 0) - *to++ = *from; - *to = 0; - - environ = newenv; + if (!tzstring) + { + unsetenv ("TZ"); + tzvalbuf_in_environ = 0; + } + else + { + ptrdiff_t tzstringlen = strlen (tzstring); - /* If we do have a TZSTRING, NEWENV points to the vector slot where - the TZ variable is stored. If we do not have a TZSTRING, - TO points to the vector slot which has the terminating null. */ + if (tzvalbufsize <= tzeqlen + tzstringlen) + { + unsetenv ("TZ"); + tzvalbuf_in_environ = 0; + tzvalbuf = xpalloc (tzvalbuf, &tzvalbufsize, + tzeqlen + tzstringlen - tzvalbufsize + 1, -1, 1); + memcpy (tzvalbuf, "TZ=", tzeqlen); + } -#ifdef LOCALTIME_CACHE - { - /* In SunOS 4.1.3_U1 and 4.1.4, if TZ has a value like - "US/Pacific" that loads a tz file, then changes to a value like - "XXX0" that does not load a tz file, and then changes back to - its original value, the last change is (incorrectly) ignored. - Also, if TZ changes twice in succession to values that do - not load a tz file, tzset can dump core (see Sun bug#1225179). - The following code works around these bugs. */ - - if (tzstring) - { - /* Temporarily set TZ to a value that loads a tz file - and that differs from tzstring. */ - char *tz = *newenv; - *newenv = (strcmp (tzstring, set_time_zone_rule_tz1 + 3) == 0 - ? set_time_zone_rule_tz2 : set_time_zone_rule_tz1); - tzset (); - *newenv = tz; - } - else - { - /* The implied tzstring is unknown, so temporarily set TZ to - two different values that each load a tz file. */ - *to = set_time_zone_rule_tz1; - to[1] = 0; - tzset (); - *to = set_time_zone_rule_tz2; - tzset (); - *to = 0; - } + strcpy (tzvalbuf + tzeqlen, tzstring); - /* Now TZ has the desired value, and tzset can be invoked safely. */ - } + if (!tzvalbuf_in_environ) + { + xputenv (tzvalbuf); + tzvalbuf_in_environ = 1; + } + } +#ifdef LOCALTIME_CACHE tzset (); #endif } @@ -4800,9 +4791,6 @@ Transposing beyond buffer boundaries is an error. */) void syms_of_editfns (void) { - environbuf = 0; - initial_tz = 0; - DEFSYM (Qbuffer_access_fontify_functions, "buffer-access-fontify-functions"); DEFVAR_LISP ("inhibit-field-text-motion", Vinhibit_field_text_motion, diff --git a/src/emacs.c b/src/emacs.c index b2b193e3a4f..fbaf0355000 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -535,7 +535,7 @@ DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory, #ifdef HAVE_TZSET /* A valid but unlikely value for the TZ environment value. It is OK (though a bit slower) if the user actually chooses this value. */ -static char dump_tz[] = "UtC0"; +static char const dump_tz[] = "UtC0"; #endif #ifndef ORDINARY_LINK @@ -717,7 +717,7 @@ main (int argc, char **argv) #ifdef G_SLICE_ALWAYS_MALLOC /* This is used by the Cygwin build. */ - setenv ("G_SLICE", "always-malloc", 1); + xputenv ("G_SLICE=always-malloc"); #endif #ifdef GNU_LINUX @@ -803,9 +803,8 @@ main (int argc, char **argv) #ifdef HAVE_PERSONALITY_LINUX32 if (dumping && ! getenv ("EMACS_HEAP_EXEC")) { - static char heapexec[] = "EMACS_HEAP_EXEC=true"; /* Set this so we only do this once. */ - putenv (heapexec); + xputenv ("EMACS_HEAP_EXEC=true"); /* A flag to turn off address randomization which is introduced in linux kernel shipped with fedora core 4 */ @@ -1309,7 +1308,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem don't pollute Vglobal_environment. */ /* Setting LANG here will defeat the startup locale processing... */ #ifdef AIX - putenv ("LANG=C"); + xputenv ("LANG=C"); #endif init_buffer (); /* Init default directory of main buffer. */ diff --git a/src/lisp.h b/src/lisp.h index 172a32e92a9..91fc3dfa1c6 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3594,6 +3594,7 @@ extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t); extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t); extern char *xstrdup (const char *); +extern void xputenv (const char *); extern char *egetenv (const char *); diff --git a/src/xterm.c b/src/xterm.c index 8acd1d7843e..e9e99574663 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -9908,10 +9908,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) /* Emacs can only handle core input events, so make sure Gtk doesn't use Xinput or Xinput2 extensions. */ - { - static char fix_events[] = "GDK_CORE_DEVICE_EVENTS=1"; - putenv (fix_events); - } + xputenv ("GDK_CORE_DEVICE_EVENTS=1"); /* Work around GLib bug that outputs a faulty warning. See https://bugzilla.gnome.org/show_bug.cgi?id=563627. */ -- cgit v1.2.1 From a16e75cd3cb27ea5647774bc71625899f35b2fa6 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 8 Dec 2012 20:27:37 +0200 Subject: Fix putenv and unsetenv on MS-Windows. src/w32.c (unsetenv): Return 0 if the input string is too long. nt/inc/ms-w32.h (sys_putenv): Add prototype. Fixes: debbugs:13070 --- src/ChangeLog | 4 ++++ src/w32.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 0be3eee6726..222be9575b8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2012-12-08 Eli Zaretskii + + * w32.c (unsetenv): Return 0 if the input string is too long. + 2012-12-08 Paul Eggert Use putenv+unsetenv instead of modifying environ directly (Bug#13070). diff --git a/src/w32.c b/src/w32.c index 203c5cd40ff..b6bb653369d 100644 --- a/src/w32.c +++ b/src/w32.c @@ -1562,7 +1562,7 @@ unsetenv (const char *name) if (name_len > 32767) { errno = ENOMEM; - return -1; + return 0; } /* It is safe to use 'alloca' with 32K size, since the stack is at least 2MB, and we set it to 8MB in the link command line. */ -- cgit v1.2.1 From a06ae17da2c6eb3c0e53fb3c9de555da71796af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Dj=C3=A4rv?= Date: Sat, 8 Dec 2012 20:02:30 +0100 Subject: * nsterm.m (fd_handler:): FD_ZERO fds. Fixes: debbugs:13103 --- src/ChangeLog | 6 +++++- src/nsterm.m | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index f3af852f9e9..9d9c1fdaff5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,9 +1,13 @@ +2012-12-08 Jan Djärv + + * nsterm.m (fd_handler:): FD_ZERO fds (Bug#13103). + 2012-12-08 Fabrice Popineau * w32fns.c (cache_system_info): Cast sysinfo_cache.dwPageSize to DWORD_PTR, for compatibility with 64-bit builds. - * w32.c (_PROCESS_MEMORY_COUNTERS_EX): + * w32.c (_PROCESS_MEMORY_COUNTERS_EX): (GetProcessWorkingSetSize_Proc, get_process_working_set_size) (system_process_attributes): Use SIZE_T rather than DWORD, for compatibility with 64-bit builds. diff --git a/src/nsterm.m b/src/nsterm.m index 9d52bd7f52b..783765fe0b6 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -4566,7 +4566,7 @@ not_in_argv (NSString *arg) if (waiting) { SELECT_TYPE fds; - + FD_ZERO (&fds); FD_SET (selfds[0], &fds); result = select (selfds[0]+1, &fds, NULL, NULL, NULL); if (result > 0) -- cgit v1.2.1 From 5f460827dd14fbfae26ac8451cedd4446817d1ec Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 9 Dec 2012 17:44:32 -0800 Subject: * fileio.c (Fsubstitute_in_file_name): Use ptrdiff_t, not int, for string length. --- src/ChangeLog | 5 +++++ src/fileio.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 222be9575b8..dd51eb9ed3b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2012-12-10 Paul Eggert + + * fileio.c (Fsubstitute_in_file_name): Use ptrdiff_t, not int, + for string length. + 2012-12-08 Eli Zaretskii * w32.c (unsetenv): Return 0 if the input string is too long. diff --git a/src/fileio.c b/src/fileio.c index de3b84ba95d..56c340bfa40 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -1590,7 +1590,7 @@ those `/' is discarded. */) { char *nm, *s, *p, *o, *x, *endp; char *target = NULL; - int total = 0; + ptrdiff_t total = 0; bool substituted = 0; bool multibyte; char *xnm; -- cgit v1.2.1 From 81606b10501169a5671061b8461bbc32dcec8705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BCdiger=20Sonderfeld?= Date: Mon, 10 Dec 2012 06:17:21 -0500 Subject: Support filesystem notification through inotify on GNU/Linux. configure.ac (inotify): New option. (HAVE_INOTIFY): Test for inotify. src/termhooks.h (enum event_kind) [HAVE_INOTIFY]: Add FILE_NOTIFY_EVENT. src/lisp.h (syms_of_inotify) [HAVE_INOTIFY]: Add prototype. src/keyboard.c (Qfile_inotify) [HAVE_INOTIFY]: New variable. (syms_of_keyboard): DEFSYM it. (kbd_buffer_get_event) [HAVE_INOTIFY]: Generate FILE_NOTIFY_EVENT. (make_lispy_event): Support FILE_NOTIFY_EVENT by generating Qfile_inotify events. (keys_of_keyboard) [HAVE_INOTIFY]: Bind file-inotify events in special-event-map to inotify-handle-event. src/emacs.c (main) [HAVE_INOTIFY]: Call syms_of_inotify. src/Makefile.in (base_obj): Add inotify.o. src/inotify.c: New file. lisp/subr.el (inotify-event-p, inotify-handle-event): New functions. test/automated/inotify-test.el: New test. --- src/ChangeLog | 21 +++ src/Makefile.in | 2 +- src/emacs.c | 4 + src/inotify.c | 438 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/keyboard.c | 28 ++++ src/lisp.h | 5 + src/termhooks.h | 5 + 7 files changed, 502 insertions(+), 1 deletion(-) create mode 100644 src/inotify.c (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index e7fc8179e07..e234b342ac7 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,24 @@ +2012-12-10 Rüdiger Sonderfeld + + * termhooks.h (enum event_kind) [HAVE_INOTIFY]: Add + FILE_NOTIFY_EVENT. + + * lisp.h (syms_of_inotify) [HAVE_INOTIFY]: Add prototype. + + * keyboard.c (Qfile_inotify) [HAVE_INOTIFY]: New variable. + (syms_of_keyboard): DEFSYM it. + (kbd_buffer_get_event) [HAVE_INOTIFY]: Generate FILE_NOTIFY_EVENT. + (make_lispy_event): Support FILE_NOTIFY_EVENT by generating + Qfile_inotify events. + (keys_of_keyboard) [HAVE_INOTIFY]: Bind file-inotify events in + special-event-map to inotify-handle-event. + + * emacs.c (main) [HAVE_INOTIFY]: Call syms_of_inotify. + + * Makefile.in (base_obj): Add inotify.o. + + * inotify.c: New file. + 2012-12-10 Jan Djärv * nsterm.m (fd_handler:): FD_ZERO fds (Bug#13103). diff --git a/src/Makefile.in b/src/Makefile.in index d034ad04796..eb7c7720ea5 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -344,7 +344,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \ syntax.o $(UNEXEC_OBJ) bytecode.o \ process.o gnutls.o callproc.o \ region-cache.o sound.o atimer.o \ - doprnt.o intervals.o textprop.o composite.o xml.o \ + doprnt.o intervals.o textprop.o composite.o xml.o inotify.o \ profiler.o \ $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \ $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) diff --git a/src/emacs.c b/src/emacs.c index fbaf0355000..c5d27a28852 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1442,6 +1442,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem syms_of_gnutls (); #endif +#ifdef HAVE_INOTIFY + syms_of_inotify (); +#endif /* HAVE_INOTIFY */ + #ifdef HAVE_DBUS syms_of_dbusbind (); #endif /* HAVE_DBUS */ diff --git a/src/inotify.c b/src/inotify.c new file mode 100644 index 00000000000..4db95a069fe --- /dev/null +++ b/src/inotify.c @@ -0,0 +1,438 @@ +/* Inotify support for Emacs + +Copyright (C) 2012 + Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs. If not, see . */ + +#include + +#ifdef HAVE_INOTIFY + +#include "lisp.h" +#include "coding.h" +#include "process.h" +#include "keyboard.h" +#include "character.h" +#include "frame.h" /* Required for termhooks.h. */ +#include "termhooks.h" + +static Lisp_Object Qaccess; /* IN_ACCESS */ +static Lisp_Object Qattrib; /* IN_ATTRIB */ +static Lisp_Object Qclose_write; /* IN_CLOSE_WRITE */ +static Lisp_Object Qclose_nowrite; /* IN_CLOSE_NOWRITE */ +static Lisp_Object Qcreate; /* IN_CREATE */ +static Lisp_Object Qdelete; /* IN_DELETE */ +static Lisp_Object Qdelete_self; /* IN_DELETE_SELF */ +static Lisp_Object Qmodify; /* IN_MODIFY */ +static Lisp_Object Qmove_self; /* IN_MOVE_SELF */ +static Lisp_Object Qmoved_from; /* IN_MOVED_FROM */ +static Lisp_Object Qmoved_to; /* IN_MOVED_TO */ +static Lisp_Object Qopen; /* IN_OPEN */ + +static Lisp_Object Qall_events; /* IN_ALL_EVENTS */ +static Lisp_Object Qmove; /* IN_MOVE */ +static Lisp_Object Qclose; /* IN_CLOSE */ + +static Lisp_Object Qdont_follow; /* IN_DONT_FOLLOW */ +static Lisp_Object Qexcl_unlink; /* IN_EXCL_UNLINK */ +static Lisp_Object Qmask_add; /* IN_MASK_ADD */ +static Lisp_Object Qoneshot; /* IN_ONESHOT */ +static Lisp_Object Qonlydir; /* IN_ONLYDIR */ + +static Lisp_Object Qignored; /* IN_IGNORED */ +static Lisp_Object Qisdir; /* IN_ISDIR */ +static Lisp_Object Qq_overflow; /* IN_Q_OVERFLOW */ +static Lisp_Object Qunmount; /* IN_UNMOUNT */ + +#include +#include + +/* Ignore bits that might be undefined on old GNU/Linux systems. */ +#ifndef IN_EXCL_UNLINK +# define IN_EXCL_UNLINK 0 +#endif +#ifndef IN_DONT_FOLLOW +# define IN_DONT_FOLLOW 0 +#endif +#ifndef IN_ONLYDIR +# define IN_ONLYDIR 0 +#endif + +enum { uninitialized = -100 }; +/* File handle for inotify. */ +static int inotifyfd = uninitialized; + +/* Assoc list of files being watched. + Format: + (watch-descriptor . callback) + */ +static Lisp_Object watch_list; + +static Lisp_Object +make_watch_descriptor (int wd) +{ + /* TODO replace this with a Misc Object! */ + return make_number (wd); +} + +static Lisp_Object +mask_to_aspects (uint32_t mask) { + Lisp_Object aspects = Qnil; + if (mask & IN_ACCESS) + aspects = Fcons (Qaccess, aspects); + if (mask & IN_ATTRIB) + aspects = Fcons (Qattrib, aspects); + if (mask & IN_CLOSE_WRITE) + aspects = Fcons (Qclose_write, aspects); + if (mask & IN_CLOSE_NOWRITE) + aspects = Fcons (Qclose_nowrite, aspects); + if (mask & IN_CREATE) + aspects = Fcons (Qcreate, aspects); + if (mask & IN_DELETE) + aspects = Fcons (Qdelete, aspects); + if (mask & IN_DELETE_SELF) + aspects = Fcons (Qdelete_self, aspects); + if (mask & IN_MODIFY) + aspects = Fcons (Qmodify, aspects); + if (mask & IN_MOVE_SELF) + aspects = Fcons (Qmove_self, aspects); + if (mask & IN_MOVED_FROM) + aspects = Fcons (Qmoved_from, aspects); + if (mask & IN_MOVED_TO) + aspects = Fcons (Qmoved_to, aspects); + if (mask & IN_OPEN) + aspects = Fcons (Qopen, aspects); + if (mask & IN_IGNORED) + aspects = Fcons (Qignored, aspects); + if (mask & IN_ISDIR) + aspects = Fcons (Qisdir, aspects); + if (mask & IN_Q_OVERFLOW) + aspects = Fcons (Qq_overflow, aspects); + if (mask & IN_UNMOUNT) + aspects = Fcons (Qunmount, aspects); + return aspects; +} + +static Lisp_Object +inotifyevent_to_event (Lisp_Object watch_object, struct inotify_event const *ev) +{ + Lisp_Object name = Qnil; + if (ev->len > 0) + { + size_t const len = strlen (ev->name); + name = make_unibyte_string (ev->name, min (len, ev->len)); + name = DECODE_FILE (name); + } + + return list2 (list4 (make_watch_descriptor (ev->wd), + mask_to_aspects (ev->mask), + make_number (ev->cookie), + name), + XCDR (watch_object)); +} + +/* This callback is called when the FD is available for read. The inotify + events are read from FD and converted into input_events. */ +static void +inotify_callback (int fd, void *_) +{ + struct input_event event; + Lisp_Object watch_object; + int to_read; + char *buffer; + ssize_t n; + size_t i; + + to_read = 0; + if (ioctl (fd, FIONREAD, &to_read) == -1) + report_file_error ("Error while trying to retrieve file system events", + Qnil); + buffer = xmalloc (to_read); + n = read (fd, buffer, to_read); + if (n < 0) + { + xfree (buffer); + report_file_error ("Error while trying to read file system events", + Qnil); + } + + EVENT_INIT (event); + event.kind = FILE_NOTIFY_EVENT; + event.arg = Qnil; + + i = 0; + while (i < (size_t)n) + { + struct inotify_event *ev = (struct inotify_event*)&buffer[i]; + + watch_object = Fassoc (make_watch_descriptor (ev->wd), watch_list); + if (!NILP (watch_object)) + { + event.arg = inotifyevent_to_event (watch_object, ev); + + /* If event was removed automatically: Drop it from watch list. */ + if (ev->mask & IN_IGNORED) + watch_list = Fdelete (watch_object, watch_list); + } + + i += sizeof (*ev) + ev->len; + } + + if (!NILP (event.arg)) + kbd_buffer_store_event (&event); + + xfree (buffer); +} + +static uint32_t +symbol_to_inotifymask (Lisp_Object symb) +{ + if (EQ (symb, Qaccess)) + return IN_ACCESS; + else if (EQ (symb, Qattrib)) + return IN_ATTRIB; + else if (EQ (symb, Qclose_write)) + return IN_CLOSE_WRITE; + else if (EQ (symb, Qclose_nowrite)) + return IN_CLOSE_NOWRITE; + else if (EQ (symb, Qcreate)) + return IN_CREATE; + else if (EQ (symb, Qdelete)) + return IN_DELETE; + else if (EQ (symb, Qdelete_self)) + return IN_DELETE_SELF; + else if (EQ (symb, Qmodify)) + return IN_MODIFY; + else if (EQ (symb, Qmove_self)) + return IN_MOVE_SELF; + else if (EQ (symb, Qmoved_from)) + return IN_MOVED_FROM; + else if (EQ (symb, Qmoved_to)) + return IN_MOVED_TO; + else if (EQ (symb, Qopen)) + return IN_OPEN; + else if (EQ (symb, Qmove)) + return IN_MOVE; + else if (EQ (symb, Qclose)) + return IN_CLOSE; + + else if (EQ (symb, Qdont_follow)) + return IN_DONT_FOLLOW; + else if (EQ (symb, Qexcl_unlink)) + return IN_EXCL_UNLINK; + else if (EQ (symb, Qmask_add)) + return IN_MASK_ADD; + else if (EQ (symb, Qoneshot)) + return IN_ONESHOT; + else if (EQ (symb, Qonlydir)) + return IN_ONLYDIR; + + else if (EQ (symb, Qt) || EQ (symb, Qall_events)) + return IN_ALL_EVENTS; + else + signal_error ("Unknown aspect", symb); +} + +static uint32_t +aspect_to_inotifymask (Lisp_Object aspect) +{ + if (CONSP (aspect)) + { + Lisp_Object x = aspect; + uint32_t mask = 0; + while (CONSP (x)) + { + mask |= symbol_to_inotifymask (XCAR (x)); + x = XCDR (x); + } + return mask; + } + else + return symbol_to_inotifymask (aspect); +} + +DEFUN ("inotify-add-watch", Finotify_add_watch, Sinotify_add_watch, 3, 3, 0, + doc: /* Add a watch for FILE-NAME to inotify. + +A WATCH-DESCRIPTOR is returned on success. ASPECT might be one of the following +symbols or a list of those symbols: + +access +attrib +close-write +close-nowrite +create +delete +delete-self +modify +move-self +moved-from +moved-to +open + +all-events or t +move +close + +The following symbols can also be added to a list of aspects + +dont-follow +excl-unlink +mask-add +oneshot +onlydir + +Watching a directory is not recursive. CALLBACK gets called in case of an +event. It gets passed a single argument EVENT which contains an event structure +of the format + +(WATCH-DESCRIPTOR ASPECTS COOKIE NAME) + +WATCH-DESCRIPTOR is the same object that was returned by this function. It can +be tested for equality using `equal'. ASPECTS describes the event. It is a +list of ASPECT symbols described above and can also contain one of the following +symbols + +ignored +isdir +q-overflow +unmount + +COOKIE is an object that can be compared using `equal' to identify two matching +renames (moved-from and moved-to). + +If a directory is watched then NAME is the name of file that caused the event. + +See inotify(7) and inotify_add_watch(2) for further information. The inotify fd +is managed internally and there is no corresponding inotify_init. Use +`inotify-rm-watch' to remove a watch. + */) + (Lisp_Object file_name, Lisp_Object aspect, Lisp_Object callback) +{ + uint32_t mask; + Lisp_Object watch_object; + Lisp_Object decoded_file_name; + Lisp_Object watch_descriptor; + int watchdesc = -1; + + CHECK_STRING (file_name); + + if (inotifyfd == uninitialized) + { + inotifyfd = inotify_init1 (IN_NONBLOCK|IN_CLOEXEC); + if (inotifyfd == -1) + { + inotifyfd = uninitialized; + report_file_error ("File watching feature (inotify) is not available", + Qnil); + } + watch_list = Qnil; + add_read_fd (inotifyfd, &inotify_callback, NULL); + } + + mask = aspect_to_inotifymask (aspect); + decoded_file_name = ENCODE_FILE (file_name); + watchdesc = inotify_add_watch (inotifyfd, SSDATA (decoded_file_name), mask); + if (watchdesc == -1) + report_file_error ("Could not add watch for file", Fcons (file_name, Qnil)); + + watch_descriptor = make_watch_descriptor (watchdesc); + + /* Delete existing watch object. */ + watch_object = Fassoc (watch_descriptor, watch_list); + if (!NILP (watch_object)) + watch_list = Fdelete (watch_object, watch_list); + + /* Store watch object in watch list. */ + watch_object = Fcons (watch_descriptor, callback); + watch_list = Fcons (watch_object, watch_list); + + return watch_descriptor; +} + +DEFUN ("inotify-rm-watch", Finotify_rm_watch, Sinotify_rm_watch, 1, 1, 0, + doc: /* Remove an existing WATCH-DESCRIPTOR. + +WATCH-DESCRIPTOR should be an object returned by `inotify-add-watch'. + +See inotify_rm_watch(2) for more information. + */) + (Lisp_Object watch_descriptor) +{ + Lisp_Object watch_object; + int wd = XINT (watch_descriptor); + + if (inotify_rm_watch (inotifyfd, wd) == -1) + report_file_error ("Could not rm watch", Fcons (watch_descriptor, + Qnil)); + + /* Remove watch descriptor from watch list. */ + watch_object = Fassoc (watch_descriptor, watch_list); + if (!NILP (watch_object)) + watch_list = Fdelete (watch_object, watch_list); + + /* Cleanup if no more files are watched. */ + if (NILP (watch_list)) + { + close (inotifyfd); + delete_read_fd (inotifyfd); + inotifyfd = uninitialized; + } + + return Qt; +} + +void +syms_of_inotify (void) +{ + DEFSYM (Qaccess, "access"); + DEFSYM (Qattrib, "attrib"); + DEFSYM (Qclose_write, "close-write"); + DEFSYM (Qclose_nowrite, "close-nowrite"); + DEFSYM (Qcreate, "create"); + DEFSYM (Qdelete, "delete"); + DEFSYM (Qdelete_self, "delete-self"); + DEFSYM (Qmodify, "modify"); + DEFSYM (Qmove_self, "move-self"); + DEFSYM (Qmoved_from, "moved-from"); + DEFSYM (Qmoved_to, "moved-to"); + DEFSYM (Qopen, "open"); + + DEFSYM (Qall_events, "all-events"); + DEFSYM (Qmove, "move"); + DEFSYM (Qclose, "close"); + + DEFSYM (Qdont_follow, "dont-follow"); + DEFSYM (Qexcl_unlink, "excl-unlink"); + DEFSYM (Qmask_add, "mask-add"); + DEFSYM (Qoneshot, "oneshot"); + DEFSYM (Qonlydir, "onlydir"); + + DEFSYM (Qignored, "ignored"); + DEFSYM (Qisdir, "isdir"); + DEFSYM (Qq_overflow, "q-overflow"); + DEFSYM (Qunmount, "unmount"); + + defsubr (&Sinotify_add_watch); + defsubr (&Sinotify_rm_watch); + + staticpro (&watch_list); + + Fprovide (intern_c_string ("inotify"), Qnil); +} + +#endif /* HAVE_INOTIFY */ diff --git a/src/keyboard.c b/src/keyboard.c index fc155c5a5f7..4c484efe0c0 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -319,6 +319,9 @@ static Lisp_Object Qsave_session; #ifdef HAVE_DBUS static Lisp_Object Qdbus_event; #endif +#ifdef HAVE_INOTIFY +static Lisp_Object Qfile_inotify; +#endif /* HAVE_INOTIFY */ static Lisp_Object Qconfig_changed_event; /* Lisp_Object Qmouse_movement; - also an event header */ @@ -3960,6 +3963,13 @@ kbd_buffer_get_event (KBOARD **kbp, obj = make_lispy_event (event); kbd_fetch_ptr = event + 1; } +#endif +#ifdef HAVE_INOTIFY + else if (event->kind == FILE_NOTIFY_EVENT) + { + obj = make_lispy_event (event); + kbd_fetch_ptr = event + 1; + } #endif else if (event->kind == CONFIG_CHANGED_EVENT) { @@ -5874,6 +5884,13 @@ make_lispy_event (struct input_event *event) } #endif /* HAVE_DBUS */ +#ifdef HAVE_INOTIFY + case FILE_NOTIFY_EVENT: + { + return Fcons (Qfile_inotify, event->arg); + } +#endif /* HAVE_INOTIFY */ + case CONFIG_CHANGED_EVENT: return Fcons (Qconfig_changed_event, Fcons (event->arg, @@ -11337,6 +11354,10 @@ syms_of_keyboard (void) DEFSYM (Qdbus_event, "dbus-event"); #endif +#ifdef HAVE_INOTIFY + DEFSYM (Qfile_inotify, "file-inotify"); +#endif /* HAVE_INOTIFY */ + DEFSYM (QCenable, ":enable"); DEFSYM (QCvisible, ":visible"); DEFSYM (QChelp, ":help"); @@ -12093,6 +12114,13 @@ keys_of_keyboard (void) "dbus-handle-event"); #endif +#ifdef HAVE_INOTIFY + /* Define a special event which is raised for inotify callback + functions. */ + initial_define_lispy_key (Vspecial_event_map, "file-inotify", + "inotify-handle-event"); +#endif /* HAVE_INOTIFY */ + initial_define_lispy_key (Vspecial_event_map, "config-changed-event", "ignore"); #if defined (WINDOWSNT) diff --git a/src/lisp.h b/src/lisp.h index 91fc3dfa1c6..5acb37f08d1 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3516,6 +3516,11 @@ extern void syms_of_fontset (void); extern Lisp_Object Qfont_param; #endif +/* Defined in inotify.c */ +#ifdef HAVE_INOTIFY +extern void syms_of_inotify (void); +#endif + /* Defined in xfaces.c. */ extern Lisp_Object Qdefault, Qtool_bar, Qfringe; extern Lisp_Object Qheader_line, Qscroll_bar, Qcursor; diff --git a/src/termhooks.h b/src/termhooks.h index b35c927fc53..da65f9d6b74 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -211,6 +211,11 @@ enum event_kind , NS_NONKEY_EVENT #endif +#ifdef HAVE_INOTIFY + /* File or directory was changed. */ + , FILE_NOTIFY_EVENT +#endif + }; /* If a struct input_event has a kind which is SELECTION_REQUEST_EVENT -- cgit v1.2.1