diff --git a/collects/scribblings/reference/file-ports.scrbl b/collects/scribblings/reference/file-ports.scrbl index 4a2b57a9fd..909fc10a6b 100644 --- a/collects/scribblings/reference/file-ports.scrbl +++ b/collects/scribblings/reference/file-ports.scrbl @@ -321,7 +321,8 @@ advisory on other platforms. Typically, locking is supported only for file ports, and attempting to acquire a lock with other kinds of file-stream ports raises an -@racket[exn:fail:filesystem] exception.} +@racket[exn:fail:filesystem] exception. Locking is not supported under Solaris, +where the @racket[exn:fail:unsupported] exception is raised.} @defproc[(port-file-unlock [port file-stream-port?]) diff --git a/src/racket/sconfig.h b/src/racket/sconfig.h index 8b01fd2c50..d4b0e3e916 100644 --- a/src/racket/sconfig.h +++ b/src/racket/sconfig.h @@ -99,6 +99,7 @@ # define USE_FCNTL_O_NONBLOCK # define SOME_FDS_ARE_NOT_SELECTABLE # define NEED_RESET_STDOUT_BLOCKING +# undef USE_FLOCK_FOR_FILE_LOCKS # define USE_TIMEZONE_AND_ALTZONE_VAR # define USE_NULL_TO_DISCONNECT_UDP # else @@ -1050,6 +1051,9 @@ pending bytes. Don't use this unless one of the HAS__IOB flags is used. */ + /* USE_FLOCK_FOR_FILE_LOCKS means that flock() is available and works + for file locking. */ + /* CLOSE_ALL_FDS_AFTER_FORK means that all fds except 0, 1, and 2 should be closed after performing a fork() for `process' and `system' calls. */ diff --git a/src/racket/src/port.c b/src/racket/src/port.c index 4684479760..e296fd02c8 100644 --- a/src/racket/src/port.c +++ b/src/racket/src/port.c @@ -4694,6 +4694,7 @@ scheme_file_buffer(int argc, Scheme_Object *argv[]) static int try_lock(int fd, int writer, int *_errid) { #ifdef UNIX_FILE_SYSTEM +# ifdef USE_FLOCK_FOR_FILE_LOCKS { int ok; @@ -4712,6 +4713,13 @@ static int try_lock(int fd, int writer, int *_errid) *_errid = errno; return 0; } +# else + /* using fcntl(F_SETFL, ...) isn't really an option, since the + any-close-release-the-lock semantics of fcntl()-based locks + doesn't work with Racket threads that compete for a lock */ + *_errid = ENOTSUP; + return 0; +# endif #endif #ifdef WINDOWS_FILE_HANDLES { @@ -4804,11 +4812,16 @@ Scheme_Object *scheme_file_unlock(int argc, Scheme_Object **argv) check_already_closed("port-file-unlock", argv[0]); #ifdef UNIX_FILE_SYSTEM +# ifdef USE_FLOCK_FOR_FILE_LOCKS do { ok = flock(fd, LOCK_UN); } while ((ok == -1) && (errno == EINTR)); ok = !ok; errid = errno; +# else + ok = 0; + errid = ENOTSUP; +# endif #endif #ifdef WINDOWS_FILE_HANDLES ok = UnlockFile((HANDLE)fd, 0, 0, LOCK_ALL_FILE_LO, LOCK_ALL_FILE_HI); diff --git a/src/racket/uconfig.h b/src/racket/uconfig.h index 20b0dbdffc..e7744c9b9a 100644 --- a/src/racket/uconfig.h +++ b/src/racket/uconfig.h @@ -14,6 +14,7 @@ #define HAS_STANDARD_IOB #define FILES_HAVE_FDS #define USE_UNIX_SOCKETS_TCP +#define USE_FLOCK_FOR_FILE_LOCKS #define UNIX_PROCESSES #define CLOSE_ALL_FDS_AFTER_FORK