[Openmcl-cvs-notifications] r15096 - in /release/1.7/source: level-1/linux-files.lisp lib/pathnames.lisp
gb at clozure.com
gb at clozure.com
Tue Nov 29 08:14:23 CST 2011
Author: gb
Date: Tue Nov 29 08:14:22 2011
New Revision: 15096
Log:
Propagate r15083 (DIRECTORY and symbolic links) to 1.7
Modified:
release/1.7/source/level-1/linux-files.lisp
release/1.7/source/lib/pathnames.lisp
Modified: release/1.7/source/level-1/linux-files.lisp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- release/1.7/source/level-1/linux-files.lisp (original)
+++ release/1.7/source/level-1/linux-files.lisp Tue Nov 29 08:14:22 2011
@@ -362,8 +362,9 @@
#+android-target :stat.st_mtime_nsec) 1000)
#-(or linux-target solaris-target)
(round (pref stat :stat.st_mtimespec.tv_nsec) 1000)
- (pref stat :stat.st_gid))
- (values nil nil nil nil nil nil nil)))
+ (pref stat :stat.st_gid)
+ (pref stat :stat.st_dev))
+ (values nil nil nil nil nil nil nil nil nil nil)))
=
#+win64-target
(defun %stat-values (result stat)
@@ -377,8 +378,9 @@
(pref stat :_stat64.st_uid)
#$BUFSIZ
(pref stat :_stat64.st_mtime) ; ???
- (pref stat :_stat64.st_gid))
- (values nil nil nil nil nil nil nil nil nil)))
+ (pref stat :_stat64.st_gid)
+ (pref stat :_stat64.st_dev))
+ (values nil nil nil nil nil nil nil nil nil nil)))
=
#+win32-target
(defun %stat-values (result stat)
@@ -392,8 +394,9 @@
(pref stat :__stat64.st_uid)
#$BUFSIZ
(pref stat :__stat64.st_mtime) ; ???
- (pref stat :__stat64.st_gid))
- (values nil nil nil nil nil nil nil nil nil)))
+ (pref stat :__stat64.st_gid)
+ (pref stat :__stat64.st_dev))
+ (values nil nil nil nil nil nil nil nil nil nil)))
=
#+windows-target
(defun windows-strip-trailing-slash (namestring)
Modified: release/1.7/source/lib/pathnames.lisp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- release/1.7/source/lib/pathnames.lisp (original)
+++ release/1.7/source/lib/pathnames.lisp Tue Nov 29 08:14:22 2011
@@ -330,34 +330,65 @@
(%str-cat device ":" dir subdir)
(%str-cat dir subdir)))
=
-(defmacro with-open-dir ((dirent device dir) &body body)
- `(let ((,dirent (%open-dir (native-translated-namestring (make-pathname =
:device ,device :directory ,dir :defaults nil)))))
- (when ,dirent
- (unwind-protect
- (progn , at body)
- (close-dir ,dirent)))))
+(defmacro with-open-dir ((dirent device dir state follow-links) &body body)
+ (let* ((namestring (gensym)))
+ `(let* ((,namestring (native-translated-namestring (make-pathname :dev=
ice ,device :directory ,dir :defaults nil))))
+ (when (%new-directory-p ,namestring ,follow-links ,state)
+ (let* ((,dirent (%open-dir (native-translated-namestring (make-pat=
hname :device ,device :directory ,dir :defaults nil)))))
+ (when ,dirent
+ (unwind-protect
+ (progn , at body)
+ (close-dir ,dirent))))))))
=
(defun path-is-link (path)
"Returns T if PATH is a (hard or symbolic) link, NIL otherwise."
+ ;; Actually, it's a bit more subtle than that; it basically
+ ;; returns information about the last component of PATH. If
+ ;; some enclosing directory name is a link but the last component
+ ;; isn't, this'll return false.
(eq (%unix-file-kind (native-translated-namestring path) t) :link))
=
-
-(defun %add-directory-result (path result follow-links)
- (let* ((resolved (and follow-links (path-is-link path) (probe-file path)=
)))
- (if resolved
- (push (namestring resolved) (cdr result)) ; may introduce duplicates.
- (push (namestring path) (car result)))
- path))
-
-(defun %make-directory-result ()
- (cons nil nil))
+(defstruct (directory-result (:constructor %make-directory-result))
+ (truenames (make-hash-table :shared nil :test 'string=3D :hash-function =
'sxhash))
+ (directories-seen ()))
+
+
+;;; If no component of the pathname involves a link we could avoid the cal=
l to
+;;; TRUENAME here. Later ...
+(defun %add-directory-result (path result follow-links &optional followed-=
some-links)
+ (declare (ignore followed-some-links))
+ (let* ((truename (if follow-links (truename path) path))
+ (namestring (namestring truename))
+ (truenames (directory-result-truenames result)))
+ (or (gethash namestring truenames)
+ (setf (gethash namestring truenames) truename))))
+ =
=
(defun %process-directory-result (result)
- (dolist (resolved (cdr result) (mapcar #'parse-namestring (sort (car res=
ult) #'string<)))
- (pushnew resolved (car result) :test #'string=3D)))
+ (collect ((pairs))
+ (maphash (lambda (namestring truename) (pairs (cons namestring truenam=
e))) (directory-result-truenames result))
+ (mapcar #'cdr (sort (pairs) #'string< :key #'car))))
+
+(defun %new-directory-p (namestring follow-links result)
+ (multiple-value-bind (win mode size mtime inode uid blocksize rmtime gi=
d dev)
+ (%stat namestring (not follow-links))
+ (declare (ignore size mtime uid blocksize rmtime gid #+windows-target =
inode #+windows-target dev))
+ (when (and win (=3D (logand mode #$S_IFMT) #$S_IFDIR))
+ #+windows-target
+ (let* ((dirname (namestring (truename (pathname namestring)))))
+ (unless (member dirname (directory-result-directories-seen result)=
:test #'string=3D)
+ (push dirname (directory-result-directories-seen result))
+ t))
+ #-windows-target
+ (when (dolist (pair (directory-result-directories-seen result) t)
+ (when (and (eql inode (car pair))
+ (eql dev (cdr pair)))
+ (return)))
+ (push (cons inode dev) (directory-result-directories-seen result))
+ t))))
=
=
-(defun directory (path &key (directories nil) ;; include subdirectories
+(defun directory (path &key (directories t) ;; include subdirectories
(files t) ;; include files
(all t) ;; include Unix dot files (other than dot and dot=
dot)
(directory-pathnames t) ;; return directories as directory-pathname=
-p's.
@@ -409,14 +440,15 @@
(defun %one-wild (dir wild rest path so-far keys result)
(let ((device (pathname-device path))
(all (getf keys :all))
+ (follow-links (getf keys :follow-links))
name)
- (with-open-dir (dirent device dir)
+ (with-open-dir (dirent device dir result follow-links)
(while (setq name (%read-dir dirent))
(when (and (or all (neq (%schar name 0) #\.))
(not (string=3D name "."))
(not (string=3D name ".."))
(%path-pstr*=3D wild name)
- (eq (%unix-file-kind (%path-cat device dir name) t) :directory))
+ (eq (%unix-file-kind (%path-cat device dir name) (not follow-links)) =
:directory))
(let ((subdir (%path-cat nil dir name))
(so-far (cons (%path-std-quotes name nil "/;:*") so-far)))
(declare (dynamic-extent so-far))
@@ -440,13 +472,13 @@
(let (full-path)
(when (and directories
(eq (%unix-file-kind (namestring (setq full-path (%cons-pathname (rev=
erse so-far) nil nil nil device)))
- t)
+ (not follow-links))
:directory))
(setq ans (if directory-pathnames full-path
(%cons-pathname (reverse (cdr so-far)) (car so-far) nil nil device=
)))
(when (and ans (or (null test) (funcall test ans)))
(%add-directory-result ans result follow-links))))
- (with-open-dir (dirent (pathname-device path) dir)
+ (with-open-dir (dirent (pathname-device path) dir result follow-link=
s)
(while (setq sub (%read-dir dirent))
(when (and (or all (neq (%schar sub 0) #\.))
(or include-emacs-lockfiles
@@ -456,7 +488,7 @@
(not (string=3D sub ".."))
(%file*=3D name type sub))
(setq ans
- (if (eq (%unix-file-kind (%path-cat device dir sub) t) :directory)
+ (if (eq (%unix-file-kind (%path-cat device dir sub) (not follow-links)=
) :directory)
(when directories
(let* ((std-sub (%path-std-quotes sub nil "/;:*")))
(if directory-pathnames
@@ -502,12 +534,12 @@
(%add-directory-result sub result follow-links))))))
;; now descend doing %all-dirs on dirs and collecting files & dirs
;; if do-x is t
- (with-open-dir (dirent device (%path-std-quotes dir nil "*;:"))
+ (with-open-dir (dirent device (%path-std-quotes dir nil "*;:") result =
follow-links)
(while (setq sub (%read-dir dirent))
(when (and (or all (neq (%schar sub 0) #\.))
(not (string=3D sub "."))
(not (string=3D sub "..")))
- (if (eq (%unix-file-kind (%path-cat device dir sub) t) :directory)
+ (if (eq (%unix-file-kind (%path-cat device dir sub) (not follow-links))=
:directory)
(let* ((subfile (%path-cat nil dir sub))
(std-sub (%path-std-quotes sub nil "/;:*"))
(so-far (cons std-sub so-far))
More information about the Openmcl-cvs-notifications
mailing list