aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2017-09-10 20:37:17 -0700
committerPaul Eggert2017-09-10 20:38:19 -0700
commitcf9891e14e48a93bca2065fdd7998f5f677786dc (patch)
treea4d310f7868b010342634c45f36964af33c91af7
parent01c885f21f343045783eb9ad1ff5f9b83d6cd789 (diff)
downloademacs-cf9891e14e48a93bca2065fdd7998f5f677786dc.tar.gz
emacs-cf9891e14e48a93bca2065fdd7998f5f677786dc.zip
Fix some make-directory bugs
* lisp/files.el (files--ensure-directory): New function. (make-directory): Use it to avoid bugs when (make-directory FOO t) is invoked on a non-directory, or on a directory hierarchy that is being built by some other process while Emacs is running. * test/lisp/files-tests.el (files-tests--make-directory): New test.
-rw-r--r--lisp/files.el31
-rw-r--r--test/lisp/files-tests.el21
2 files changed, 41 insertions, 11 deletions
diff --git a/lisp/files.el b/lisp/files.el
index 43aec8173d9..85e649fbb59 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -5320,6 +5320,14 @@ instance of such commands."
5320 (rename-buffer (generate-new-buffer-name base-name)) 5320 (rename-buffer (generate-new-buffer-name base-name))
5321 (force-mode-line-update)))) 5321 (force-mode-line-update))))
5322 5322
5323(defun files--ensure-directory (dir)
5324 "Make directory DIR if it is not already a directory. Return nil."
5325 (condition-case err
5326 (make-directory-internal dir)
5327 (file-already-exists
5328 (unless (file-directory-p dir)
5329 (signal (car err) (cdr err))))))
5330
5323(defun make-directory (dir &optional parents) 5331(defun make-directory (dir &optional parents)
5324 "Create the directory DIR and optionally any nonexistent parent dirs. 5332 "Create the directory DIR and optionally any nonexistent parent dirs.
5325If DIR already exists as a directory, signal an error, unless 5333If DIR already exists as a directory, signal an error, unless
@@ -5348,18 +5356,19 @@ raised."
5348 (if (not parents) 5356 (if (not parents)
5349 (make-directory-internal dir) 5357 (make-directory-internal dir)
5350 (let ((dir (directory-file-name (expand-file-name dir))) 5358 (let ((dir (directory-file-name (expand-file-name dir)))
5351 create-list) 5359 create-list parent)
5352 (while (and (not (file-exists-p dir)) 5360 (while (progn
5353 ;; If directory is its own parent, then we can't 5361 (setq parent (directory-file-name
5354 ;; keep looping forever 5362 (file-name-directory dir)))
5355 (not (equal dir 5363 (condition-case err
5356 (directory-file-name 5364 (files--ensure-directory dir)
5357 (file-name-directory dir))))) 5365 (file-missing
5366 ;; Do not loop if root does not exist (Bug#2309).
5367 (not (string= dir parent)))))
5358 (setq create-list (cons dir create-list) 5368 (setq create-list (cons dir create-list)
5359 dir (directory-file-name (file-name-directory dir)))) 5369 dir parent))
5360 (while create-list 5370 (dolist (dir create-list)
5361 (make-directory-internal (car create-list)) 5371 (files--ensure-directory dir)))))))
5362 (setq create-list (cdr create-list))))))))
5363 5372
5364(defconst directory-files-no-dot-files-regexp 5373(defconst directory-files-no-dot-files-regexp
5365 "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*" 5374 "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*"
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el
index a2f2b74312f..b52965a02b4 100644
--- a/test/lisp/files-tests.el
+++ b/test/lisp/files-tests.el
@@ -344,6 +344,27 @@ be invoked with the right arguments."
344 (cdr path-res) 344 (cdr path-res)
345 (insert-directory-wildcard-in-dir-p (car path-res))))))) 345 (insert-directory-wildcard-in-dir-p (car path-res)))))))
346 346
347(ert-deftest files-tests--make-directory ()
348 (let* ((dir (make-temp-file "files-mkdir-test" t))
349 (dirname (file-name-as-directory dir))
350 (file (concat dirname "file"))
351 (subdir1 (concat dirname "subdir1"))
352 (subdir2 (concat dirname "subdir2"))
353 (a/b (concat dirname "a/b")))
354 (write-region "" nil file)
355 (should-error (make-directory "/"))
356 (should-not (make-directory "/" t))
357 (should-error (make-directory dir))
358 (should-not (make-directory dir t))
359 (should-error (make-directory dirname))
360 (should-not (make-directory dirname t))
361 (should-error (make-directory file))
362 (should-error (make-directory file t))
363 (should-not (make-directory subdir1))
364 (should-not (make-directory subdir2 t))
365 (should-error (make-directory a/b))
366 (should-not (make-directory a/b t))))
367
347 368
348(provide 'files-tests) 369(provide 'files-tests)
349;;; files-tests.el ends here 370;;; files-tests.el ends here