(declare (type unix-pathname path)
(type fixnum flags)
(type unix-file-mode mode))
- (int-syscall ("open" c-string int int) path (logior #!+win32 o_binary flags) mode))
+ (int-syscall ("open" c-string int int)
+ path
+ (logior #!+win32 o_binary
+ #!+largefile o_largefile
+ flags)
+ mode))
;;; UNIX-CLOSE accepts a file descriptor and attempts to close the file
;;; associated with it.
"
(declare (type unix-fd fd)
(type (integer 0 2) whence))
- (let ((result (alien-funcall (extern-alien "lseek" (function off-t int off-t int))
+ (let ((result (alien-funcall (extern-alien #!-largefile "lseek"
+ #!+largefile "lseek_largefile"
+ (function off-t int off-t int))
fd offset whence)))
(if (minusp result )
(values nil (get-errno))
;;; longer than 32 bits anyway, right?":-|
(define-alien-type nil
(struct wrapped_stat
- #!-mips
- (st-dev unsigned-int) ; would be dev-t in a real stat
- #!+mips
- (st-dev unsigned-long) ; this is _not_ a dev-t on mips
+ (st-dev #!-(or mips largefile) unsigned-int
+ #!+mips unsigned-long
+ #!+largefile dev-t)
(st-ino ino-t)
(st-mode mode-t)
(st-nlink nlink-t)
(st-uid uid-t)
(st-gid gid-t)
- #!-mips
- (st-rdev unsigned-int) ; would be dev-t in a real stat
- #!+mips
- (st-rdev unsigned-long) ; this is _not_ a dev-t on mips
- #!-mips
- (st-size unsigned-int) ; would be off-t in a real stat
- #!+mips
- (st-size off-t)
+ (st-rdev #!-(or mips largefile) unsigned-int
+ #!+mips unsigned-long
+ #!+largefile dev-t)
+ (st-size #!-(or mips largefile) unsigned-int
+ #!+(or mips largefile) off-t)
(st-blksize unsigned-long)
(st-blocks unsigned-long)
(st-atime time-t)
(if (null link)
(return pathname)
(let ((new-pathname
- (unix-simplify-pathname
+ (simplify-namestring
(if (relative-unix-pathname? link)
(let* ((dir-len (1+ (position #\/
pathname
(if (member pathname previous-pathnames :test #'string=)
(return pathname)
(push pathname previous-pathnames))))
-
-(defun unix-simplify-pathname (src)
- (declare (type simple-string src))
- (let* ((src-len (length src))
- (dst (make-string src-len :element-type 'character))
- (dst-len 0)
- (dots 0)
- (last-slash nil))
- (macrolet ((deposit (char)
- `(progn
- (setf (schar dst dst-len) ,char)
- (incf dst-len))))
- (dotimes (src-index src-len)
- (let ((char (schar src src-index)))
- (cond ((char= char #\.)
- (when dots
- (incf dots))
- (deposit char))
- ((char= char #\/)
- (case dots
- (0
- ;; either ``/...' or ``...//...'
- (unless last-slash
- (setf last-slash dst-len)
- (deposit char)))
- (1
- ;; either ``./...'' or ``..././...''
- (decf dst-len))
- (2
- ;; We've found ..
- (cond
- ((and last-slash (not (zerop last-slash)))
- ;; There is something before this ..
- (let ((prev-prev-slash
- (position #\/ dst :end last-slash :from-end t)))
- (cond ((and (= (+ (or prev-prev-slash 0) 2)
- last-slash)
- (char= (schar dst (- last-slash 2)) #\.)
- (char= (schar dst (1- last-slash)) #\.))
- ;; The something before this .. is another ..
- (deposit char)
- (setf last-slash dst-len))
- (t
- ;; The something is some directory or other.
- (setf dst-len
- (if prev-prev-slash
- (1+ prev-prev-slash)
- 0))
- (setf last-slash prev-prev-slash)))))
- (t
- ;; There is nothing before this .., so we need to keep it
- (setf last-slash dst-len)
- (deposit char))))
- (t
- ;; something other than a dot between slashes
- (setf last-slash dst-len)
- (deposit char)))
- (setf dots 0))
- (t
- (setf dots nil)
- (setf (schar dst dst-len) char)
- (incf dst-len))))))
- (when (and last-slash (not (zerop last-slash)))
- (case dots
- (1
- ;; We've got ``foobar/.''
- (decf dst-len))
- (2
- ;; We've got ``foobar/..''
- (unless (and (>= last-slash 2)
- (char= (schar dst (1- last-slash)) #\.)
- (char= (schar dst (- last-slash 2)) #\.)
- (or (= last-slash 2)
- (char= (schar dst (- last-slash 3)) #\/)))
- (let ((prev-prev-slash
- (position #\/ dst :end last-slash :from-end t)))
- (if prev-prev-slash
- (setf dst-len (1+ prev-prev-slash))
- (return-from unix-simplify-pathname
- (coerce "./" 'simple-string))))))))
- (cond ((zerop dst-len)
- "./")
- ((= dst-len src-len)
- dst)
- (t
- (subseq dst 0 dst-len)))))
+\f
+;;; UNIX specific code, that has been cleanly separated from the
+;;; Windows build.
+#!-win32
+(progn
+ (defconstant micro-seconds-per-internal-time-unit
+ (/ 1000000 sb!xc:internal-time-units-per-second))
+
+ (declaim (inline system-internal-real-time system-internal-run-time))
+ (defun system-internal-real-time ()
+ (multiple-value-bind (ignore seconds useconds) (unix-gettimeofday)
+ (declare (ignore ignore) (type (unsigned-byte 32) seconds useconds))
+ (let ((uint (truncate useconds
+ micro-seconds-per-internal-time-unit)))
+ (declare (type (unsigned-byte 32) uint))
+ (+ (* seconds sb!xc:internal-time-units-per-second)
+ uint))))
+
+ (defun system-internal-run-time ()
+ (multiple-value-bind (ignore utime-sec utime-usec stime-sec stime-usec)
+ (unix-fast-getrusage rusage_self)
+ (declare (ignore ignore)
+ (type (unsigned-byte 31) utime-sec stime-sec)
+ ;; (Classic CMU CL had these (MOD 1000000) instead, but
+ ;; at least in Linux 2.2.12, the type doesn't seem to
+ ;; be documented anywhere and the observed behavior is
+ ;; to sometimes return 1000000 exactly.)
+ (type (integer 0 1000000) utime-usec stime-usec))
+ (let ((result (+ (* (+ utime-sec stime-sec)
+ sb!xc:internal-time-units-per-second)
+ (floor (+ utime-usec
+ stime-usec
+ (floor micro-seconds-per-internal-time-unit 2))
+ micro-seconds-per-internal-time-unit))))
+ result))))
\f
;;;; A magic constant for wait3().
;;;;
`(progn
,@(loop for index upfrom 0 below (/ fd-setsize sb!vm:n-machine-word-bits)
collect `(setf (deref (slot ,fd-set 'fds-bits) ,index) 0))))
+