Allow unlink/rename of files open by another process on Win32, using a

special Win32 open flag FILE_SHARE_DELETE.

Claudio Natoli
This commit is contained in:
Bruce Momjian 2004-03-24 03:54:16 +00:00
parent d6bc5944a0
commit b8fd6756e2
6 changed files with 110 additions and 6 deletions

1
configure vendored
View File

@ -12079,6 +12079,7 @@ esac
case $host_os in mingw*)
LIBOBJS="$LIBOBJS copydir.$ac_objext"
LIBOBJS="$LIBOBJS gettimeofday.$ac_objext"
LIBOBJS="$LIBOBJS open.$ac_objext"
LIBOBJS="$LIBOBJS pipe.$ac_objext"
LIBOBJS="$LIBOBJS rand.$ac_objext" ;;
esac

View File

@ -1,5 +1,5 @@
dnl Process this file with autoconf to produce a configure script.
dnl $PostgreSQL: pgsql/configure.in,v 1.321 2004/03/20 16:11:22 momjian Exp $
dnl $PostgreSQL: pgsql/configure.in,v 1.322 2004/03/24 03:54:16 momjian Exp $
dnl
dnl Developers, please strive to achieve this order:
dnl
@ -907,6 +907,7 @@ esac
case $host_os in mingw*)
AC_LIBOBJ(copydir)
AC_LIBOBJ(gettimeofday)
AC_LIBOBJ(open)
AC_LIBOBJ(pipe)
AC_LIBOBJ(rand) ;;
esac

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/port.h,v 1.22 2004/03/10 21:12:46 momjian Exp $
* $PostgreSQL: pgsql/src/include/port.h,v 1.23 2004/03/24 03:54:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -50,6 +50,11 @@ extern int pgunlink(const char *path);
#endif
#ifdef WIN32
/* open() replacement to allow delete of held files */
extern int win32_open(const char*,int,...);
#define open(a,b,...) win32_open(a,b,##__VA_ARGS__)
extern int copydir(char *fromdir, char *todir);
/* Missing rand functions */

View File

@ -4,7 +4,7 @@
#
# Copyright (c) 1994, Regents of the University of California
#
# $PostgreSQL: pgsql/src/interfaces/libpq/Makefile,v 1.99 2004/03/12 04:33:41 momjian Exp $
# $PostgreSQL: pgsql/src/interfaces/libpq/Makefile,v 1.100 2004/03/24 03:54:16 momjian Exp $
#
#-------------------------------------------------------------------------
@ -23,7 +23,7 @@ override CPPFLAGS := -I$(srcdir) $(CPPFLAGS) $(THREAD_CPPFLAGS) -DFRONTEND -DSYS
OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \
fe-protocol2.o fe-protocol3.o pqexpbuffer.o pqsignal.o fe-secure.o \
dllist.o md5.o ip.o wchar.o encnames.o \
$(filter crypt.o getaddrinfo.o inet_aton.o noblock.o snprintf.o strerror.o path.o thread.o, $(LIBOBJS))
$(filter crypt.o getaddrinfo.o inet_aton.o noblock.o snprintf.o strerror.o open.o path.o thread.o, $(LIBOBJS))
ifeq ($(PORTNAME), win32)
OBJS+=win32.o
endif
@ -52,7 +52,7 @@ backend_src = $(top_srcdir)/src/backend
# For port modules, this only happens if configure decides the module
# is needed (see filter hack in OBJS, above).
crypt.c getaddrinfo.c inet_aton.c noblock.c snprintf.c strerror.c path.c thread.c: % : $(top_srcdir)/src/port/%
crypt.c getaddrinfo.c inet_aton.c noblock.c snprintf.c strerror.c open.c path.c thread.c: % : $(top_srcdir)/src/port/%
rm -f $@ && $(LN_S) $< .
md5.c ip.c: % : $(backend_src)/libpq/%

View File

