aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2004-03-24 03:54:16 +0000
committerBruce Momjian <bruce@momjian.us>2004-03-24 03:54:16 +0000
commitb8fd6756e28a27224c90d3e82ce9dc93af5951c2 (patch)
tree12bd13779d0f476cfab62d678a821b20a069cf9f
parentd6bc5944a06a322a36800cedd46f0bb4922a6332 (diff)
downloadpostgresql-b8fd6756e28a27224c90d3e82ce9dc93af5951c2.tar.gz
postgresql-b8fd6756e28a27224c90d3e82ce9dc93af5951c2.zip
Allow unlink/rename of files open by another process on Win32, using a
special Win32 open flag FILE_SHARE_DELETE. Claudio Natoli
-rwxr-xr-xconfigure1
-rw-r--r--configure.in3
-rw-r--r--src/include/port.h7
-rw-r--r--src/interfaces/libpq/Makefile6
-rw-r--r--src/interfaces/libpq/win32.h2
-rw-r--r--src/port/open.c97
6 files changed, 110 insertions, 6 deletions
diff --git a/configure b/configure
index 072e851db7d..9629ef2602a 100755
--- a/configure
+++ b/configure
@@ -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
diff --git a/configure.in b/configure.in
index 0a2a719cfb6..92756c5b958 100644
--- a/configure.in
+++ b/configure.in
@@ -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
diff --git a/src/include/port.h b/src/include/port.h
index 4f52075308a..70f2b5f3fe5 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -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 */
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index 4149f9a6961..f9031e79b25 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -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/%
diff --git a/src/interfaces/libpq/win32.h b/src/interfaces/libpq/win32.h
index 468e786dccc..9d4557fc0d5 100644
--- a/src/interfaces/libpq/win32.h
+++ b/src/interfaces/libpq/win32.h
@@ -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)
diff --git a/src/port/open.c b/src/port/open.c
new file mode 100644
index 00000000000..ccd2a15b1de
--- /dev/null
+++ b/src/port/open.c
@@ -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