diff -dur nethack-3.4.3/include/unixconf.h nethack-3.4.3-fcntl/include/unixconf.h --- nethack-3.4.3/include/unixconf.h 2003-12-08 00:39:13.000000000 +0100 +++ nethack-3.4.3-fcntl/include/unixconf.h 2011-08-27 13:24:40.000000000 +0200 @@ -209,6 +209,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 -dur nethack-3.4.3/src/files.c nethack-3.4.3-fcntl/src/files.c --- nethack-3.4.3/src/files.c 2003-12-08 00:39:13.000000000 +0100 +++ nethack-3.4.3-fcntl/src/files.c 2011-08-27 13:29:28.000000000 +0200 @@ -11,7 +11,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 @@ -150,7 +150,9 @@ STATIC_DCL void FDECL(redirect, (const char *,const char *,FILE *,BOOLEAN_P)); STATIC_DCL void FDECL(docompress_file, (const char *,BOOLEAN_P)); #endif +#ifndef USE_FCNTL STATIC_DCL char *FDECL(make_lockname, (const char *,char *)); +#endif STATIC_DCL FILE *FDECL(fopen_config_file, (const char *)); STATIC_DCL int FDECL(get_uchars, (FILE *,char *,char *,uchar *,BOOLEAN_P,int,const char *)); int FDECL(parse_config_line, (FILE *,char *,char *,char *)); @@ -1243,12 +1245,16 @@ 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) +#ifndef USE_FCNTL STATIC_OVL char * make_lockname(filename, lockname) const char *filename; @@ -1282,6 +1288,7 @@ # endif /* UNIX || VMS || AMIGA || WIN32 || MSDOS */ #endif } +#endif /* !USE_FCNTL */ /* lock a file */ @@ -1294,8 +1301,10 @@ #if (defined(macintosh) && (defined(__SC__) || defined(__MRC__))) || defined(__MWERKS__) # pragma unused(filename, retryct) #endif +#ifndef USE_FCNTL char locknambuf[BUFSZ]; const char *lockname; +#endif nesting++; if (nesting > 1) { @@ -1303,18 +1312,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 */ 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 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 while (link(filename, lockname) == -1) { # 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 */ @@ -1360,11 +1402,12 @@ 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; @@ -1414,10 +1457,19 @@ # pragma unused(filename) #endif { +#ifndef USE_FCNTL char locknambuf[BUFSZ]; const char *lockname; +#endif 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 */ lockname = fqname(lockname, LOCKPREFIX, 2); @@ -1437,6 +1489,7 @@ DeleteFile(lockname); lockptr = 0; #endif /* AMIGA || WIN32 || MSDOS */ +#endif /* USE_FCNTL */ } nesting--;