diff --git a/ChangeLog b/ChangeLog index bf4d53edf4b..1286f7dcf5a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2012-05-02 Glenn Morris + * configure.in (LD_SWITCH_SYSTEM): Don't try to defeat + the choices made by FreeBSD and NetBSD. (Bug#10313) + * Makefile.in (INFO_FILES): Remove variable. (INFO_NONMISC): New variable. (install-arch-indep, uninstall): Don't use $INFO_FILES. @@ -10,13 +13,6 @@ * Makefile.in (install-arch-indep, uninstall): Ensure that INSTALL-type commands are run from top-level. - * Makefile.in (INFO_FILES): Add emacs-gnutls; accidentally - omitted from 2012-04-12 backport from trunk. - - * info/dir: Make some entries consistent with the source texi files. - - * configure.in (LIBS_TERMCAP): Fix netbsd logic, broken 2012-03-04. - * info/dir: Make some entries consistent with the source texi files. * configure.in (LIBS_TERMCAP): Fix netbsd logic, broken 2012-03-04. diff --git a/autogen/configure b/autogen/configure index 6e8ddc505fe..5a70efc967f 100755 --- a/autogen/configure +++ b/autogen/configure @@ -14939,9 +14939,7 @@ $as_echo "$emacs_cv_freebsd_terminfo" >&6; } ;; netbsd) - if test $ac_cv_search_tputs = -lterminfo; then - LIBS_TERMCAP="-lterminfo" - else + if "x$LIBS_TERMCAP" != "x-lterminfo" ; then TERMINFO=no LIBS_TERMCAP="-ltermcap" fi diff --git a/configure.in b/configure.in index c0a12672c62..2bf78e522ec 100644 --- a/configure.in +++ b/configure.in @@ -951,7 +951,9 @@ case "$opsys" in ## Let `ld' find image libs and similar things in /usr/local/lib. ## The system compiler, GCC, has apparently been modified to not ## look there, contrary to what a stock GCC would do. - LD_SWITCH_SYSTEM=-L/usr/local/lib +### It's not our place to do this. See bug#10313#17. +### LD_SWITCH_SYSTEM=-L/usr/local/lib + : ;; gnu-linux) @@ -960,7 +962,9 @@ case "$opsys" in ;; netbsd) - LD_SWITCH_SYSTEM="-Wl,-rpath,/usr/pkg/lib -L/usr/pkg/lib -Wl,-rpath,/usr/local/lib -L/usr/local/lib" +### It's not our place to do this. See bug#10313#17. +### LD_SWITCH_SYSTEM="-Wl,-rpath,/usr/pkg/lib -L/usr/pkg/lib -Wl,-rpath,/usr/local/lib -L/usr/local/lib" + : ;; openbsd) diff --git a/etc/NEWS b/etc/NEWS index 01d8d308831..cd15273c3db 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -32,6 +32,11 @@ may be useful. --- ** Emacs uses libtinfo in preference to libncurses, if available. +--- +** On FreeBSD and NetBSD, configure no longer adds /usr/local/lib and +/usr/pkg/lib to the linker search path. You must add them yourself if +you want them. + * Startup Changes in Emacs 24.2 diff --git a/lisp/ChangeLog b/lisp/ChangeLog index d35f5475bbc..ff2c5a40787 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -4,6 +4,18 @@ decoding, and show a warning message without signalling an error (Bug#11282). +2012-05-03 Stefan Monnier + + * emacs-lisp/bytecomp.el + (byte-compile-file-form-custom-declare-variable): Compile all elements, + since cconv.el might have introduced :fun-body, internal-make-closure, + and friends for bytecomp to handle (bug#11391). + * custom.el (defcustom): Avoid ((λ ..) ..). + +2012-05-02 Stefan Monnier + + * subr.el (read-passwd): Better clean after ourselves (bug#11392). + 2012-05-02 Juanma Barranquero * notifications.el (dbus-debug): diff --git a/lisp/custom.el b/lisp/custom.el index 611d5688f30..d0eadcc23ff 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -335,7 +335,7 @@ for more information." ;; expression is checked by the byte-compiler, and that ;; lexical-binding is obeyed, so quote the expression with ;; `lambda' rather than with `quote'. - `(list (lambda () ,standard)) + ``(funcall #',(lambda () ,standard)) `',standard) ,doc ,@args)) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 93c6518d215..9cb0a376e36 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2267,19 +2267,7 @@ list that represents a doc string reference. (when (byte-compile-warning-enabled-p 'callargs) (byte-compile-nogroup-warn form)) (push (nth 1 (nth 1 form)) byte-compile-bound-variables) - ;; Don't compile the expression because it may be displayed to the user. - ;; (when (eq (car-safe (nth 2 form)) 'quote) - ;; ;; (nth 2 form) is meant to evaluate to an expression, so if we have the - ;; ;; final value already, we can byte-compile it. - ;; (setcar (cdr (nth 2 form)) - ;; (byte-compile-top-level (cadr (nth 2 form)) nil 'file))) - (let ((tail (nthcdr 4 form))) - (while tail - (unless (keywordp (car tail)) ;No point optimizing keywords. - ;; Compile the keyword arguments. - (setcar tail (byte-compile-top-level (car tail) nil 'file))) - (setq tail (cdr tail)))) - form) + (byte-compile-keep-pending form)) (put 'require 'byte-hunk-handler 'byte-compile-file-form-require) (defun byte-compile-file-form-require (form) diff --git a/lisp/subr.el b/lisp/subr.el index b548f82ca5a..1f9f3aee9fa 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2115,21 +2115,21 @@ by doing (clear-string STRING)." (message "Password not repeated accurately; please start over") (sit-for 1)))) success) - (let (minibuf) + (let ((hide-chars-fun + (lambda (beg end _len) + (clear-this-command-keys) + (setq beg (min end (max (minibuffer-prompt-end) + beg))) + (dotimes (i (- end beg)) + (put-text-property (+ i beg) (+ 1 i beg) + 'display (string ?.))))) + minibuf) (minibuffer-with-setup-hook (lambda () (setq minibuf (current-buffer)) ;; Turn off electricity. (set (make-local-variable 'post-self-insert-hook) nil) - (add-hook 'after-change-functions - (lambda (beg end _len) - (clear-this-command-keys) - (setq beg (min end (max (minibuffer-prompt-end) - beg))) - (dotimes (i (- end beg)) - (put-text-property (+ i beg) (+ 1 i beg) - 'display (string ?.)))) - nil t)) + (add-hook 'after-change-functions hide-chars-fun nil 'local)) (unwind-protect (read-string prompt nil (let ((sym (make-symbol "forget-history"))) @@ -2137,7 +2137,14 @@ by doing (clear-string STRING)." sym) default) (when (buffer-live-p minibuf) - (with-current-buffer minibuf (erase-buffer)))))))) + (with-current-buffer minibuf + ;; Not sure why but it seems that there might be cases where the + ;; minibuffer is not always properly reset later on, so undo + ;; whatever we've done here (bug#11392). + (remove-hook 'after-change-functions hide-chars-fun 'local) + (kill-local-variable 'post-self-insert-hook) + ;; And of course, don't keep the sensitive data around. + (erase-buffer)))))))) ;; This should be used by `call-interactively' for `n' specs. (defun read-number (prompt &optional default) diff --git a/src/ChangeLog b/src/ChangeLog index d621dcc8859..bf297616e82 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,29 @@ +2012-05-02 Paul Eggert + + Fix race conditions involving setenv, gmtime, localtime, asctime. + Without this fix, interrupts could mess up code that uses these + nonreentrant functions, since setting TZ invalidates existing + tm_zone or tzname values, and since most of these functions return + pointers to static storage. + * editfns.c (format_time_string, Fdecode_time, Fencode_time) + (Fcurrent_time_string, Fcurrent_time_zone, Fset_time_zone_rule): + Grow the critical sections to include not just invoking + localtime/gmtime, but also accessing these functions' results + including their tm_zone values if any, and any related TZ setting. + (format_time_string): Last arg is now struct tm *, not struct tm **, + so that the struct tm is saved in the critical section. All + callers changed. Simplify allocation of initial buffer, partly + motivated by the fact that memory allocation needs to be outside + the critical section. + +2012-05-02 Dmitry Antipov + + * intervals.c (adjust_intervals_for_insertion): Initialize `newi' + with RESET_INTERVAL. + + * buffer.c (Fget_buffer_create, Fmake_indirect_buffer): + Remove duplicated buffer name initialization. + 2012-05-02 Jim Meyering * xterm.c (x_term_init): Use memcpy instead of strncpy (Bug#11373). diff --git a/src/buffer.c b/src/buffer.c index 9bac3ec742b..2ddbc699481 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -392,7 +392,6 @@ even if it is dead. The return value is never nil. */) BVAR (b, mark) = Fmake_marker (); BUF_MARKERS (b) = NULL; - BVAR (b, name) = name; /* Put this in the alist of all live buffers. */ XSETBUFFER (buffer, b); @@ -612,7 +611,6 @@ CLONE nil means the indirect buffer's state is reset to default values. */) Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil)); BVAR (b, mark) = Fmake_marker (); - BVAR (b, name) = name; /* The multibyte status belongs to the base buffer. */ BVAR (b, enable_multibyte_characters) = BVAR (b->base_buffer, enable_multibyte_characters); diff --git a/src/editfns.c b/src/editfns.c index a41565d8588..b52bc0c2a99 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -86,7 +86,7 @@ extern Lisp_Object w32_get_internal_run_time (void); static void time_overflow (void) NO_RETURN; static Lisp_Object format_time_string (char const *, ptrdiff_t, Lisp_Object, - int, time_t *, struct tm **); + int, time_t *, struct tm *); static int tm_diff (struct tm *, struct tm *); static void update_buffer_properties (EMACS_INT, EMACS_INT); @@ -1704,7 +1704,7 @@ usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal) { time_t t; - struct tm *tm; + struct tm tm; CHECK_STRING (format_string); format_string = code_convert_string_norecord (format_string, @@ -1715,54 +1715,55 @@ usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) static Lisp_Object format_time_string (char const *format, ptrdiff_t formatlen, - Lisp_Object timeval, int ut, time_t *tval, struct tm **tmp) + Lisp_Object timeval, int ut, time_t *tval, struct tm *tmp) { - ptrdiff_t size; + char buffer[4000]; + char *buf = buffer; + size_t size = sizeof buffer; + size_t len; + Lisp_Object bufstring; int usec; int ns; struct tm *tm; + USE_SAFE_ALLOCA; if (! (lisp_time_argument (timeval, tval, &usec) && 0 <= usec && usec < 1000000)) error ("Invalid time specification"); ns = usec * 1000; - /* This is probably enough. */ - size = formatlen; - if (size <= (STRING_BYTES_BOUND - 50) / 6) - size = size * 6 + 50; - - BLOCK_INPUT; - tm = ut ? gmtime (tval) : localtime (tval); - UNBLOCK_INPUT; - if (! tm) - time_overflow (); - *tmp = tm; - - synchronize_system_time_locale (); - while (1) { - char *buf = (char *) alloca (size + 1); - size_t result; + BLOCK_INPUT; + + synchronize_system_time_locale (); + + tm = ut ? gmtime (tval) : localtime (tval); + if (! tm) + { + UNBLOCK_INPUT; + time_overflow (); + } + *tmp = *tm; buf[0] = '\1'; - BLOCK_INPUT; - result = emacs_nmemftime (buf, size, format, formatlen, tm, ut, ns); - UNBLOCK_INPUT; - if ((result > 0 && result < size) || (result == 0 && buf[0] == '\0')) - return code_convert_string_norecord (make_unibyte_string (buf, result), - Vlocale_coding_system, 0); + len = emacs_nmemftime (buf, size, format, formatlen, tm, ut, ns); + if ((0 < len && len < size) || (len == 0 && buf[0] == '\0')) + break; - /* If buffer was too small, make it bigger and try again. */ - BLOCK_INPUT; - result = emacs_nmemftime (NULL, (size_t) -1, format, formatlen, - tm, ut, ns); + /* Buffer was too small, so make it bigger and try again. */ + len = emacs_nmemftime (NULL, SIZE_MAX, format, formatlen, tm, ut, ns); UNBLOCK_INPUT; - if (STRING_BYTES_BOUND <= result) + if (STRING_BYTES_BOUND <= len) string_overflow (); - size = result + 1; + size = len + 1; + SAFE_ALLOCA (buf, char *, size); } + + UNBLOCK_INPUT; + bufstring = make_unibyte_string (buf, len); + SAFE_FREE (); + return code_convert_string_norecord (bufstring, Vlocale_coding_system, 0); } DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 1, 0, @@ -1792,31 +1793,32 @@ DOW and ZONE.) */) BLOCK_INPUT; decoded_time = localtime (&time_spec); + /* Make a copy, in case a signal handler modifies TZ or the struct. */ + if (decoded_time) + save_tm = *decoded_time; UNBLOCK_INPUT; if (! (decoded_time - && MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= decoded_time->tm_year - && decoded_time->tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE)) + && MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= save_tm.tm_year + && save_tm.tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE)) time_overflow (); - XSETFASTINT (list_args[0], decoded_time->tm_sec); - XSETFASTINT (list_args[1], decoded_time->tm_min); - XSETFASTINT (list_args[2], decoded_time->tm_hour); - XSETFASTINT (list_args[3], decoded_time->tm_mday); - XSETFASTINT (list_args[4], decoded_time->tm_mon + 1); + XSETFASTINT (list_args[0], save_tm.tm_sec); + XSETFASTINT (list_args[1], save_tm.tm_min); + XSETFASTINT (list_args[2], save_tm.tm_hour); + XSETFASTINT (list_args[3], save_tm.tm_mday); + XSETFASTINT (list_args[4], save_tm.tm_mon + 1); /* On 64-bit machines an int is narrower than EMACS_INT, thus the cast below avoids overflow in int arithmetics. */ - XSETINT (list_args[5], TM_YEAR_BASE + (EMACS_INT) decoded_time->tm_year); - XSETFASTINT (list_args[6], decoded_time->tm_wday); - list_args[7] = (decoded_time->tm_isdst)? Qt : Qnil; + XSETINT (list_args[5], TM_YEAR_BASE + (EMACS_INT) save_tm.tm_year); + XSETFASTINT (list_args[6], save_tm.tm_wday); + list_args[7] = save_tm.tm_isdst ? Qt : Qnil; - /* Make a copy, in case gmtime modifies the struct. */ - save_tm = *decoded_time; BLOCK_INPUT; decoded_time = gmtime (&time_spec); - UNBLOCK_INPUT; if (decoded_time == 0) list_args[8] = Qnil; else XSETINT (list_args[8], tm_diff (&save_tm, decoded_time)); + UNBLOCK_INPUT; return Flist (9, list_args); } @@ -1898,21 +1900,23 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */) else error ("Invalid time zone specification"); + BLOCK_INPUT; + /* Set TZ before calling mktime; merely adjusting mktime's returned value doesn't suffice, since that would mishandle leap seconds. */ set_time_zone_rule (tzstring); - BLOCK_INPUT; value = mktime (&tm); - UNBLOCK_INPUT; /* Restore TZ to previous value. */ newenv = environ; environ = oldenv; - xfree (newenv); #ifdef LOCALTIME_CACHE tzset (); #endif + UNBLOCK_INPUT; + + xfree (newenv); } if (value == (time_t) -1) @@ -1939,24 +1943,29 @@ but this is considered obsolete. */) { time_t value; struct tm *tm; - register char *tem; + char *tem = NULL; + char buf[sizeof "Mon Apr 30 12:49:17 2012" - 1]; if (! lisp_time_argument (specified_time, &value, NULL)) error ("Invalid time specification"); /* Convert to a string, checking for out-of-range time stamps. + Omit the trailing newline. Don't use 'ctime', as that might dump core if VALUE is out of range. */ BLOCK_INPUT; tm = localtime (&value); + if (tm && TM_YEAR_IN_ASCTIME_RANGE (tm->tm_year)) + { + tem = asctime (tm); + if (tem) + memcpy (buf, tem, sizeof buf); + } UNBLOCK_INPUT; - if (! (tm && TM_YEAR_IN_ASCTIME_RANGE (tm->tm_year) && (tem = asctime (tm)))) + if (! tem) time_overflow (); - /* Remove the trailing newline. */ - tem[strlen (tem) - 1] = '\0'; - - return build_string (tem); + return make_unibyte_string (buf, sizeof buf); } /* Yield A - B, measured in seconds. @@ -2000,22 +2009,22 @@ the data it can't find. */) (Lisp_Object specified_time) { time_t value; + int offset; struct tm *t; struct tm localtm; - struct tm *localt; Lisp_Object zone_offset, zone_name; zone_offset = Qnil; zone_name = format_time_string ("%Z", sizeof "%Z" - 1, specified_time, - 0, &value, &localt); - localtm = *localt; + 0, &value, &localtm); BLOCK_INPUT; t = gmtime (&value); + if (t) + offset = tm_diff (&localtm, t); UNBLOCK_INPUT; if (t) { - int offset = tm_diff (&localtm, t); zone_offset = make_number (offset); if (SCHARS (zone_name) == 0) { @@ -2053,9 +2062,16 @@ 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. */ - if (!environbuf) + old_environbuf = environbuf; + if (!old_environbuf) initial_tz = (char *) getenv ("TZ"); if (NILP (tz)) @@ -2063,15 +2079,14 @@ only the former. */) else if (EQ (tz, Qt)) tzstring = "UTC0"; else - { - CHECK_STRING (tz); - tzstring = SSDATA (tz); - } + tzstring = SSDATA (tz); set_time_zone_rule (tzstring); - xfree (environbuf); environbuf = environ; + UNBLOCK_INPUT; + + xfree (old_environbuf); return Qnil; } diff --git a/src/intervals.c b/src/intervals.c index 88f47f58b52..a750ccd13f7 100644 --- a/src/intervals.c +++ b/src/intervals.c @@ -1000,6 +1000,7 @@ adjust_intervals_for_insertion (INTERVAL tree, Lisp_Object pleft, pright; struct interval newi; + RESET_INTERVAL (&newi); pleft = NULL_INTERVAL_P (prev) ? Qnil : prev->plist; pright = NULL_INTERVAL_P (i) ? Qnil : i->plist; newi.plist = merge_properties_sticky (pleft, pright);