From 4bbbe25802ee5d625d05b9566bcc488b93974692 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 2 Feb 2010 15:28:36 +0000 Subject: [PATCH] * Remove most Cygwin-specific code. Cygwin 1.7 implements advisory POSIX locks, and simulates Unix-style file deletion semantics sufficiently. Note that this means that Nix won't work on Cygwin 1.5 anymore. --- src/libstore/gc.cc | 38 ------------------------ src/libstore/pathlocks.cc | 61 ++------------------------------------- src/libstore/pathlocks.hh | 6 ++-- src/libutil/util.cc | 12 -------- 4 files changed, 5 insertions(+), 112 deletions(-) diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index baa6826fe..f58f691c9 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -15,11 +15,6 @@ #include #include -#ifdef __CYGWIN__ -#include -#include -#endif - namespace nix { @@ -179,15 +174,6 @@ void LocalStore::addTempRoot(const Path & path) fdGCLock.close(); - /* Note that on Cygwin a lot of the following complexity - is unnecessary, since we cannot delete open lock - files. If we have the lock file open, then it's valid; - if we can delete it, then it wasn't in use any more. - - Also note that on Cygwin we cannot "upgrade" a lock - from a read lock to a write lock. */ - -#ifndef __CYGWIN__ debug(format("acquiring read lock on `%1%'") % fnTempRoots); lockFile(fdTempRoots, ltRead, true); @@ -201,10 +187,6 @@ void LocalStore::addTempRoot(const Path & path) /* The garbage collector deleted this file before we could get a lock. (It won't delete the file after we get a lock.) Try again. */ - -#else - break; -#endif } } @@ -217,14 +199,9 @@ void LocalStore::addTempRoot(const Path & path) string s = path + '\0'; writeFull(fdTempRoots, (const unsigned char *) s.c_str(), s.size()); -#ifndef __CYGWIN__ /* Downgrade to a read lock. */ debug(format("downgrading to read lock on `%1%'") % fnTempRoots); lockFile(fdTempRoots, ltRead, true); -#else - debug(format("releasing write lock on `%1%'") % fnTempRoots); - lockFile(fdTempRoots, ltNone, true); -#endif } @@ -252,19 +229,6 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds) Path path = (format("%1%/%2%/%3%") % nixStateDir % tempRootsDir % *i).str(); debug(format("reading temporary root file `%1%'") % path); - -#ifdef __CYGWIN__ - /* On Cygwin we just try to delete the lock file. */ - char win32Path[MAX_PATH]; - cygwin_conv_to_full_win32_path(path.c_str(), win32Path); - if (DeleteFile(win32Path)) { - printMsg(lvlError, format("removed stale temporary roots file `%1%'") - % path); - continue; - } else - debug(format("delete of `%1%' failed: %2%") % path % GetLastError()); -#endif - FDPtr fd(new AutoCloseFD(open(path.c_str(), O_RDWR, 0666))); if (*fd == -1) { /* It's okay if the file has disappeared. */ @@ -276,7 +240,6 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds) //FDPtr fd(new AutoCloseFD(openLockFile(path, false))); //if (*fd == -1) continue; -#ifndef __CYGWIN__ /* Try to acquire a write lock without blocking. This can only succeed if the owning process has died. In that case we don't care about its temporary roots. */ @@ -287,7 +250,6 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds) writeFull(*fd, (const unsigned char *) "d", 1); continue; } -#endif /* Acquire a read lock. This will prevent the owning process from upgrading to a write lock, therefore it will block in diff --git a/src/libstore/pathlocks.cc b/src/libstore/pathlocks.cc index a698609d3..d8290815c 100644 --- a/src/libstore/pathlocks.cc +++ b/src/libstore/pathlocks.cc @@ -8,11 +8,6 @@ #include #include -#ifdef __CYGWIN__ -#include -#include -#endif - namespace nix { @@ -21,72 +16,24 @@ int openLockFile(const Path & path, bool create) { AutoCloseFD fd; -#ifdef __CYGWIN__ - /* On Cygwin we have to open the lock file without "DELETE" - sharing mode; otherwise Windows will allow open lock files to - be deleted (which is almost but not quite what Unix does). */ - char win32Path[MAX_PATH + 1]; - cygwin_conv_to_full_win32_path(path.c_str(), win32Path); - - SECURITY_ATTRIBUTES sa; /* required, otherwise inexplicably bad shit happens */ - sa.nLength = sizeof sa; - sa.lpSecurityDescriptor = 0; - sa.bInheritHandle = TRUE; - HANDLE h = CreateFile(win32Path, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, - (create ? OPEN_ALWAYS : OPEN_EXISTING), - FILE_ATTRIBUTE_NORMAL, 0); - if (h == INVALID_HANDLE_VALUE) { - if (create || GetLastError() != ERROR_FILE_NOT_FOUND) - throw Error(format("opening lock file `%1%'") % path); - fd = -1; - } - else - fd = cygwin_attach_handle_to_fd((char *) path.c_str(), -1, h, 1, O_RDWR); -#else fd = open(path.c_str(), O_RDWR | (create ? O_CREAT : 0), 0666); if (fd == -1 && (create || errno != ENOENT)) throw SysError(format("opening lock file `%1%'") % path); -#endif return fd.borrow(); } -void deleteLockFilePreClose(const Path & path, int fd) +void deleteLockFile(const Path & path, int fd) { -#ifndef __CYGWIN__ /* Get rid of the lock file. Have to be careful not to introduce - races. */ - /* On Unix, write a (meaningless) token to the file to indicate to + races. Write a (meaningless) token to the file to indicate to other processes waiting on this lock that the lock is stale (deleted). */ unlink(path.c_str()); writeFull(fd, (const unsigned char *) "d", 1); /* Note that the result of unlink() is ignored; removing the lock file is an optimisation, not a necessity. */ -#endif -} - - -void deleteLockFilePostClose(const Path & path) -{ -#ifdef __CYGWIN__ - /* On Windows, just try to delete the lock file. This will fail - if anybody still has the file open. We cannot use unlink() - here, because Cygwin emulates Unix semantics of allowing an - open file to be deleted (but fakes it - the file isn't actually - deleted until later, so a file with the same name cannot be - created in the meantime). */ - char win32Path[MAX_PATH + 1]; - cygwin_conv_to_full_win32_path(path.c_str(), win32Path); - if (DeleteFile(win32Path)) - debug(format("delete of `%1%' succeeded") % path.c_str()); - else - /* Not an error: probably means that the lock is still opened - by someone else. */ - debug(format("delete of `%1%' failed: %2%") % path.c_str() % GetLastError()); -#endif } @@ -220,15 +167,13 @@ PathLocks::~PathLocks() void PathLocks::unlock() { foreach (list::iterator, i, fds) { - if (deletePaths) deleteLockFilePreClose(i->second, i->first); + if (deletePaths) deleteLockFile(i->second, i->first); lockedPaths.erase(i->second); if (close(i->first) == -1) printMsg(lvlError, format("error (ignored): cannot close lock file on `%1%'") % i->second); - if (deletePaths) deleteLockFilePostClose(i->second); - debug(format("lock released on `%1%'") % i->second); } diff --git a/src/libstore/pathlocks.hh b/src/libstore/pathlocks.hh index 64d62f6ae..57ca1584a 100644 --- a/src/libstore/pathlocks.hh +++ b/src/libstore/pathlocks.hh @@ -12,10 +12,8 @@ namespace nix { because it doesn't exist. Any other error throws an exception. */ int openLockFile(const Path & path, bool create); -/* Delete an open lock file. Both must be called to be fully portable - between Unix and Windows. */ -void deleteLockFilePreClose(const Path & path, int fd); -void deleteLockFilePostClose(const Path & path); +/* Delete an open lock file. */ +void deleteLockFile(const Path & path, int fd); enum LockType { ltRead, ltWrite, ltNone }; diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 711a969e4..bb17fa5f6 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -1,9 +1,5 @@ #include "config.h" -#ifdef __CYGWIN__ -#include -#endif - #include #include #include @@ -905,15 +901,7 @@ void closeMostFDs(const set & exceptions) void quickExit(int status) { -#ifdef __CYGWIN__ - /* Hack for Cygwin: _exit() doesn't seem to work quite right, - since some Berkeley DB code appears to be called when a child - exits through _exit() (e.g., because execve() failed). So call - the Windows API directly. */ - ExitProcess(status); -#else _exit(status); -#endif }