[Git][cmucl/cmucl][master] 2 commits: Fix #125: Linux unix-stat returns wrong values
Raymond Toy (@rtoy)
gitlab at common-lisp.net
Tue Aug 23 23:01:33 UTC 2022
Raymond Toy pushed to branch master at cmucl / cmucl
Commits:
171ca28b by Raymond Toy at 2022-08-23T23:01:04+00:00
Fix #125: Linux unix-stat returns wrong values
- - - - -
2dfc9ff1 by Raymond Toy at 2022-08-23T23:01:09+00:00
Merge branch 'issue-125-unix-stat-wrong' into 'master'
Fix #125: Linux unix-stat returns wrong values
Closes #125
See merge request cmucl/cmucl!85
- - - - -
7 changed files:
- src/code/unix.lisp
- src/contrib/unix/unix-glibc2.lisp
- src/contrib/unix/unix.lisp
- src/i18n/locale/cmucl-unix.pot
- src/lisp/Config.x86_linux
- src/lisp/Config.x86_linux_clang
- src/lisp/os-common.c
Changes:
=====================================
src/code/unix.lisp
=====================================
@@ -53,12 +53,9 @@
(def-alien-type u-int32-t unsigned-int)
(def-alien-type ino-t
- #+netbsd u-int64-t
+ #+(or netbsd linux darwin) u-int64-t
#+alpha unsigned-int
- #-(or alpha netbsd) unsigned-long)
-
-#+linux
-(def-alien-type ino64-t u-int64-t)
+ #-(or alpha netbsd linux darwin) unsigned-long)
(def-alien-type size-t
#-(or linux alpha) long
@@ -72,14 +69,6 @@
#+(and bsd netbsd) int64-t
#+alpha unsigned-int)
-(def-alien-type dev-t
- #-(or alpha svr4 bsd linux) short
- #+(and linux (not amd64)) uquad-t
- #+(and linux amd64) u-int64-t
- #+netbsd u-int64-t
- #+alpha int
- #+(and (not linux) (not netbsd) (or bsd svr4)) unsigned-long)
-
#-BSD
(progn
(deftype file-offset () '(signed-byte 32))
@@ -131,13 +120,6 @@
`(multiple-value-bind (,word ,bit) (floor ,offset 32)
(logbitp ,bit (deref (slot ,fd-set 'fds-bits) ,word)))))
-(def-alien-type nlink-t
- #-(or svr4 netbsd linux) unsigned-short
- #+netbsd unsigned-long
- #+svr4 unsigned-long
- #+(and linux (not amd64)) unsigned-int
- #+(and linux amd64) u-int64-t)
-
(defconstant fd-setsize
#-(or hpux alpha linux FreeBSD) 256
#+hpux 2048 #+alpha 4096 #+(or linux FreeBSD) 1024)
@@ -1301,7 +1283,7 @@
#+glibc2.1
(d-ino ino-t) ; inode number of entry
#-glibc2.1
- (d-ino ino64-t) ; inode number of entry
+ (d-ino ino-t) ; inode number of entry
(d-off off-t) ; offset of next disk directory entry
(d-reclen unsigned-short) ; length of this record
(d_type unsigned-char)
@@ -1347,261 +1329,143 @@
(d-name (array char 256)))) ; name must be no longer than this
-#+(and bsd (not netbsd))
-(def-alien-type nil
- (struct stat
- (st-dev dev-t)
- (st-ino ino-t)
- (st-mode mode-t)
- (st-nlink nlink-t)
- (st-uid uid-t)
- (st-gid gid-t)
- (st-rdev dev-t)
- (st-atime (struct timespec-t))
- (st-mtime (struct timespec-t))
- (st-ctime (struct timespec-t))
- (st-size off-t)
- (st-blocks off-t)
- (st-blksize unsigned-long)
- (st-flags unsigned-long)
- (st-gen unsigned-long)
- (st-lspare long)
- (st-qspare (array long 4))))
-
-#+svr4
-(def-alien-type nil
- (struct stat
- (st-dev dev-t)
- (st-pad1 #-linux (array long 3) #+linux unsigned-short)
- (st-ino ino-t)
- (st-mode #-linux unsigned-long #+linux unsigned-short)
- (st-nlink #-linux short #+linux unsigned-short)
- (st-uid #-linux uid-t #+linux unsigned-short)
- (st-gid #-linux gid-t #+linux unsigned-short)
- (st-rdev dev-t)
- (st-pad2 #-linux (array long 2) #+linux unsigned-short)
- (st-size off-t)
- #-linux (st-pad3 long)
- #+linux (st-blksize unsigned-long)
- #+linux (st-blocks unsigned-long)
- #-linux (st-atime (struct timestruc-t))
- #+linux (st-atime unsigned-long)
- #+linux (unused-1 unsigned-long)
- #-linux (st-mtime (struct timestruc-t))
- #+linux (st-mtime unsigned-long)
- #+linux (unused-2 unsigned-long)
- #-linux (st-ctime (struct timestruc-t))
- #+linux (st-ctime unsigned-long)
- #+linux (unused-3 unsigned-long)
- #+linux (unused-4 unsigned-long)
- #+linux (unused-5 unsigned-long)
- #-linux(st-blksize long)
- #-linux (st-blocks long)
- #-linux (st-fstype (array char 16))
- #-linux (st-pad4 (array long 8))))
-
-#+linux
-(def-alien-type nil
- (struct stat
- (st-dev dev-t)
- #-(or alpha amd64) (st-pad1 unsigned-short)
- (st-ino ino-t)
- #+alpha (st-pad1 unsigned-int)
- #-amd64 (st-mode mode-t)
- (st-nlink nlink-t)
- #+amd64 (st-mode mode-t)
- (st-uid uid-t)
- (st-gid gid-t)
- (st-rdev dev-t)
- #-alpha (st-pad2 unsigned-short)
- (st-size off-t)
- #-alpha (st-blksize unsigned-long)
- #-alpha (st-blocks blkcnt-t)
- (st-atime time-t)
- #-alpha (unused-1 unsigned-long)
- (st-mtime time-t)
- #-alpha (unused-2 unsigned-long)
- (st-ctime time-t)
- #+alpha (st-blocks int)
- #+alpha (st-pad2 unsigned-int)
- #+alpha (st-blksize unsigned-int)
- #+alpha (st-flags unsigned-int)
- #+alpha (st-gen unsigned-int)
- #+alpha (st-pad3 unsigned-int)
- #+alpha (unused-1 unsigned-long)
- #+alpha (unused-2 unsigned-long)
- (unused-3 unsigned-long)
- (unused-4 unsigned-long)
- #-alpha (unused-5 unsigned-long)))
-
-;;; 64-bit stat for Solaris
-#+solaris
-(def-alien-type nil
- (struct stat64
- (st-dev dev-t)
- (st-pad1 (array long 3)) ; Pad so ino is 64-bit aligned
- (st-ino ino64-t)
- (st-mode unsigned-long)
- (st-nlink short)
- (st-uid uid-t)
- (st-gid gid-t)
- (st-rdev dev-t)
- (st-pad2 (array long 3)) ; Pad so size is 64-bit aligned
- (st-size off64-t)
- (st-atime (struct timestruc-t))
- (st-mtime (struct timestruc-t))
- (st-ctime (struct timestruc-t))
- (st-blksize long)
- (st-pad3 (array long 1)) ; Pad so blocks is 64-bit aligned
- (st-blocks blkcnt64-t)
- (st-fstype (array char 16))
- (st-pad4 (array long 8))))
-
-#+netbsd
-(def-alien-type nil
- (struct stat
- (st-dev dev-t)
- (st-mode mode-t)
- (st-ino ino-t)
- (st-nlink nlink-t)
- (st-uid uid-t)
- (st-gid gid-t)
- (st-rdev dev-t)
- (st-atime (struct timespec-t))
- (st-mtime (struct timespec-t))
- (st-ctime (struct timespec-t))
- (st-birthtime (struct timespec-t))
- (st-size off-t)
- (st-blocks off-t)
- (st-blksize long)
- (st-flags unsigned-long)
- (st-gen unsigned-long)
- (st-spare (array unsigned-long 2))))
-
-#-linux
-(defmacro extract-stat-results (buf)
- `(values T
- (slot ,buf 'st-dev)
- (slot ,buf 'st-ino)
- (slot ,buf 'st-mode)
- (slot ,buf 'st-nlink)
- (slot ,buf 'st-uid)
- (slot ,buf 'st-gid)
- (slot ,buf 'st-rdev)
- (slot ,buf 'st-size)
- #-(or svr4 BSD) (slot ,buf 'st-atime)
- #+svr4 (slot (slot ,buf 'st-atime) 'tv-sec)
- #+BSD (slot (slot ,buf 'st-atime) 'ts-sec)
- #-(or svr4 BSD)(slot ,buf 'st-mtime)
- #+svr4 (slot (slot ,buf 'st-mtime) 'tv-sec)
- #+BSD(slot (slot ,buf 'st-mtime) 'ts-sec)
- #-(or svr4 BSD) (slot ,buf 'st-ctime)
- #+svr4 (slot (slot ,buf 'st-ctime) 'tv-sec)
- #+BSD(slot (slot ,buf 'st-ctime) 'ts-sec)
- #+netbsd (slot (slot ,buf 'st-birthtime) 'ts-sec)
- (slot ,buf 'st-blksize)
- (slot ,buf 'st-blocks)))
-
-#+linux
-(defmacro extract-stat-results (buf)
- `(values T
- #+(or alpha amd64)
- (slot ,buf 'st-dev)
- #-(or alpha amd64)
- (+ (deref (slot ,buf 'st-dev) 0)
- (* (+ +max-u-long+ 1)
- (deref (slot ,buf 'st-dev) 1))) ;;; let's hope this works..
- (slot ,buf 'st-ino)
- (slot ,buf 'st-mode)
- (slot ,buf 'st-nlink)
- (slot ,buf 'st-uid)
- (slot ,buf 'st-gid)
- #+(or alpha amd64)
- (slot ,buf 'st-rdev)
- #-(or alpha amd64)
- (+ (deref (slot ,buf 'st-rdev) 0)
- (* (+ +max-u-long+ 1)
- (deref (slot ,buf 'st-rdev) 1))) ;;; let's hope this works..
- (slot ,buf 'st-size)
- (slot ,buf 'st-atime)
- (slot ,buf 'st-mtime)
- (slot ,buf 'st-ctime)
- (slot ,buf 'st-blksize)
- (slot ,buf 'st-blocks)))
-
-#-solaris
-(progn
-(defun unix-stat (name)
- _N"Unix-stat retrieves information about the specified
- file returning them in the form of multiple values.
- See the UNIX Programmer's Manual for a description
- of the values returned. If the call fails, then NIL
- and an error number is returned instead."
- (declare (type unix-pathname name))
- (when (string= name "")
- (setf name "."))
- (with-alien ((buf (struct stat)))
- (syscall (#+linux "stat64" #+netbsd "__stat50" #-(or linux netbsd) "stat"
- c-string (* (struct stat)))
- (extract-stat-results buf)
- (%name->file name) (addr buf))))
-
-(defun unix-lstat (name)
- _N"Unix-lstat is similar to unix-stat except the specified
- file must be a symbolic link."
- (declare (type unix-pathname name))
- (with-alien ((buf (struct stat)))
- (syscall (#+linux "lstat64" #+netbsd "__lstat50" #-(or linux netbsd) "lstat"
- c-string (* (struct stat)))
- (extract-stat-results buf)
- (%name->file name) (addr buf))))
-
-(defun unix-fstat (fd)
- _N"Unix-fstat is similar to unix-stat except the file is specified
- by the file descriptor fd."
- (declare (type unix-fd fd))
- (with-alien ((buf (struct stat)))
- (syscall (#+linux "fstat64" #+netbsd "__fstat50" #-(or linux netbsd) "fstat"
- int (* (struct stat)))
- (extract-stat-results buf)
- fd (addr buf))))
-)
-
-;;; 64-bit versions of stat and friends
-#+solaris
-(progn
-(defun unix-stat (name)
- _N"Unix-stat retrieves information about the specified
- file returning them in the form of multiple values.
- See the UNIX Programmer's Manual for a description
- of the values returned. If the call fails, then NIL
- and an error number is returned instead."
- (declare (type unix-pathname name))
- (when (string= name "")
- (setf name "."))
- (with-alien ((buf (struct stat64)))
- (syscall ("stat64" c-string (* (struct stat64)))
- (extract-stat-results buf)
- (%name->file name) (addr buf))))
-
-(defun unix-lstat (name)
- _N"Unix-lstat is similar to unix-stat except the specified
- file must be a symbolic link."
- (declare (type unix-pathname name))
- (with-alien ((buf (struct stat64)))
- (syscall ("lstat64" c-string (* (struct stat64)))
- (extract-stat-results buf)
- (%name->file name) (addr buf))))
-
-(defun unix-fstat (fd)
- _N"Unix-fstat is similar to unix-stat except the file is specified
- by the file descriptor fd."
- (declare (type unix-fd fd))
- (with-alien ((buf (struct stat64)))
- (syscall ("fstat64" int (* (struct stat64)))
- (extract-stat-results buf)
- fd (addr buf))))
-)
+;; unix-stat and friends
+(macrolet
+ ((call-stat (c-func-name first-arg-type first-arg)
+ ;; Call the stat function named C-FUNC-NAME. The type of the
+ ;; first arg is FIRST-ARG-TYPE and FIRST-ARG is the first arg
+ ;; to the stat function. fstat is different from stat and
+ ;; lstat since it takes an fd for the first arg instead of
+ ;; string.
+ `(with-alien ((dev c-call:long-long)
+ (ino c-call:unsigned-long-long)
+ (mode c-call:unsigned-int)
+ (nlink c-call:unsigned-long-long)
+ (uid c-call:unsigned-int)
+ (gid c-call:unsigned-int)
+ (rdev c-call:unsigned-long-long)
+ (size c-call:long-long)
+ (atime c-call:long-long)
+ (mtime c-call:long-long)
+ (ctime c-call:long-long)
+ (blksize c-call:long)
+ (blocks c-call:long-long))
+ (let ((result
+ (alien-funcall
+ (extern-alien ,c-func-name
+ (function int
+ ,first-arg-type
+ (* c-call:long-long)
+ (* c-call:unsigned-long-long)
+ (* c-call:unsigned-int)
+ (* c-call:unsigned-long-long)
+ (* c-call:unsigned-int)
+ (* c-call:unsigned-int)
+ (* c-call:unsigned-long-long)
+ (* c-call:long-long)
+ (* c-call:long-long)
+ (* c-call:long-long)
+ (* c-call:long-long)
+ (* c-call:long)
+ (* c-call:long-long)))
+ ,first-arg
+ (addr dev)
+ (addr ino)
+ (addr mode)
+ (addr nlink)
+ (addr uid)
+ (addr gid)
+ (addr rdev)
+ (addr size)
+ (addr atime)
+ (addr mtime)
+ (addr ctime)
+ (addr blksize)
+ (addr blocks))))
+ (if (eql -1 result)
+ (values nil (unix-errno))
+ (values t
+ dev
+ ino
+ mode
+ nlink
+ uid
+ gid
+ rdev
+ size
+ atime
+ mtime
+ ctime
+ blksize
+ blocks))))))
+ (defun unix-stat (name)
+ _N"Unix-stat retrieves information about the specified
+ file returning them in the form of multiple values. If the call
+ fails, then NIL and an error number is returned. If the call
+ succeeds, then T is returned in addition to the following values
+ from the stat struct st:
+
+ st_dev Device ID
+ st_ino File serial number
+ st_mode Mode of file
+ st_nlink Number of hard links to the file
+ st_uid User ID
+ st_gid Group ID
+ st_rdev Device ID (if file is character or block special)
+ st_atime Last data access time, in sec
+ st_mtime Last data modification time, in sec
+ st_ctime Last file status change time, in sec
+ st_blksize Preferred I/O block size
+ st_blocks Number of blocks allocated. (Block size is implementation dependent.)
+"
+ (declare (type unix-pathname name))
+ (when (string= name "")
+ (setf name "."))
+ (call-stat "os_stat" c-call:c-string (%name->file name)))
+
+ (defun unix-lstat (name)
+ "Unix-lstat is similar to unix-stat except the specified
+ file must be a symbolic link. If the call fails, then NIL and an
+ error number is returned. If the call succeeds, then T is returned
+ in addition to the following values from the stat struct st:
+
+ st_dev Device ID
+ st_ino File serial number
+ st_mode Mode of file
+ st_nlink Number of hard links to the file
+ st_uid User ID
+ st_gid Group ID
+ st_rdev Device ID (if file is character or block special)
+ st_atime Last data access time, in sec
+ st_mtime Last data modification time, in sec
+ st_ctime Last file status change time, in sec
+ st_blksize Preferred I/O block size
+ st_blocks Number of blocks allocated. (Block size is implementation dependent.)
+"
+ (declare (type unix-pathname name))
+ (call-stat "os_lstat" c-call:c-string (%name->file name)))
+
+ (defun unix-fstat (fd)
+ _N"Unix-fstat is similar to unix-stat except the file is specified
+ by the file descriptor fd. If the call fails, then NIL and an
+ error number is returned. If the call succeeds, then T is returned
+ in addition to the following values from the stat struct st:
+
+ st_dev Device ID
+ st_ino File serial number
+ st_mode Mode of file
+ st_nlink Number of hard links to the file
+ st_uid User ID
+ st_gid Group ID
+ st_rdev Device ID (if file is character or block special)
+ st_atime Last data access time, in sec
+ st_mtime Last data modification time, in sec
+ st_ctime Last file status change time, in sec
+ st_blksize Preferred I/O block size
+ st_blocks Number of blocks allocated. (Block size is implementation dependent.)
+"
+ (declare (type unix-fd fd))
+ (call-stat "os_fstat" int fd)))
(def-alien-type nil
(struct rusage
=====================================
src/contrib/unix/unix-glibc2.lisp
=====================================
@@ -175,7 +175,7 @@
TIOCSIGSEND
KBDCGET KBDCSET KBDCRESET KBDCRST KBDCSSTD KBDSGET KBDGCLICK
- KBDSCLICK FIONREAD unix-exit unix-stat unix-lstat unix-fstat
+ KBDSCLICK FIONREAD unix-exit
unix-getrusage unix-fast-getrusage rusage_self rusage_children
unix-gettimeofday
unix-utimes unix-sched-yield unix-setreuid
=====================================
src/contrib/unix/unix.lisp
=====================================
@@ -159,7 +159,7 @@
KBDCGET KBDCSET KBDCRESET KBDCRST KBDCSSTD KBDSGET KBDGCLICK
KBDSCLICK FIONREAD #+(or hpux bsd) siocspgrp
- unix-exit unix-stat unix-lstat unix-fstat
+ unix-exit
unix-getrusage unix-fast-getrusage rusage_self rusage_children
unix-gettimeofday
#-hpux unix-utimes #-(or svr4 hpux) unix-setreuid
@@ -230,50 +230,6 @@
;;;
-;;; From sys/stat.h
-;; oh boy, in linux-> 2 stat(s)!!
-
-#-(or svr4 bsd linux) ; eg hpux and alpha
-(def-alien-type nil
- (struct stat
- (st-dev dev-t)
- (st-ino ino-t)
- (st-mode mode-t)
- (st-nlink nlink-t)
- (st-uid uid-t)
- (st-gid gid-t)
- (st-rdev dev-t)
- (st-size off-t)
- (st-atime time-t)
- (st-spare1 int)
- (st-mtime time-t)
- (st-spare2 int)
- (st-ctime time-t)
- (st-spare3 int)
- (st-blksize #-alpha long #+alpha unsigned-int)
- (st-blocks #-alpha long #+alpha int)
- (st-spare4 (array long 2))))
-
-#+netbsd
-(def-alien-type nil
- (struct stat
- (st-dev dev-t)
- (st-mode mode-t)
- (st-ino ino-t)
- (st-nlink nlink-t)
- (st-uid uid-t)
- (st-gid gid-t)
- (st-rdev dev-t)
- (st-atime (struct timespec-t))
- (st-mtime (struct timespec-t))
- (st-ctime (struct timespec-t))
- (st-birthtime (struct timespec-t))
- (st-size off-t)
- (st-blocks off-t)
- (st-blksize long)
- (st-flags unsigned-long)
- (st-gen unsigned-long)
- (st-spare (array unsigned-long 2))))
;;; From sys/resource.h
=====================================
src/i18n/locale/cmucl-unix.pot
=====================================
@@ -489,22 +489,71 @@ msgstr ""
#: src/code/unix.lisp
msgid ""
"Unix-stat retrieves information about the specified\n"
-" file returning them in the form of multiple values.\n"
-" See the UNIX Programmer's Manual for a description\n"
-" of the values returned. If the call fails, then NIL\n"
-" and an error number is returned instead."
+" file returning them in the form of multiple values. If the call\n"
+" fails, then NIL and an error number is returned. If the call\n"
+" succeeds, then T is returned in addition to the following values\n"
+" from the stat struct st:\n"
+"\n"
+" st_dev Device ID\n"
+" st_ino File serial number\n"
+" st_mode Mode of file\n"
+" st_nlink Number of hard links to the file\n"
+" st_uid User ID\n"
+" st_gid Group ID\n"
+" st_rdev Device ID (if file is character or block special)\n"
+" st_atime Last data access time, in sec\n"
+" st_mtime Last data modification time, in sec\n"
+" st_ctime Last file status change time, in sec\n"
+" st_blksize Preferred I/O block size\n"
+" st_blocks Number of blocks allocated. (Block size is implementation"
+" dependent.)\n"
+""
msgstr ""
#: src/code/unix.lisp
msgid ""
-"Unix-lstat is similar to unix-stat except the specified\n"
-" file must be a symbolic link."
+"Unix-fstat is similar to unix-stat except the file is specified\n"
+" by the file descriptor fd. If the call fails, then NIL and an\n"
+" error number is returned. If the call succeeds, then T is returned\n"
+" in addition to the following values from the stat struct st:\n"
+"\n"
+" st_dev Device ID\n"
+" st_ino File serial number\n"
+" st_mode Mode of file\n"
+" st_nlink Number of hard links to the file\n"
+" st_uid User ID\n"
+" st_gid Group ID\n"
+" st_rdev Device ID (if file is character or block special)\n"
+" st_atime Last data access time, in sec\n"
+" st_mtime Last data modification time, in sec\n"
+" st_ctime Last file status change time, in sec\n"
+" st_blksize Preferred I/O block size\n"
+" st_blocks Number of blocks allocated. (Block size is implementation"
+" dependent.)\n"
+""
msgstr ""
#: src/code/unix.lisp
msgid ""
-"Unix-fstat is similar to unix-stat except the file is specified\n"
-" by the file descriptor fd."
+"Unix-lstat is similar to unix-stat except the specified\n"
+" file must be a symbolic link. If the call fails, then NIL and an\n"
+" error number is returned. If the call succeeds, then T is returned\n"
+" in addition to the following values from the stat struct st:\n"
+"\n"
+" st_dev Device ID\n"
+" st_ino File serial number\n"
+" st_mode Mode of file\n"
+" st_nlink Number of hard links to the file\n"
+" st_uid User ID\n"
+" st_gid Group ID\n"
+" st_rdev Device ID (if file is character or block special)\n"
+" st_atime Last data access time, in sec\n"
+" st_mtime Last data modification time, in sec\n"
+" st_ctime Last file status change time, in sec\n"
+" st_blksize Preferred I/O block size\n"
+" st_blocks Number of blocks allocated. (Block size is implementation"
+" dependent.)\n"
+""
msgstr ""
#: src/code/unix.lisp
=====================================
src/lisp/Config.x86_linux
=====================================
@@ -4,6 +4,7 @@ include Config.x86_common
CFLAGS += $(COPT)
CPPFLAGS += -m32 -D__NO_CTYPE
CFLAGS += -rdynamic -march=pentium4 -mfpmath=sse -mtune=generic
+CFLAGS += -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
UNDEFSYMPATTERN = -Xlinker -u -Xlinker &
ASSEM_SRC += linux-stubs.S
=====================================
src/lisp/Config.x86_linux_clang
=====================================
@@ -9,6 +9,7 @@ CFLAGS += $(COPT)
# (-mtune=pentium4), the first chip to have sse2; and finally generate
# code assuming instructions can trap (-ftrapping-math).
CFLAGS += -msse2 -mtune=pentium4 -ftrapping-math
+CFLAGS += -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
UNDEFSYMPATTERN = -Xlinker -u -Xlinker &
ASSEM_SRC += linux-stubs.S
=====================================
src/lisp/os-common.c
=====================================
@@ -10,6 +10,7 @@
#include <netdb.h>
#include <stdio.h>
#include <string.h>
+#include <sys/stat.h>
#include <time.h>
#include "os.h"
@@ -589,3 +590,128 @@ os_sleep(double seconds)
requested = remaining;
}
}
+
+/*
+ * Interface to stat/fstat/lstat.
+ *
+ * The arg types are chosen such that they can hold the largest
+ * possible value that any OS would use for the particular slot in the
+ * stat structure. That way we can just use one OS-independent
+ * function that works across all OSes.
+ */
+int
+os_stat(const char* path, u_int64_t *dev, u_int64_t *ino, unsigned int *mode, u_int64_t *nlink,
+ unsigned int *uid, unsigned int *gid, u_int64_t *rdev, int64_t *size,
+ int64_t *atime, int64_t *mtime, int64_t *ctime,
+ long *blksize, int64_t *blocks)
+{
+ int rc;
+ struct stat buf;
+
+ rc = stat(path, &buf);
+
+ if (rc != 0) {
+ return rc;
+ }
+
+#if 0
+ /*
+ * Useful prints to see the actual size of the various
+ * fields. Helpful for porting this to other OSes that we haven't
+ * tested on.
+ */
+ fprintf(stderr, "size dev %d\n", sizeof(buf.st_dev));
+ fprintf(stderr, "size ino %d\n", sizeof(buf.st_ino));
+ fprintf(stderr, "size mode %d\n", sizeof(buf.st_mode));
+ fprintf(stderr, "size nlink %d\n", sizeof(buf.st_nlink));
+ fprintf(stderr, "size uid %d\n", sizeof(buf.st_uid));
+ fprintf(stderr, "size gid %d\n", sizeof(buf.st_gid));
+ fprintf(stderr, "size rdev %d\n", sizeof(buf.st_rdev));
+ fprintf(stderr, "size size %d\n", sizeof(buf.st_size));
+ fprintf(stderr, "size atime %d\n", sizeof(buf.st_atime));
+ fprintf(stderr, "size mtime %d\n", sizeof(buf.st_mtime));
+ fprintf(stderr, "size ctime %d\n", sizeof(buf.st_ctime));
+ fprintf(stderr, "size blksize %d\n", sizeof(buf.st_blksize));
+ fprintf(stderr, "size blocks %d\n", sizeof(buf.st_blocks));
+#endif
+
+ *dev = buf.st_dev;
+ *ino = buf.st_ino;
+ *mode = buf.st_mode;
+ *nlink = buf.st_nlink;
+ *uid = buf.st_uid;
+ *gid = buf.st_gid;
+ *rdev = buf.st_rdev;
+ *size = buf.st_size;
+ *atime = buf.st_atime;
+ *mtime = buf.st_mtime;
+ *ctime = buf.st_ctime;
+ *blksize = buf.st_blksize;
+ *blocks = buf.st_blocks;
+
+ return rc;
+}
+
+int
+os_fstat(int fd, u_int64_t *dev, u_int64_t *ino, unsigned int *mode, u_int64_t *nlink,
+ unsigned int *uid, unsigned int *gid, u_int64_t *rdev, int64_t *size,
+ int64_t *atime, int64_t *mtime, int64_t *ctime,
+ long *blksize, int64_t *blocks)
+{
+ int rc;
+ struct stat buf;
+
+ rc = fstat(fd, &buf);
+
+ if (rc != 0) {
+ return rc;
+ }
+
+ *dev = buf.st_dev;
+ *ino = buf.st_ino;
+ *mode = buf.st_mode;
+ *nlink = buf.st_nlink;
+ *uid = buf.st_uid;
+ *gid = buf.st_gid;
+ *rdev = buf.st_rdev;
+ *size = buf.st_size;
+ *atime = buf.st_atime;
+ *mtime = buf.st_mtime;
+ *ctime = buf.st_ctime;
+ *blksize = buf.st_blksize;
+ *blocks = buf.st_blocks;
+
+ return rc;
+}
+
+int
+os_lstat(const char* path, u_int64_t *dev, u_int64_t *ino, unsigned int *mode, u_int64_t *nlink,
+ unsigned int *uid, unsigned int *gid, u_int64_t *rdev, int64_t *size,
+ int64_t *atime, int64_t *mtime, int64_t *ctime,
+ long *blksize, int64_t *blocks)
+{
+ int rc;
+ struct stat buf;
+
+ rc = lstat(path, &buf);
+
+ if (rc != 0) {
+ return rc;
+ }
+
+ *dev = buf.st_dev;
+ *ino = buf.st_ino;
+ *mode = buf.st_mode;
+ *nlink = buf.st_nlink;
+ *uid = buf.st_uid;
+ *gid = buf.st_gid;
+ *rdev = buf.st_rdev;
+ *size = buf.st_size;
+ *atime = buf.st_atime;
+ *mtime = buf.st_mtime;
+ *ctime = buf.st_ctime;
+ *blksize = buf.st_blksize;
+ *blocks = buf.st_blocks;
+
+ return rc;
+}
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/f62f1e9ee9835281ee42b6ff3a3c6c6cd3822e7b...2dfc9ff1e3f3c6dd4eb6e9b475875ef11310fb54
--
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/f62f1e9ee9835281ee42b6ff3a3c6c6cd3822e7b...2dfc9ff1e3f3c6dd4eb6e9b475875ef11310fb54
You're receiving this email because of your account on gitlab.common-lisp.net.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/cmucl-cvs/attachments/20220823/c6b8227e/attachment-0001.html>
More information about the cmucl-cvs
mailing list