- Fixed errno-error calls to include the syscall's args. This should greatly

improve the quality of the error messages.

- Fixed file-match so that if a filter procedure raises an error condition,
  it is caught and treated as a match failure (as if the procedure returned
  #f). This means you no longer get blown out of the water by
    (file-match "." #f file-directory?)
  if the cwd contains a dangling symlink, for example.

- Added set-file-times (utime).

- Caught a bug in an unused arm of the define-errno-syscall macros (rest arg
  case).

- Perhaps one or two other minor tweaks.
This commit is contained in:
shivers 1995-10-21 12:07:25 +00:00
parent 241344c36b
commit 3e52c5100b
9 changed files with 131 additions and 34 deletions

View File

@ -32,6 +32,13 @@
;;; Return: list of matching file names (strings)
;;; The matcher never considers "." or "..".
;;; Subtle point:
;;; If a file-match predicate raises an error condition, it is caught by
;;; FILE-MATCH, and the file under consideration is not matched. This
;;; means that (file-match "." #f file-directory?) doesn't error out
;;; if you happen to run it in a directory containing a dangling symlink
;;; when FILE-DIRECTORY? is applied to the bogus symlink.
(define (file-match root dot-files? . patterns)
(let ((patterns (apply append (map split-pat patterns))))
(let recur ((root root)
@ -43,11 +50,26 @@
(matcher (cond ((string? pattern)
(let ((re (make-regexp pattern)))
(lambda (f) (regexp-exec re f))))
;; This arm makes a file-matcher using
;; predicate PATTERN. If PATTERN signals
;; an error condition while it is being
;; run, our matcher catches it and returns
;; #f.
((procedure? pattern)
(lambda (f)
(pattern (string-append dir f))))
(call-with-current-continuation
(lambda (abort)
(with-handler (lambda (condition more)
(if (error? condition)
(abort #f)
(more)))
(lambda ()
(pattern (string-append dir f))))))))
(else
(error "Bad file-match pattern" pattern))))
(candidates (maybe-directory-files root dot-files?))
(winners (filter matcher candidates)))
(apply append (map (lambda (fn) (recur (string-append dir fn)

View File

@ -106,7 +106,7 @@
(define (get-lock-region fdes lock)
(receive (err type whence start len pid)
(call-lock-region %get-lock fcntl/get-record-lock fdes lock)
(if err (errno-error err get-lock-region)
(if err (errno-error err get-lock-region fdes lock)
(and (not (= type lock/release))
(make-%lock-region (= type lock/write) start len whence pid)))))

View File

@ -82,7 +82,7 @@
(define (dbm-open file flags mode)
(receive (err dbm) (%dbm-open file flags mode)
(if err
(errno-error err dbm-open)
(errno-error err dbm-open file flags mode)
dbm)))
(define-foreign dbm-close (database_close ((C DBM*) dbm))

View File

@ -118,7 +118,7 @@
-1))
(policy (if (zero? size) bufpol/none policy))
(err (%fdport-set-buffering/errno port policy size)))
(if err (errno-error err set-port-buffering))))
(if err (errno-error err set-port-buffering port policy size))))
;;; Open & Close

View File

@ -222,7 +222,7 @@
(receive (err pid status) (%wait-pid/errno pid flags)
(if err
(if (= err errno/intr) (lp)
(errno-error err %wait-pid))
(errno-error err %wait-pid pid flags))
(and (not (zero? pid)) status))))) ; pid=0 => none ready.
@ -231,7 +231,7 @@
(receive (err pid status) (%wait-pid/errno -1 flags)
(cond (err (cond ((= err errno/child) (values #f #t)) ; No more.
((= err errno/intr) (lp))
(else (errno-error err %wait-any))))
(else (errno-error err %wait-any flags))))
((zero? pid) (values #f #f)) ; None ready.
(else (values pid status))))))

View File

@ -205,6 +205,7 @@
set-file-mode
set-file-owner
set-file-group
set-file-times
truncate-file
read-symlink ; Not POSIX.

View File

@ -443,6 +443,30 @@ scheme_value df_rmdir(long nargs, scheme_value *args)
return ret1;
}
scheme_value df_scm_utime(long nargs, scheme_value *args)
{
extern int scm_utime(const char *, int , int , int , int );
scheme_value ret1;
int r1;
cig_check_nargs(5, nargs, "scm_utime");
r1 = scm_utime(cig_string_body(args[4]), EXTRACT_FIXNUM(args[3]), EXTRACT_FIXNUM(args[2]), EXTRACT_FIXNUM(args[1]), EXTRACT_FIXNUM(args[0]));
ret1 = errno_or_false(r1);
return ret1;
}
scheme_value df_scm_utime_now(long nargs, scheme_value *args)
{
extern int scm_utime_now(const char *);
scheme_value ret1;
int r1;
cig_check_nargs(1, nargs, "scm_utime_now");
r1 = scm_utime_now(cig_string_body(args[0]));
ret1 = errno_or_false(r1);
return ret1;
}
scheme_value df_scheme_stat(long nargs, scheme_value *args)
{
extern int scheme_stat(const char *, scheme_value , int );

View File

@ -35,7 +35,7 @@
;;;
;;; (define (SYSCALL . ARGS)
;;; (receive (err . RET-VALS) (SYSCALL/ERRNO . ARGS)
;;; (if err (errno-error err SYSCALL)
;;; (if err (errno-error err SYSCALL . ARGS)
;;; (values . RET-VALS))))
(define-syntax define-errno-syscall
@ -44,7 +44,7 @@
ret-val ...)
(define (syscall arg ...)
(receive (err ret-val ...) (syscall/errno arg ...)
(if err (errno-error err syscall)
(if err (errno-error err syscall arg ...)
(values ret-val ...)))))
;;; This case handles rest args
@ -52,7 +52,7 @@
ret-val ...)
(define (syscall . args)
(receive (err ret-val ...) (apply syscall/errno . args)
(if err (errno-error err syscall)
(if err (apply errno-error err syscall args)
(values ret-val ...)))))))
;;; DEFINE-SIMPLE-ERRNO-SYSCALL is for the simple case of a system call
@ -63,21 +63,21 @@
;;;
;;; (define (SYSCALL . ARGS)
;;; (cond ((SYSCALL/ERRNO . ARGS) =>
;;; (lambda (err) (errno-error err SYSCALL)))))
;;; (lambda (err) (errno-error err SYSCALL . ARGS)))))
(define-syntax define-simple-errno-syscall
(syntax-rules ()
((define-simple-errno-syscall (syscall arg ...) syscall/errno)
(define (syscall arg ...)
(cond ((syscall/errno arg ...) =>
(lambda (err) (errno-error err syscall))))))
(lambda (err) (errno-error err syscall arg ...))))))
;; This case handles rest args
((define-simple-errno-syscall (syscall . args) syscall/errno)
(define (syscall . args)
(cond ((apply syscall/errno . args) =>
(lambda (err) (errno-error err syscall))))))))
;; This case handles a single rest arg.
((define-simple-errno-syscall (syscall . rest) syscall/errno)
(define (syscall . rest)
(cond ((apply syscall/errno rest) =>
(lambda (err) (apply errno-error err syscall rest))))))))
;;; Process
@ -90,7 +90,7 @@
integer)
(define (%%exec prog argv env)
(errno-error (%%exec/errno prog argv env) %exec)) ; cute.
(errno-error (%%exec/errno prog argv env) %exec prog argv env)) ; cute.
(define (%exec prog arg-list env)
(let ((argv (mapv! stringify (list->vector arg-list)))
@ -342,7 +342,8 @@
(let ((mode (optional-arg maybe-mode #o777))
(fname (ensure-file-name-is-nondirectory path)))
(cond ((create-directory/errno fname mode) =>
(lambda (err) (if err (errno-error err create-directory)))))))
(lambda (err)
(if err (errno-error err create-directory path mode)))))))
(define-foreign read-symlink/errno (scm_readlink (string path))
@ -368,6 +369,31 @@
(define-simple-errno-syscall (delete-directory path) delete-directory/errno)
(define-foreign %utime/errno (scm_utime (string path)
(integer ac_hi) (integer ac_lo)
(integer m_hi) (integer m_lo))
(to-scheme integer errno_or_false))
(define-foreign %utime-now/errno (scm_utime_now (string path))
(to-scheme integer errno_or_false))
;;; (SET-FILE-TIMES/ERRNO path [access-time mod-time])
(define (set-file-times/errno path . maybe-times)
(if (pair? maybe-times)
(let ((access-time (car maybe-times))
(mod-time (if (pair? (cddr maybe-times))
(error "Too many arguments to set-file-times/errno"
(cons path maybe-times))
(cadr maybe-times))))
(%utime/errno path (hi8 access-time) (lo24 access-time)
(hi8 mod-time) (lo24 mod-time)))
(%utime-now/errno path)))
(define-simple-errno-syscall (set-file-times . args) set-file-times/errno)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; STAT
@ -436,10 +462,10 @@
(vector-ref ans-vec 13))))))))
(define (file-info fd/port/fname . maybe-chase?)
(receive (err info) (file-info/errno fd/port/fname
(optional-arg maybe-chase? #t))
(if err (errno-error err file-info)
info)))
(let ((chase? (optional-arg maybe-chase? #t)))
(receive (err info) (file-info/errno fd/port/fname chase?)
(if err (errno-error err file-info fd/port/fname chase?)
info))))
(define file-attributes
@ -540,18 +566,19 @@
(define seek/end 2)
(define (seek fd/port offset . maybe-whence)
(receive (err offset)
(let ((whence (optional-arg maybe-whence seek/set)))
(receive (err cursor)
((if (integer? fd/port) %fd-seek/errno %fdport-seek/errno)
fd/port
offset
(optional-arg maybe-whence seek/set))
(if err (errno-error err seek) offset)))
whence)
(if err (errno-error err seek fd/port offset whence) cursor))))
(define (tell fd/port)
(receive (err offset) (if (integer? fd/port)
(%fd-seek/errno fd/port 0 seek/delta) ; seek(fd)
(%fdport-tell/errno fd/port)) ; ftell(f)
(if err (errno-error err tell) offset)))
(if err (errno-error err tell fd/port) offset)))
(define-foreign %char-ready-fdes?/errno
@ -601,7 +628,7 @@
(define (read-fdes-char fd)
(let ((c (%read-fdes-char fd)))
(if (integer? c) (errno-error c read-fdes-char) c)))
(if (integer? c) (errno-error c read-fdes-char fd) c)))
(define-foreign write-fdes-char/errno (write_fdes_char (char char) (integer fd))
@ -797,7 +824,7 @@
(check-arg string? dir directory-files)
(receive (err cvec numfiles)
(%open-dir (ensure-file-name-is-nondirectory dir))
(if err (errno-error err directory-files))
(if err (errno-error err directory-files dir dotfiles?))
(%sort-file-vector cvec numfiles)
(let ((files (vector->list (C-string-vec->Scheme&free cvec numfiles))))
(if dotfiles? files
@ -816,7 +843,7 @@
(check-arg string? dir match-files)
(receive (err cvec numfiles)
(%open-dir (ensure-file-name-is-nondirectory dir))
(if err (errno-error err match-files))
(if err (errno-error err match-files regexp dir))
(receive (err numfiles) (%filter-C-strings! regexp cvec)
(if (not (equal? err "")) (error err match-files))
(%sort-file-vector cvec numfiles)
@ -922,7 +949,7 @@
(define (%fdport*-read-char data)
(let ((c (%fdport*-read-char/errno data)))
(if (integer? c) (errno-error c %fdport*-read-char)
(if (integer? c) (errno-error c %fdport*-read-char data)
(or c eof-object))))
@ -932,7 +959,7 @@
(define (%fdport*-char-ready? data)
(let ((val (%fdport*-char-ready?/errno data)))
(if (integer? val) (errno-error val %fdport*-char-ready?)
(if (integer? val) (errno-error val %fdport*-char-ready? data)
val)))
(define-foreign %fdport*-write-char/errno

View File

@ -19,12 +19,19 @@
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <utime.h>
#include "cstuff.h"
extern int errno;
extern char **environ;
/* Sux because it's dependent on 32-bitness. */
#define hi8(i) (((i)>>24) & 0xff)
#define lo24(i) ((i) & 0xffffff)
#define comp8_24(hi, lo) (((hi)<<24) + (lo))
/* Process stuff
*******************************************************************************
** wait, exec
@ -121,6 +128,22 @@ char *scm_readlink(char *path)
}
/* Scheme interfaces to utime().
** Complicated by need to pass real 32-bit quantities.
*/
int scm_utime(char const *path, int ac_hi, int ac_lo, int mod_hi, int mod_lo)
{
struct utimbuf t;
t.actime = comp8_24(ac_hi, ac_lo);
t.modtime = comp8_24(mod_hi, mod_lo);
return utime(path, &t);
}
int scm_utime_now(char const *path) {return utime(path, 0);}
/* Two versions of CWD
*******************************************************************************
*/