Subject: bug#23206: closed (Re: bug#23206: 25.0.92; dired-shell-stuff-it: wait until all parallel jobs finish)

From: [email-masked] (GNU bug Tracking System)
Date: Fri, 08 Apr 2016 14:08:01 +0000

Your bug report

#23206: 25.0.92; dired-shell-stuff-it: wait until all parallel jobs finish

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
23206: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=23206
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#23206: 25.0.92; dired-shell-stuff-it: wait until all parallel jobs finish
From: Eli Zaretskii <[email-masked]>
To: Tino Calancha <[email-masked]>
Cc: [email-masked]
Date: Fri, 08 Apr 2016 17:06:44 +0300
List-Id: <debbugs-submit.debbugs.gnu.org>

> Date: Wed, 6 Apr 2016 00:58:30 +0900 (JST)
> From: Tino Calancha <[email-masked]>
> cc: Tino Calancha <[email-masked]>, [email-masked]
> 
> Attached atomic commits without the extra care.

Thanks, pushed to the master branch.

Subject: 25.0.92; dired-shell-stuff-it: wait until all parallel jobs finish
From: Tino Calancha <[email-masked]>
To: [email-masked]
Date: Sun, 3 Apr 2016 22:02:17 +0900 (JST)
List-Id: <debbugs-submit.debbugs.gnu.org>

Good (or morning afternoon evening night)

When `dired-do-shell-command' runs COMMAND over FILES in
parallel, the `shell-command' process may finish before all the
files have being processed.

emacs -Q ~

* / & du SPC -s RET
; If the number of lines in #<buffer *Async Shell Command*> is less
; than (1+ (length (dired-get-marked-files))) then NOT all files
; has being processed.

Attached patch fix this issue adding 'wait' at the end of COMMAND
when FILES are procesed in parallel.

In GNU Emacs 25.0.92.1 (x86_64-pc-linux-gnu, GTK+ Version 2.24.30)
  of 2016-04-01 built on calancha-pc
Repository revision: a3daa34336da158555d96d670077eedb9eaeeb9c

a3daa34336da158555d96d670077eedb9eaeeb9cdiff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index d29abf3..f351d79 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -722,33 +722,43 @@ dired-shell-stuff-it
 ;; (coming from interactive P and currently ignored) to decide what to do.
 ;; Smart would be a way to access basename or extension of file names.
   (let* ((in-background (string-match "[ \t]*&[ \t]*\\'" command))
-	 (command (if in-background
-		      (substring command 0 (match-beginning 0))
-		    command))
-	 (sequentially (string-match "[ \t]*;[ \t]*\\'" command))
-	 (command (if sequentially
-		      (substring command 0 (match-beginning 0))
-		    command))
-	 (stuff-it
-	  (if (or (string-match-p dired-star-subst-regexp command)
-		  (string-match-p dired-quark-subst-regexp command))
-	      (lambda (x)
-		(let ((retval command))
-		  (while (string-match
-			  "\\(^\\|[ \t]\\)\\([*?]\\)\\([ \t]\\|$\\)" retval)
-		    (setq retval (replace-match x t t retval 2)))
-		  retval))
-	    (lambda (x) (concat command dired-mark-separator x)))))
+         (command (if in-background
+                      (let ((cmd command))
+                        (while (string-match "[ \t]*[&]+[ \t]*\\'" cmd)
+                          (setq cmd (substring cmd 0 (match-beginning 0)))) cmd)
+                    command))
+         (sequentially (string-match "[ \t]*;[ \t]*\\'" command))
+         (command (if sequentially
+                      (let ((cmd command))
+                        (while (string-match "[ \t]*[;]+[ \t]*\\'" cmd)
+                          (setq cmd (substring cmd 0 (match-beginning 0)))) cmd)
+                    command))
+         (in-back-no-seq (and in-background (not sequentially)))
+         (stuff-it
+          (if (or (string-match-p dired-star-subst-regexp command)
+                  (string-match-p dired-quark-subst-regexp command))
+              (lambda (x)
+                (let ((retval command))
+                  (while (string-match
+                          "\\(^\\|[ \t]\\)\\([*?]\\)\\([ \t]\\|$\\)" retval)
+                    (setq retval (replace-match x t t retval 2)))
+                  retval))
+            (lambda (x) (concat command dired-mark-separator x)))))
     (concat
-     (if on-each
-	 (mapconcat stuff-it (mapcar 'shell-quote-argument file-list)
-		    (if (and in-background (not sequentially)) "&" ";"))
-       (let ((files (mapconcat 'shell-quote-argument
-			       file-list dired-mark-separator)))
-	 (if (> (length file-list) 1)
-	     (setq files (concat dired-mark-prefix files dired-mark-postfix)))
-	 (funcall stuff-it files)))
-     (if in-background "&" ""))))
+     (cond (on-each
+            (format "%s%s"
+                    (mapconcat stuff-it (mapcar 'shell-quote-argument file-list)
+                               (or (and in-back-no-seq "&")
+                                   ";"))
+                    (or (and in-back-no-seq "&\nwait"); Wait for background jobs finish.
+                        "")))
+           (t
+            (let ((files (mapconcat 'shell-quote-argument
+                                    file-list dired-mark-separator)))
+              (when (cdr file-list)
+                (setq files (concat dired-mark-prefix files dired-mark-postfix)))
+              (funcall stuff-it files))))
+     (or (and in-background "&") ""))))
 
 ;; This is an extra function so that it can be redefined by ange-ftp.
 ;;;###autoload