From a1d23eb50565fe149ef2daf4c8404029a9ecaa74 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Wed, 13 Feb 2013 15:24:11 +0800 Subject: [PATCH 01/11] * xml.el (xml-parse-string): Fix typo in handling of bad character references. --- lisp/ChangeLog | 5 +++++ lisp/xml.el | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 580f9ea26be..5a80702af0d 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2013-02-13 Chong Yidong + + * xml.el (xml-parse-string): Fix typo in handling of bad character + references. + 2013-02-10 Michael Albinus * net/ange-ftp.el (ange-ftp-make-directory): Don't raise an error, diff --git a/lisp/xml.el b/lisp/xml.el index 2232746f02a..a3d34670bfb 100644 --- a/lisp/xml.el +++ b/lisp/xml.el @@ -611,7 +611,7 @@ references." xml-validating-parser (error "XML: (Validity) Invalid character reference `%s'" (match-string 0))) - (replace-match (or (string val) xml-undefined-entity) t t)) + (replace-match (if val (string val) xml-undefined-entity) t t)) ;; For an entity reference, search again from the start of ;; the replaced text, since the replacement can contain ;; entity or character references, or markup. @@ -620,7 +620,7 @@ references." (and (null val) xml-validating-parser (error "XML: (Validity) Undefined entity `%s'" ref)) - (replace-match (cdr val) t t) + (replace-match (or (cdr val) xml-undefined-entity) t t) (goto-char (match-beginning 0))) ;; Check for XML bombs. (and xml-entity-expansion-limit From 6e432f0cda1daa7bcee1fb5872dcfa130abe5018 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 13 Feb 2013 19:00:26 +0200 Subject: [PATCH 02/11] Cleanup related to bug #13546 with subprocesses on MS-Windows. src/w32.c (sys_pipe): When failing due to file descriptors above MAXDESC, set errno to EMFILE. (_sys_read_ahead): Update cp->status when failing to read serial communications input, so that the status doesn't stay at STATUS_READ_IN_PROGRESS. --- src/ChangeLog | 8 ++++++++ src/w32.c | 21 +++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 62d33e15ece..358f25b40f9 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2013-02-13 Eli Zaretskii + + * w32.c (sys_pipe): When failing due to file descriptors above + MAXDESC, set errno to EMFILE. + (_sys_read_ahead): Update cp->status when failing to read serial + communications input, so that the status doesn't stay at + STATUS_READ_IN_PROGRESS. (Bug#13546) + 2013-02-13 Glenn Morris * keyboard.c (input-decode-map, key-translation-map): Doc fixes. diff --git a/src/w32.c b/src/w32.c index 802403168f0..214fb7fdfae 100644 --- a/src/w32.c +++ b/src/w32.c @@ -6209,6 +6209,7 @@ sys_pipe (int * phandles) { _close (phandles[0]); _close (phandles[1]); + errno = EMFILE; rc = -1; } else @@ -6281,19 +6282,31 @@ _sys_read_ahead (int fd) /* Configure timeouts for blocking read. */ if (!GetCommTimeouts (hnd, &ct)) - return STATUS_READ_ERROR; + { + cp->status = STATUS_READ_ERROR; + return STATUS_READ_ERROR; + } ct.ReadIntervalTimeout = 0; ct.ReadTotalTimeoutMultiplier = 0; ct.ReadTotalTimeoutConstant = 0; if (!SetCommTimeouts (hnd, &ct)) - return STATUS_READ_ERROR; + { + cp->status = STATUS_READ_ERROR; + return STATUS_READ_ERROR; + } if (!ReadFile (hnd, &cp->chr, sizeof (char), (DWORD*) &rc, ovl)) { if (GetLastError () != ERROR_IO_PENDING) - return STATUS_READ_ERROR; + { + cp->status = STATUS_READ_ERROR; + return STATUS_READ_ERROR; + } if (!GetOverlappedResult (hnd, ovl, (DWORD*) &rc, TRUE)) - return STATUS_READ_ERROR; + { + cp->status = STATUS_READ_ERROR; + return STATUS_READ_ERROR; + } } } else if (fd_info[fd].flags & FILE_SOCKET) From 0e4e7b741b515be091e2ec3b3ff63f1b16084555 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 13 Feb 2013 19:04:30 +0200 Subject: [PATCH 03/11] More robust creation of a subprocess, attempt to solve bug #13546. src/w32proc.c (new_child): If no vacant slots are found in child_procs[], make another pass looking for slots whose process has exited or died. --- src/ChangeLog | 4 ++++ src/w32proc.c | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/ChangeLog b/src/ChangeLog index 358f25b40f9..e1b8a23e6b2 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,9 @@ 2013-02-13 Eli Zaretskii + * w32proc.c (new_child): If no vacant slots are found in + child_procs[], make another pass looking for slots whose process + has exited or died. (Bug#13546) + * w32.c (sys_pipe): When failing due to file descriptors above MAXDESC, set errno to EMFILE. (_sys_read_ahead): Update cp->status when failing to read serial diff --git a/src/w32proc.c b/src/w32proc.c index 8c09a1b1beb..1e72d41e16b 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -797,6 +797,33 @@ new_child (void) for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess == NULL) goto Initialize; + if (child_proc_count == MAX_CHILDREN) + { + DebPrint (("new_child: No vacant slots, looking for dead processes\n")); + for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) + if (!CHILD_ACTIVE (cp) && cp->procinfo.hProcess) + { + DWORD status = 0; + + if (!GetExitCodeProcess (cp->procinfo.hProcess, &status)) + { + DebPrint (("new_child.GetExitCodeProcess: error %lu for PID %lu\n", + GetLastError (), cp->procinfo.dwProcessId)); + status = STILL_ACTIVE; + } + if (status != STILL_ACTIVE + || WaitForSingleObject (cp->procinfo.hProcess, 0) == WAIT_OBJECT_0) + { + DebPrint (("new_child: Freeing slot of dead process %d\n", + cp->procinfo.dwProcessId)); + CloseHandle (cp->procinfo.hProcess); + cp->procinfo.hProcess = NULL; + CloseHandle (cp->procinfo.hThread); + cp->procinfo.hThread = NULL; + goto Initialize; + } + } + } if (child_proc_count == MAX_CHILDREN) return NULL; cp = &child_procs[child_proc_count++]; From dcbec5e2e6799049a0b3535986f4674d452970a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A1n=20Ezequiel=20Gallina?= Date: Wed, 13 Feb 2013 20:07:59 -0300 Subject: [PATCH 04/11] * progmodes/python.el (python-info-current-defun): Fix current defun detection. Fixes: debbugs:13618 --- lisp/progmodes/python.el | 87 +++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 33 deletions(-) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 2a7a3765ac2..e611864e0c1 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -2936,40 +2936,61 @@ Optional argument INCLUDE-TYPE indicates to include the type of the defun. This function is compatible to be used as `add-log-current-defun-function' since it returns nil if point is not inside a defun." - (save-restriction - (widen) - (save-excursion - (end-of-line 1) - (let ((names) - (starting-indentation - (save-excursion - (and - (python-nav-beginning-of-defun 1) - ;; This extra number is just for checking code - ;; against indentation to work well on first run. - (+ (current-indentation) 4)))) - (starting-point (point))) - ;; Check point is inside a defun. - (when (and starting-indentation - (< starting-point + (save-restriction + (widen) + (save-excursion + (end-of-line 1) + (let ((names) + (starting-indentation (current-indentation)) + (starting-pos (point)) + (first-run t) + (last-indent) + (type)) + (catch 'exit + (while (python-nav-beginning-of-defun 1) + (when (and + (or (not last-indent) + (< (current-indentation) last-indent)) + (or + (and first-run (save-excursion - (python-nav-end-of-defun) - (point)))) - (catch 'exit - (while (python-nav-beginning-of-defun 1) - (when (< (current-indentation) starting-indentation) - (setq starting-indentation (current-indentation)) - (setq names - (cons - (if (not include-type) - (match-string-no-properties 1) - (mapconcat 'identity - (split-string - (match-string-no-properties 0)) " ")) - names))) - (and (= (current-indentation) 0) (throw 'exit t))))) - (and names - (mapconcat (lambda (string) string) names ".")))))) + ;; If this is the first run, we may add + ;; the current defun at point. + (setq first-run nil) + (goto-char starting-pos) + (python-nav-beginning-of-statement) + (beginning-of-line 1) + (looking-at-p + python-nav-beginning-of-defun-regexp))) + (< starting-pos + (save-excursion + (let ((min-indent + (+ (current-indentation) + python-indent-offset))) + (if (< starting-indentation min-indent) + ;; If the starting indentation is not + ;; within the min defun indent make the + ;; check fail. + starting-pos + ;; Else go to the end of defun and add + ;; up the current indentation to the + ;; ending position. + (python-nav-end-of-defun) + (+ (point) + (if (>= (current-indentation) min-indent) + (1+ (current-indentation)) + 0)))))))) + (setq last-indent (current-indentation)) + (if (or (not include-type) type) + (setq names (cons (match-string-no-properties 1) names)) + (let ((match (split-string (match-string-no-properties 0)))) + (setq type (car match)) + (setq names (cons (cadr match) names))))) + ;; Stop searching ASAP. + (and (= (current-indentation) 0) (throw 'exit t)))) + (and names + (concat (and type (format "%s " type)) + (mapconcat 'identity names "."))))))) (defun python-info-current-symbol (&optional replace-self) "Return current symbol using dotty syntax. From 5cd3d1e56e3e6c7dfefc77bc78280173d4bc32d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A1n=20Ezequiel=20Gallina?= Date: Wed, 13 Feb 2013 20:09:12 -0300 Subject: [PATCH 05/11] Push ChangeLog entry for previous commit. --- lisp/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 5a80702af0d..4fbb07b9d3e 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2013-02-13 Fabián Ezequiel Gallina + + * progmodes/python.el (python-info-current-defun): Fix current + defun detection (Bug#13618). + 2013-02-13 Chong Yidong * xml.el (xml-parse-string): Fix typo in handling of bad character From ea5f4192b9954301c0c65804586ed7daf3a98c16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A1n=20Ezequiel=20Gallina?= Date: Wed, 13 Feb 2013 21:42:11 -0300 Subject: [PATCH 06/11] * progmodes/python.el: Explain how to restore "cc-mode"-like forward-sexp movement in header documentation. (python-nav--forward-sexp): Behave like emacs-lisp-mode in comments and strings (GH bug 114). Fixes: debbugs:13642 --- lisp/ChangeLog | 7 +++++++ lisp/progmodes/python.el | 42 +++++++++++++++++++++------------------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 4fbb07b9d3e..a8fd8c87c5b 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,10 @@ +2013-02-14 Fabián Ezequiel Gallina + + * progmodes/python.el: Explain how to restore "cc-mode"-like + forward-sexp movement in header documentation (Bug#13642). + (python-nav--forward-sexp): Behave like emacs-lisp-mode in + comments and strings (GH bug 114). + 2013-02-13 Fabián Ezequiel Gallina * progmodes/python.el (python-info-current-defun): Fix current diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index e611864e0c1..92f86ce1231 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -54,8 +54,13 @@ ;; `python-nav-beginning-of-statement', `python-nav-end-of-statement', ;; `python-nav-beginning-of-block' and `python-nav-end-of-block' are ;; included but no bound to any key. At last but not least the -;; specialized `python-nav-forward-sexp' allows easy -;; navigation between code blocks. +;; specialized `python-nav-forward-sexp' allows easy navigation +;; between code blocks. If you prefer `cc-mode'-like `forward-sexp' +;; movement, setting `forward-sexp-function' to nil is enough, You can +;; do that using the `python-mode-hook': + +;; (add-hook 'python-mode-hook +;; (lambda () (setq forward-sexp-function nil))) ;; Shell interaction: is provided and allows you to execute easily any ;; block of code of your current buffer in an inferior Python process. @@ -1339,13 +1344,10 @@ backwards." 're-search-backward)) (context-type (python-syntax-context-type))) (cond - ((eq context-type 'string) + ((memq context-type '(string comment)) ;; Inside of a string, get out of it. - (while (and (funcall re-search-fn "[\"']" nil t) - (python-syntax-context 'string)))) - ((eq context-type 'comment) - ;; Inside of a comment, just move forward. - (python-util-forward-comment dir)) + (let ((forward-sexp-function)) + (forward-sexp dir))) ((or (eq context-type 'paren) (and forward-p (looking-at (python-rx open-paren))) (and (not forward-p) @@ -1368,16 +1370,16 @@ backwards." (save-excursion (python-nav-lisp-forward-sexp-safe dir) (point))) - (next-sexp-context - (save-excursion - (goto-char next-sexp-pos) - (cond - ((python-info-beginning-of-block-p) 'block-start) - ((python-info-end-of-block-p) 'block-end) - ((python-info-beginning-of-statement-p) 'statement-start) - ((python-info-end-of-statement-p) 'statement-end) - ((python-info-statement-starts-block-p) 'starts-block) - ((python-info-statement-ends-block-p) 'ends-block))))) + (next-sexp-context + (save-excursion + (goto-char next-sexp-pos) + (cond + ((python-info-beginning-of-block-p) 'block-start) + ((python-info-end-of-block-p) 'block-end) + ((python-info-beginning-of-statement-p) 'statement-start) + ((python-info-end-of-statement-p) 'statement-end) + ((python-info-statement-starts-block-p) 'starts-block) + ((python-info-statement-ends-block-p) 'ends-block))))) (if forward-p (cond ((and (not (eobp)) (python-info-current-line-empty-p)) @@ -1401,8 +1403,8 @@ backwards." (t (goto-char next-sexp-pos))) (cond ((and (not (bobp)) (python-info-current-line-empty-p)) - (python-util-forward-comment dir) - (python-nav--forward-sexp dir)) + (python-util-forward-comment dir) + (python-nav--forward-sexp dir)) ((eq context 'block-end) (python-nav-beginning-of-block)) ((eq context 'statement-end) From df1af142da9a6800a9c7ffef62f38464613664df Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Wed, 13 Feb 2013 20:24:03 -0500 Subject: [PATCH 07/11] * lispref/modes.texi (Basic Major Modes): 'z' no longer bound in special-mode. --- doc/lispref/ChangeLog | 4 ++++ doc/lispref/modes.texi | 5 ++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index 79ba145c5f3..65e23a82847 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,3 +1,7 @@ +2013-02-14 Glenn Morris + + * modes.texi (Basic Major Modes): 'z' no longer bound in special-mode. + 2013-02-13 Glenn Morris * objects.texi (Char-Table Type): Add footnote about #^^. diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 425bb58b651..7093f7fe336 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -905,9 +905,8 @@ modes derived from Special mode are given a @code{mode-class} property of @code{special} (@pxref{Major Mode Conventions}). Special mode sets the buffer to read-only. Its keymap defines several -common bindings, including @kbd{q} for @code{quit-window}, @kbd{z} for -@code{kill-this-buffer}, and @kbd{g} for @code{revert-buffer} -(@pxref{Reverting}). +common bindings, including @kbd{q} for @code{quit-window} and @kbd{g} +for @code{revert-buffer} (@pxref{Reverting}). An example of a major mode derived from Special mode is Buffer Menu mode, which is used by the @file{*Buffer List*} buffer. @xref{List From 213ac1686cc1557a77c6fb38619f7f6d6076051a Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Thu, 14 Feb 2013 10:53:46 -0500 Subject: [PATCH 08/11] * lisp/net/goto-addr.el (goto-address-fontify): Add start and end args. (goto-address-fontify-region): Use them instead of narrowing, so syntax-ppss has access to the whole buffer. --- lisp/ChangeLog | 6 ++++++ lisp/net/goto-addr.el | 23 +++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index a8fd8c87c5b..5bd02f933de 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,9 @@ +2013-02-14 Stefan Monnier + + * net/goto-addr.el (goto-address-fontify): Add start and end args. + (goto-address-fontify-region): Use them instead of narrowing, so + syntax-ppss has access to the whole buffer. + 2013-02-14 Fabián Ezequiel Gallina * progmodes/python.el: Explain how to restore "cc-mode"-like diff --git a/lisp/net/goto-addr.el b/lisp/net/goto-addr.el index 1005285917e..59e4da16619 100644 --- a/lisp/net/goto-addr.el +++ b/lisp/net/goto-addr.el @@ -156,18 +156,19 @@ A value of t means there is no limit--fontify regardless of the size." (defvar goto-address-prog-mode) -(defun goto-address-fontify () +(defun goto-address-fontify (&optional start end) "Fontify the URLs and e-mail addresses in the current buffer. This function implements `goto-address-highlight-p' and `goto-address-fontify-p'." ;; Clean up from any previous go. - (goto-address-unfontify (point-min) (point-max)) + (goto-address-unfontify (or start (point-min)) (or end (point-max))) (save-excursion (let ((inhibit-point-motion-hooks t)) - (goto-char (point-min)) + (goto-char (or start (point-min))) (when (or (eq t goto-address-fontify-maximum-size) - (< (- (point-max) (point)) goto-address-fontify-maximum-size)) - (while (re-search-forward goto-address-url-regexp nil t) + (< (- (or end (point-max)) (point)) + goto-address-fontify-maximum-size)) + (while (re-search-forward goto-address-url-regexp end t) (let* ((s (match-beginning 0)) (e (match-end 0)) this-overlay) @@ -187,8 +188,8 @@ and `goto-address-fontify-p'." (overlay-put this-overlay 'keymap goto-address-highlight-keymap) (overlay-put this-overlay 'goto-address t)))) - (goto-char (point-min)) - (while (re-search-forward goto-address-mail-regexp nil t) + (goto-char (or start (point-min))) + (while (re-search-forward goto-address-mail-regexp end t) (let* ((s (match-beginning 0)) (e (match-end 0)) this-overlay) @@ -212,11 +213,9 @@ and `goto-address-fontify-p'." (defun goto-address-fontify-region (start end) "Fontify URLs and e-mail addresses in the given region." (save-excursion - (save-restriction - (let ((beg-line (progn (goto-char start) (line-beginning-position))) - (end-line (progn (goto-char end) (line-end-position)))) - (narrow-to-region beg-line end-line) - (goto-address-fontify))))) + (let ((beg-line (progn (goto-char start) (line-beginning-position))) + (end-line (progn (goto-char end) (line-end-position)))) + (goto-address-fontify beg-line end-line)))) ;; code to find and goto addresses; much of this has been blatantly ;; snarfed from browse-url.el From 9e16c3b44bcf407678563f0bd679c0887ec3011c Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Thu, 14 Feb 2013 09:16:47 -0800 Subject: [PATCH 09/11] * emacs-lisp/easy-mmode.el (define-minor-mode): Doc fix re setf. --- lisp/ChangeLog | 4 ++++ lisp/emacs-lisp/easy-mmode.el | 15 ++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 5bd02f933de..4a328a749bc 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,7 @@ +2013-02-14 Glenn Morris + + * emacs-lisp/easy-mmode.el (define-minor-mode): Doc fix. + 2013-02-14 Stefan Monnier * net/goto-addr.el (goto-address-fontify): Add start and end args. diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 9173d148c6a..166c093f37b 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -132,13 +132,14 @@ BODY contains code to execute each time the mode is enabled or disabled. :require SYM Same as in `defcustom'. :variable PLACE The location to use instead of the variable MODE to store the state of the mode. This can be simply a different - named variable, or more generally anything that can be used - with the CL macro `setf'. PLACE can also be of the form - \(GET . SET), where GET is an expression that returns the - current state, and SET is a function that takes one argument, - the new state, and sets it. If you specify a :variable, - this function does not define a MODE variable (nor any of - the terms used in :variable). + named variable, or a generalized variable. + PLACE can also be of the form \(GET . SET), where GET is + an expression that returns the current state, and SET is + a function that takes one argument, the new state, and + sets it. If you specify a :variable, this function does + not define a MODE variable (nor any of the terms used + in :variable). + :after-hook A single lisp form which is evaluated after the mode hooks have been run. It should not be quoted. From 35b3a27e67b60e547ac8bc9388e7724d1f829959 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 14 Feb 2013 12:05:10 -0800 Subject: [PATCH 10/11] Fix AIX port. * configure.ac (DATA_START, DATA_SEG_BITS): Set to 0x20000000 on AIX. (GC_MARK_STACK): Do not set to GC_USE_GCPROS_AS_BEFORE, as that runs afoul of some other bug in Emacs, and the default value GC_MAKE_GCPROS_NOOPS has been tested and works. * src/lisp.h (XPNTR) [!USE_LSB_TAG && DATA_SEG_BITS]: Fix bug introduced in 2012-07-27 change. DATA_SEG_BITS, if set, was #undeffed earlier, so it cannot be used as a macro here. Use the constant and not the macro. Tested on AIX. * src/unexaix.c: Revert 2013-02-11 and 2013-02-12 changes to this file. They're almost surely OK but we're just before a release so we should avoid changes unless they're clearly needed. Instead, make the following minor change: (ADDR_CORRECT): New macro. Fixes: debbugs:13650 --- ChangeLog | 8 +++++ configure.ac | 7 +++- src/ChangeLog | 13 +++++++ src/lisp.h | 4 --- src/unexaix.c | 96 +++++++++++++++++++++++++++------------------------ 5 files changed, 78 insertions(+), 50 deletions(-) diff --git a/ChangeLog b/ChangeLog index cddaaa58a5f..6bd8f213c17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2013-02-14 Paul Eggert + + Fix AIX port (Bug#13650). + * configure.ac (DATA_START, DATA_SEG_BITS): Set to 0x20000000 on AIX. + (GC_MARK_STACK): Do not set to GC_USE_GCPROS_AS_BEFORE on AIX, as that + runs afoul of some other bug in Emacs, and the default value + GC_MAKE_GCPROS_NOOPS has been tested and works. + 2013-01-16 Glenn Morris * Makefile.in (install-arch-indep): Put back a chmod that was diff --git a/configure.ac b/configure.ac index c163ecee3fe..7f6defa7059 100644 --- a/configure.ac +++ b/configure.ac @@ -3764,6 +3764,11 @@ case $opsys in AC_DEFINE(DATA_START, [({ extern int data_start; (char *) &data_start; })]) ;; + aix*) + dnl This works with 32-bit executables; Emacs doesn't support 64-bit. + AC_DEFINE(DATA_START, [0x20000000]) + AC_DEFINE(DATA_SEG_BITS, [0x20000000]) + ;; hpux*) dnl The data segment on this machine always starts at address 0x40000000. AC_DEFINE(DATA_START, [0x40000000]) @@ -3827,7 +3832,7 @@ AH_TEMPLATE(GC_MARK_STACK, [Define to GC_USE_GCPROS_AS_BEFORE if case $opsys in - aix4-2 | hpux* | unixware) + hpux* | unixware) dnl Conservative garbage collection has not been tested, so for now dnl play it safe and stick with the old-fashioned way of marking. AC_DEFINE(GC_MARK_STACK, [GC_USE_GCPROS_AS_BEFORE]) diff --git a/src/ChangeLog b/src/ChangeLog index e1b8a23e6b2..e283d2bb48c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2013-02-14 Paul Eggert + + Fix AIX port (Bug#13650). + * lisp.h (XPNTR) [!USE_LSB_TAG && DATA_SEG_BITS]: + Fix bug introduced in 2012-07-27 change. DATA_SEG_BITS, if set, + was #undeffed earlier, so it cannot be used as a macro here. + Use the constant and not the macro. + * unexaix.c: Revert 2013-02-11 and 2013-02-12 changes to this + file. They're almost surely OK but we're just before a release so + we should avoid changes unless they're clearly needed. Instead, + make the following minor change: + (ADDR_CORRECT): New macro. + 2013-02-13 Eli Zaretskii * w32proc.c (new_child): If no vacant slots are found in diff --git a/src/lisp.h b/src/lisp.h index a62842c117a..eca3caefd8c 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -496,13 +496,9 @@ static EMACS_INT const VALMASK (XIL ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \ + ((intptr_t) (ptr) & VALMASK))) -#if DATA_SEG_BITS /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers which were stored in a Lisp_Object. */ #define XPNTR(a) ((uintptr_t) ((XLI (a) & VALMASK)) | DATA_SEG_BITS)) -#else -#define XPNTR(a) ((uintptr_t) (XLI (a) & VALMASK)) -#endif #endif /* not USE_LSB_TAG */ diff --git a/src/unexaix.c b/src/unexaix.c index da44480fdca..885d7a9f6d7 100644 --- a/src/unexaix.c +++ b/src/unexaix.c @@ -51,8 +51,6 @@ what you give them. Help stamp out software-hoarding! */ #include "getpagesize.h" #include -#include -#include #include #include #include @@ -61,8 +59,10 @@ what you give them. Help stamp out software-hoarding! */ #include "mem-limits.h" -extern char _data[]; -extern char _text[]; +char *start_of_text (void); /* Start of text */ + +extern int _data; +extern int _text; #include #include @@ -71,15 +71,15 @@ extern char _text[]; static struct filehdr f_hdr; /* File header */ static struct aouthdr f_ohdr; /* Optional file header (a.out) */ -static off_t bias; /* Bias to add for growth */ -static off_t lnnoptr; /* Pointer to line-number info within file */ +static long bias; /* Bias to add for growth */ +static long lnnoptr; /* Pointer to line-number info within file */ -static off_t text_scnptr; -static off_t data_scnptr; +static long text_scnptr; +static long data_scnptr; #define ALIGN(val, pwr) (((val) + ((1L<<(pwr))-1)) & ~((1L<<(pwr))-1)) -static off_t load_scnptr; -static off_t orig_load_scnptr; -static off_t orig_data_scnptr; +static long load_scnptr; +static long orig_load_scnptr; +static long orig_data_scnptr; static int unrelocate_symbols (int, int, const char *, const char *); #ifndef MAX_SECTIONS @@ -92,30 +92,26 @@ static int pagemask; #include "lisp.h" -static _Noreturn void +static void report_error (const char *file, int fd) { if (fd) - { - int failed_errno = errno; - close (fd); - errno = failed_errno; - } + close (fd); report_file_error ("Cannot unexec", Fcons (build_string (file), Qnil)); } -#define ERROR0(msg) report_error_1 (new, msg) -#define ERROR1(msg,x) report_error_1 (new, msg, x) -#define ERROR2(msg,x,y) report_error_1 (new, msg, x, y) +#define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1 +#define ERROR1(msg,x) report_error_1 (new, msg, x, 0); return -1 +#define ERROR2(msg,x,y) report_error_1 (new, msg, x, y); return -1 -static _Noreturn void ATTRIBUTE_FORMAT_PRINTF (2, 3) -report_error_1 (int fd, const char *msg, ...) +#undef ADDR_CORRECT +#define ADDR_CORRECT(x) ((int)(x)) + +static void +report_error_1 (int fd, const char *msg, int a1, int a2) { - va_list ap; close (fd); - va_start (ap, msg); - verror (msg, ap); - va_end (ap); + error (msg, a1, a2); } static int make_hdr (int, int, const char *, const char *); @@ -170,8 +166,8 @@ make_hdr (int new, int a_out, const char *a_name, const char *new_name) { int scns; - uintptr_t bss_start; - uintptr_t data_start; + unsigned int bss_start; + unsigned int data_start; struct scnhdr section[MAX_SECTIONS]; struct scnhdr * f_thdr; /* Text section header */ @@ -186,17 +182,17 @@ make_hdr (int new, int a_out, pagemask = getpagesize () - 1; /* Adjust text/data boundary. */ - data_start = (uintptr_t) _data; + data_start = (long) start_of_data (); + data_start = ADDR_CORRECT (data_start); data_start = data_start & ~pagemask; /* (Down) to page boundary. */ - bss_start = (uintptr_t) sbrk (0) + pagemask; + bss_start = ADDR_CORRECT (sbrk (0)) + pagemask; bss_start &= ~ pagemask; if (data_start > bss_start) /* Can't have negative data size. */ { - ERROR2 (("unexec: data_start (0x%"PRIxPTR - ") can't be greater than bss_start (0x%"PRIxPTR")"), + ERROR2 ("unexec: data_start (%u) can't be greater than bss_start (%u)", data_start, bss_start); } @@ -286,7 +282,7 @@ make_hdr (int new, int a_out, /* fix scnptr's */ { - off_t ptr = section[0].s_scnptr; + ulong ptr = section[0].s_scnptr; bias = -1; for (scns = 0; scns < f_hdr.f_nscns; scns++) @@ -382,12 +378,12 @@ copy_text_and_data (int new) char *end; char *ptr; - lseek (new, text_scnptr, SEEK_SET); - ptr = _text + text_scnptr; + lseek (new, (long) text_scnptr, SEEK_SET); + ptr = start_of_text () + text_scnptr; end = ptr + f_ohdr.tsize; write_segment (new, ptr, end); - lseek (new, data_scnptr, SEEK_SET); + lseek (new, (long) data_scnptr, SEEK_SET); ptr = (char *) f_ohdr.data_start; end = ptr + f_ohdr.dsize; write_segment (new, ptr, end); @@ -400,6 +396,7 @@ static void write_segment (int new, char *ptr, char *end) { int i, nwrite, ret; + char buf[80]; char zeros[UnexBlockSz]; for (i = 0; ptr < end;) @@ -420,13 +417,9 @@ write_segment (int new, char *ptr, char *end) } else if (nwrite != ret) { - int write_errno = errno; - char buf[1000]; - void *addr = ptr; sprintf (buf, - "unexec write failure: addr %p, fileno %d, size 0x%x, wrote 0x%x, errno %d", - addr, new, nwrite, ret, errno); - errno = write_errno; + "unexec write failure: addr 0x%lx, fileno %d, size 0x%x, wrote 0x%x, errno %d", + (unsigned long)ptr, new, nwrite, ret, errno); PERROR (buf); } i += nwrite; @@ -547,13 +540,13 @@ unrelocate_symbols (int new, int a_out, int i; LDHDR ldhdr; LDREL ldrel; - off_t t_reloc = (intptr_t) _text - f_ohdr.text_start; + ulong t_reloc = (ulong) &_text - f_ohdr.text_start; #ifndef ALIGN_DATA_RELOC - off_t d_reloc = (intptr_t) _data - f_ohdr.data_start; + ulong d_reloc = (ulong) &_data - f_ohdr.data_start; #else /* This worked (and was needed) before AIX 4.2. I have no idea why. -- Mike */ - off_t d_reloc = (intptr_t) _data - ALIGN (f_ohdr.data_start, 2); + ulong d_reloc = (ulong) &_data - ALIGN (f_ohdr.data_start, 2); #endif int * p; @@ -638,3 +631,16 @@ unrelocate_symbols (int new, int a_out, } return 0; } + +/* + * Return the address of the start of the text segment prior to + * doing an unexec. After unexec the return value is undefined. + * See crt0.c for further explanation and _start. + * + */ + +char * +start_of_text (void) +{ + return ((char *) 0x10000000); +} From 974c7646ec5b2985a50007c9d599154d667df349 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 14 Feb 2013 14:08:38 -0800 Subject: [PATCH 11/11] Backport GCPRO fix from trunk. The bug was reported for AIX before today's changes. I reproduced the problem on Fedora 17 x86-64 when setting GC_MARK_STACK by hand, and I presume it occurs with default configurations on HP-UX and Unixware. Trunk fix on 2013-01-14 by Dmitry Antipov : Fix compilation with GC_MARK_STACK == GC_USE_GCPROS_AS_BEFORE. * eval.c (eval_sub): Protect `form' from being GCed before its car and cdr becomes protected with the backtrace entry. Fixes: debbugs:13650 --- src/ChangeLog | 10 ++++++++++ src/eval.c | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/ChangeLog b/src/ChangeLog index e283d2bb48c..46a466d060d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,15 @@ 2013-02-14 Paul Eggert + Backport GCPRO fix from trunk (Bug#13650). + The bug was reported for AIX before today's changes. + I reproduced the problem on Fedora 17 x86-64 when setting + GC_MARK_STACK by hand, and I presume it occurs with default + configurations on HP-UX and Unixware. + Trunk fix on 2013-01-14 by Dmitry Antipov : + Fix compilation with GC_MARK_STACK == GC_USE_GCPROS_AS_BEFORE. + * eval.c (eval_sub): Protect `form' from being GCed before its + car and cdr becomes protected with the backtrace entry. + Fix AIX port (Bug#13650). * lisp.h (XPNTR) [!USE_LSB_TAG && DATA_SEG_BITS]: Fix bug introduced in 2012-07-27 change. DATA_SEG_BITS, if set, diff --git a/src/eval.c b/src/eval.c index a0db6e0745c..a21b2b05762 100644 --- a/src/eval.c +++ b/src/eval.c @@ -2034,7 +2034,10 @@ eval_sub (Lisp_Object form) return form; QUIT; + + GCPRO1 (form); maybe_gc (); + UNGCPRO; if (++lisp_eval_depth > max_lisp_eval_depth) {