Patch against NetHack 3.4.2 from ftp://alt.org/pub/nethack/nh342-fcntl-1.diff updated for Slash'EM 7E6F3 (line numbers only) by Ali 2004-12-03. diff -Naurd ../slashem-0.0.7E6F3/include/unixconf.h ./include/unixconf.h --- ../slashem-0.0.7E6F3/include/unixconf.h 2004-11-13 08:58:52.000000000 +0000 +++ ./include/unixconf.h 2004-12-03 10:29:25.000000000 +0000 @@ -272,6 +272,12 @@ #define FCMASK 0660 /* file creation mask */ +/* fcntl(2) is a POSIX-portable call for manipulating file descriptors. + * Comment out the USE_FCNTL if for some reason you have a strange + * os/filesystem combination for which fcntl(2) does not work. */ +#ifdef POSIX_TYPES +# define USE_FCNTL +#endif /* * The remainder of the file should not need to be changed. diff -Naurd ../slashem-0.0.7E6F3/src/files.c ./src/files.c --- ../slashem-0.0.7E6F3/src/files.c 2004-11-13 08:58:52.000000000 +0000 +++ ./src/files.c 2004-12-03 10:29:25.000000000 +0000 @@ -23,7 +23,7 @@ #include -#if !defined(MAC) && !defined(O_WRONLY) && !defined(AZTEC_C) +#if (!defined(MAC) && !defined(O_WRONLY) && !defined(AZTEC_C)) || defined(USE_FCNTL) #include #endif @@ -1427,9 +1427,12 @@ static int nesting = 0; -#ifdef NO_FILE_LINKS /* implies UNIX */ +#if defined(NO_FILE_LINKS) || defined(USE_FCNTL) /* implies UNIX */ static int lockfd; /* for lock_file() to pass to unlock_file() */ #endif +#ifdef USE_FCNTL +struct flock sflock; /* for unlocking, same as above */ +#endif #define HUP if (!program_state.done_hup) @@ -1467,7 +1470,6 @@ #endif } - /* lock a file */ boolean lock_file(filename, whichprefix, retryct) @@ -1487,18 +1489,51 @@ return TRUE; } +#ifndef USE_FCNTL lockname = make_lockname(filename, locknambuf); - filename = fqname(filename, whichprefix, 0); -#ifndef NO_FILE_LINKS /* LOCKDIR should be subsumed by LOCKPREFIX */ +# ifndef NO_FILE_LINKS /* LOCKDIR should be subsumed by LOCKPREFIX */ lockname = fqname(lockname, LOCKPREFIX, 2); +# endif +#endif + filename = fqname(filename, whichprefix, 0); + +#ifdef USE_FCNTL + lockfd = open(filename,O_RDWR); + if (lockfd == -1) { + HUP raw_printf("Cannot open file %s. This is a program bug.", + filename); + } + sflock.l_type = F_WRLCK; + sflock.l_whence = SEEK_SET; + sflock.l_start = 0; + sflock.l_len = 0; #endif #if defined(UNIX) || defined(VMS) -# ifdef NO_FILE_LINKS +# ifdef USE_FCNTL + while (fcntl(lockfd,F_SETLK,&sflock) == -1) { +# else +# ifdef NO_FILE_LINKS while ((lockfd = open(lockname, O_RDWR|O_CREAT|O_EXCL, 0666)) == -1) { -# else +# else while (link(filename, lockname) == -1) { -# endif +# endif +# endif + +#ifdef USE_FCNTL + if (retryct--) { + HUP raw_printf( + "Waiting for release of fcntl lock on %s. (%d retries left).", + filename, retryct); + sleep(1); + } else { + HUP (void) raw_print("I give up. Sorry."); + HUP raw_printf("Some other process has an unnatural grip on %s.", + filename); + nesting--; + return FALSE; + } +#else register int errnosv = errno; switch (errnosv) { /* George Barbanis */ @@ -1544,11 +1579,11 @@ nesting--; return FALSE; } - +#endif /* USE_FCNTL */ } #endif /* UNIX || VMS */ -#if defined(AMIGA) || defined(WIN32) || defined(MSDOS) +#if (defined(AMIGA) || defined(WIN32) || defined(MSDOS)) && !defined(USE_FCNTL) # ifdef AMIGA #define OPENFAILURE(fd) (!fd) lockptr = 0; @@ -1599,25 +1634,33 @@ const char *lockname; if (nesting == 1) { +#ifdef USE_FCNTL + sflock.l_type = F_UNLCK; + if (fcntl(lockfd,F_SETLK,&sflock) == -1) { + HUP raw_printf("Can't remove fcntl lock on %s.", filename); + (void) close(lockfd); + } +# else lockname = make_lockname(filename, locknambuf); -#ifndef NO_FILE_LINKS /* LOCKDIR should be subsumed by LOCKPREFIX */ +# ifndef NO_FILE_LINKS /* LOCKDIR should be subsumed by LOCKPREFIX */ lockname = fqname(lockname, LOCKPREFIX, 2); -#endif +# endif -#if defined(UNIX) || defined(VMS) +# if defined(UNIX) || defined(VMS) if (unlink(lockname) < 0) HUP raw_printf("Can't unlink %s.", lockname); -# ifdef NO_FILE_LINKS +# ifdef NO_FILE_LINKS (void) close(lockfd); -# endif +# endif -#endif /* UNIX || VMS */ +# endif /* UNIX || VMS */ -#if defined(AMIGA) || defined(WIN32) || defined(MSDOS) +# if defined(AMIGA) || defined(WIN32) || defined(MSDOS) if (lockptr) Close(lockptr); DeleteFile(lockname); lockptr = 0; -#endif /* AMIGA || WIN32 || MSDOS */ +# endif /* AMIGA || WIN32 || MSDOS */ +#endif /* USE_FCNTL */ } nesting--;