1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-28 17:51:15 +02:00

* 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.
This commit is contained in:
Eelco Dolstra 2010-02-02 15:28:36 +00:00
parent 2723d9b56e
commit 4bbbe25802
4 changed files with 5 additions and 112 deletions

View file

@ -8,11 +8,6 @@
#include <sys/stat.h>
#include <fcntl.h>
#ifdef __CYGWIN__
#include <windows.h>
#include <sys/cygwin.h>
#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<FDPair>::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);
}