@ -16,7 +16,7 @@
#define _strnicmp(a,b,c) strnicmp(a,b,c)
#define _errno errno
#else
#define open(a,b,c) _open(a,b,c)
/* open provided elsewhere */
#define close(a) _close(a)
#define read(a,b,c) _read(a,b,c)
#define write(a,b,c) _write(a,b,c)

97
src/port/open.c Normal file
View File

@ -0,0 +1,97 @@
/*-------------------------------------------------------------------------
*
* open.c
* Win32 open() replacement
*
*
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/port/open.c,v 1.1 2004/03/24 03:54:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifdef WIN32
#include <windows.h>
#include <fcntl.h>
#include <errno.h>
#include <assert.h>
int openFlagsToCreateFileFlags(int openFlags)
{
switch (openFlags & (O_CREAT|O_TRUNC|O_EXCL))
{
case 0:
case O_EXCL: return OPEN_EXISTING;
case O_CREAT: return OPEN_ALWAYS;
case O_TRUNC:
case O_TRUNC|O_EXCL: return TRUNCATE_EXISTING;
case O_CREAT|O_TRUNC: return CREATE_ALWAYS;
case O_CREAT|O_EXCL:
case O_CREAT|O_TRUNC|O_EXCL: return CREATE_NEW;
}
/* will never get here */
return 0;
}
/*
* - file attribute setting, based on fileMode?
* - handle other flags? (eg FILE_FLAG_NO_BUFFERING/FILE_FLAG_WRITE_THROUGH)
*/
int win32_open(const char* fileName, int fileFlags, ...)
{
int fd;
HANDLE h;
SECURITY_ATTRIBUTES sa;
/* Check that we can handle the request */
assert((fileFlags & ((O_RDONLY|O_WRONLY|O_RDWR) | O_APPEND |
(O_RANDOM|O_SEQUENTIAL|O_TEMPORARY) |
_O_SHORT_LIVED |
(O_CREAT|O_TRUNC|O_EXCL) | (O_TEXT|O_BINARY))) == fileFlags);
sa.nLength=sizeof(sa);
sa.bInheritHandle=TRUE;
sa.lpSecurityDescriptor=NULL;
if ((h = CreateFile(fileName,
/* cannot use O_RDONLY, as it == 0 */
(fileFlags & O_RDWR) ? (GENERIC_WRITE | GENERIC_READ) :
((fileFlags & O_WRONLY) ? GENERIC_WRITE : GENERIC_READ),
(FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE),
&sa,
openFlagsToCreateFileFlags(fileFlags),
FILE_ATTRIBUTE_NORMAL |
((fileFlags & O_RANDOM) ? FILE_FLAG_RANDOM_ACCESS : 0) |
((fileFlags & O_SEQUENTIAL) ? FILE_FLAG_SEQUENTIAL_SCAN : 0) |
((fileFlags & _O_SHORT_LIVED) ? FILE_ATTRIBUTE_TEMPORARY : 0) |
((fileFlags & O_TEMPORARY) ? FILE_FLAG_DELETE_ON_CLOSE : 0),
NULL)) == INVALID_HANDLE_VALUE)
{
switch (GetLastError())
{
/* EMFILE, ENFILE should not occur from CreateFile. */
case ERROR_PATH_NOT_FOUND:
case ERROR_FILE_NOT_FOUND: errno = ENOENT; break;
case ERROR_FILE_EXISTS: errno = EEXIST; break;
case ERROR_ACCESS_DENIED: errno = EACCES; break;
default:
errno = EINVAL;
}
return -1;
}
/* _open_osfhandle will, on error, set errno accordingly */
if ((fd = _open_osfhandle((long)h,fileFlags&O_APPEND)) < 0 ||
(fileFlags&(O_TEXT|O_BINARY) && (_setmode(fd,fileFlags&(O_TEXT|O_BINARY)) < 0)))
CloseHandle(h); /* will not affect errno */
return fd;
}
#endif