From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Nicolas Graner Newsgroups: gmane.emacs.bugs Subject: bug#59804: shell-resync-dirs hangs in (t)csh Date: Sun, 04 Dec 2022 19:41:24 +0100 Message-ID: <87y1rnggff.fsf@graner.name> References: <87r0xghg60.fsf@graner.name> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="1346"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 59804@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sun Dec 04 19:42:24 2022 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1p1twW-0000BI-Bi for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 04 Dec 2022 19:42:24 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p1twG-0006Ca-C8; Sun, 04 Dec 2022 13:42:11 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p1twA-0006CI-Go for bug-gnu-emacs@gnu.org; Sun, 04 Dec 2022 13:42:02 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1p1twA-0002vm-87 for bug-gnu-emacs@gnu.org; Sun, 04 Dec 2022 13:42:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1p1tw9-0007US-Ne for bug-gnu-emacs@gnu.org; Sun, 04 Dec 2022 13:42:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Nicolas Graner Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 04 Dec 2022 18:42:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 59804 X-GNU-PR-Package: emacs Original-Received: via spool by 59804-submit@debbugs.gnu.org id=B59804.167017929628781 (code B ref 59804); Sun, 04 Dec 2022 18:42:01 +0000 Original-Received: (at 59804) by debbugs.gnu.org; 4 Dec 2022 18:41:36 +0000 Original-Received: from localhost ([127.0.0.1]:59134 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1p1tvk-0007U9-2l for submit@debbugs.gnu.org; Sun, 04 Dec 2022 13:41:36 -0500 Original-Received: from ouvsmtp1.octopuce.fr ([194.36.166.50]:41778) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1p1tvf-0007U3-9a for 59804@debbugs.gnu.org; Sun, 04 Dec 2022 13:41:35 -0500 Original-Received: from panel.vitry.ouvaton.coop (unknown [194.36.166.20]) by ouvsmtp1.octopuce.fr (Postfix) with ESMTPS id 93570F4F; Sun, 4 Dec 2022 19:41:29 +0100 (CET) Original-Received: from hypra-graner (95.106.204.77.rev.sfr.net [77.204.106.95]) by panel.vitry.ouvaton.coop (Postfix) with ESMTPSA id 12DF25E28E2; Sun, 4 Dec 2022 19:41:29 +0100 (CET) In-Reply-To: <83r0xfbn21.fsf@gnu.org> (message from Eli Zaretskii on Sun, 04 Dec 2022 10:17:10 +0200) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:249960 Archived-At: Eli Zaretskii wrote on 2022-12-04 10:17: >> From: Nicolas Graner >> Date: Sat, 03 Dec 2022 12:37:11 +0100 >> >> In a shell buffer where the running shell is csh or tcsh, the command >> shell-resync-dirs never returns. >> >> You can test this even without changing your normal shell by typing >> `csh' in any shell buffer, then M- >> Emacs hangs until you quit with C-g. >> >> The reason is that the `dirs' command in (t)csh (unlike its equivalent >> in bash) adds a trailing space to its output. This triggers an infinite >> loop. >> >> As evidence that the trailing space is the culprit, note that this >> kludge, whiche removes it, fixes the problem: >> >> (setq shell-dirstack-query "dirs | sed 's/ $//'") > > Thanks for the analysis. Does the patch below fix this problem? If not, > could you point out more precisely where the command infloops and why? > > diff --git a/lisp/shell.el b/lisp/shell.el > index b396bc2..dadbdcb 100644 > --- a/lisp/shell.el > +++ b/lisp/shell.el > @@ -1162,6 +1162,7 @@ shell-resync-dirs > (dlsl nil) > (pos 0) > (ds nil)) > + (setq dls (string-trim-right dls "[ ]+")) > ;; Split the dirlist into whitespace and non-whitespace chunks. > ;; dlsl will be a reversed list of tokens. > (while (string-match "\\(\\S-+\\|\\s-+\\)" dls pos) It works in most situations, but not if a directory name actually ends with a space. Upon further investigation, I found there are two distinct issues here. 1) When the dirs command prints "foo ", there is no way to tell if the directory is named "foo" and the shell (e.g. csh) added a trailing space, or the directory is named "foo " and the shell (e.g. bash) printed it unchanged. There may even be more than one trailing space. The only clean solution I can think of is to introduce a new shell-dependent variable, similar to shell-dirstack-query, say shell-dirstack-query-suffix, which would be " " for csh and tcsh, and "" for most other shells. Your patch above would become: (setq dls (string-trim-right dls shell-dirstack-query-suffix)) 2) the loop that goes wild, later in the same function, starts with: (while newelt It tries to construct an existing directory name by concatenating tokens from the output of dirs, starting from the last. It runs indefinitely if this doesn't yield a valid directory name. This can happen for several reasons: an extra space at the end as discussed above, a non-printable character in a directory name, a directory that was deleted after being pushed onto the dirstack, and maybe more. This can happen in any shell, not just csh. This loop should therefore be fixed, regardless of the trailing space issue. The following patch fixes the bug by ensuring the loop terminates in all cases, but I am not sure it always does the right thing when no directory name is found. It should be reviewed by someone who understands the code better than me. diff --git a/lisp/shell.el b/lisp/shell.el index b396bc2b180..abeaba04ab4 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -1173,7 +1173,7 @@ shell-resync-dirs (while dlsl (let ((newelt "") tem1 tem2) - (while newelt + (while (and newelt dlsl) ;; We need tem1 because we don't want to prepend ;; `comint-file-name-prefix' repeatedly into newelt via tem2. (setq tem1 (pop dlsl)