Changeset 8335


Ignore:
Timestamp:
Jan 28, 2008, 2:53:18 PM (17 years ago)
Author:
gz
Message:

New fn COPY-FILE-ATTRIBUTES copies the mode, owner, group, and modification
time from one file to another.

In support of above:

  • add two more values to %stat-values: the mtime usec's and the gid.
  • hide some conditionalizations in a new macro: with-filename-cstrs.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/event-ide/ccl/level-1/linux-files.lisp

    r8304 r8335  
    201201  (cwd path))
    202202
     203(defmacro with-filename-cstrs (&rest rest)
     204  `(#+darwin-target with-utf-8-cstrs #-darwin-target with-cstrs ,@rest))
     205
    203206(defun %chdir (dirname)
    204   (#+darwin-target with-utf-8-cstrs #-darwin-target with-cstrs ((dirname dirname))
     207  (with-filename-cstrs ((dirname dirname))
    205208    (syscall syscalls::chdir dirname)))
    206209
     
    210213    (when (and (> len 0) (eql (char name (1- len)) #\/))
    211214      (setq name (subseq name 0 (1- len))))
    212     (#+darwin-target with-utf-8-cstrs #-darwin-target with-cstrs ((name name))
     215    (with-filename-cstrs ((name name))
    213216      (syscall syscalls::mkdir name mode))))
    214217
    215218(defun %rmdir (name)
    216219  (let* ((last (1- (length name))))
    217     (#+darwin-target with-utf-8-cstrs #-darwin-target with-cstrs ((name name))
     220    (with-filename-cstrs ((name name))
    218221      (when (and (>= last 0)
    219222                 (eql (%get-byte name last) (char-code #\/)))
     
    269272       (pref stat :stat.st_ino)
    270273       (pref stat :stat.st_uid)
    271        (pref stat :stat.st_blksize))
     274       (pref stat :stat.st_blksize)
     275       #+linux-target
     276       (pref stat :stat.st_mtim.tv_usec)
     277       #-linux-target
     278       (round (pref stat :stat.st_mtimespec.tv_nsec) 1000)
     279       (pref stat :stat.st_gid))
    272280      (values nil nil nil nil nil nil nil)))
    273281
    274282
    275283(defun %%stat (name stat)
    276   (#+darwin-target with-utf-8-cstrs #-darwin-target with-cstrs ((cname name))
     284  (with-filename-cstrs ((cname name))
    277285    (%stat-values
    278286     #+linux-target
     
    291299
    292300(defun %%lstat (name stat)
    293   (#+darwin-target with-utf-8-cstrs #-darwin-target with-cstrs ((cname name))
     301  (with-filename-cstrs ((cname name))
    294302    (%stat-values
    295303     #+linux-target
     
    341349    "unknown"))
    342350
     351(defun try-hard-to-get-errno (err)
     352  (declare (optimize (safety 0 speed 3)))
     353  (when (eq err -1)
     354    (let ((nerr (%get-errno)))
     355      (unless (eq nerr 0) (setq err nerr))))
     356  #+darwin-target
     357  (when (eq err -1)
     358    ;; Not thread safe, but when can we do??
     359    (let ((nerr (pref (foreign-symbol-address "_errno") :signed)))
     360      (unless (eq nerr 0) (setq err nerr))))
     361  err)
     362
     363(defun copy-file-attributes (source-path dest-path)
     364  "Copy the mode, owner, group and modification time of source-path to dest-path.
     365   Returns T if succeeded, NIL if some of the attributes couldn't be copied due to
     366   permission problems.  Any other failures cause an error to be signalled"
     367  (multiple-value-bind (win mode ignore mtime-sec ignore uid ignore mtime-usec gid)
     368                       (%stat (native-translated-namestring source-path) t)
     369    (declare (ignore ignore))
     370    (unless win
     371      (error "Cannot get attributes of ~s" source-path))
     372    (with-filename-cstrs ((cnamestr (native-translated-namestring dest-path)))
     373      (macrolet ((errchk (form)
     374                   `(let ((err ,form))
     375                      (unless (eql err 0)
     376                        (setq win nil)
     377                        ;; We need the real errno so we can tell if it's a permission
     378                        ;; error or something else...
     379                        (when (eql err -1)
     380                          (setq err (try-hard-to-get-errno err)))
     381                        (unless (eql err #$EPERM) (%errno-disp err dest-path))))))
     382        (errchk (#_chmod cnamestr mode))
     383        (errchk (%stack-block ((times (record-length (:array (:struct :timeval) 2))))
     384                  (setf (pref times :timeval.tv_sec) mtime-sec)
     385                  (setf (pref times :timeval.tv_usec) mtime-usec)
     386                  (%incf-ptr times (record-length :timeval))
     387                  (setf (pref times :timeval.tv_sec) mtime-sec)
     388                  (setf (pref times :timeval.tv_usec) mtime-usec)
     389                  (%incf-ptr times (- (record-length :timeval)))
     390                  (#_utimes cnamestr times)))
     391        (errchk (#_chown cnamestr uid gid))))
     392    win))
    343393
    344394#+linux-target
     
    406456    (setq namestring (current-directory-name)))
    407457  (%stack-block ((resultbuf #$PATH_MAX))
    408     (#+darwin-target with-utf-8-cstrs #-darwin-target with-cstrs ((name namestring #|(tilde-expand namestring)|#))
     458    (with-filename-cstrs ((name namestring #|(tilde-expand namestring)|#))
    409459      (let* ((result (#_realpath name resultbuf)))
    410460        (declare (dynamic-extent result))
     
    477527
    478528(defun %utimes (namestring)
    479   (#+darwin-target with-utf-8-cstrs #-darwin-target with-cstrs ((cnamestring namestring))
     529  (with-filename-cstrs ((cnamestring namestring))
    480530    (let* ((err (#_utimes cnamestring (%null-ptr))))
    481531      (declare (fixnum err))
     
    495545
    496546(defun %open-dir (namestring)
    497   (#+darwin-target with-utf-8-cstrs #-darwin-target with-cstrs ((name namestring))
     547  (with-filename-cstrs ((name namestring))
    498548    (let* ((DIR (#_opendir name)))
    499549      (unless (%null-ptr-p DIR)
Note: See TracChangeset for help on using the changeset viewer.