open.c 2.91 KB
Newer Older
1 2 3 4 5 6
/*-------------------------------------------------------------------------
 *
 * open.c
 *	   Win32 open() replacement
 *
 *
7
 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
8
 *
9
 * $PostgreSQL: pgsql/src/port/open.c,v 1.8 2005/02/27 00:53:29 momjian Exp $
10 11 12 13 14 15
 *
 *-------------------------------------------------------------------------
 */

#ifdef WIN32

16
#include <postgres.h>
17 18 19 20 21
#include <windows.h>
#include <fcntl.h>
#include <errno.h>
#include <assert.h>

22 23
int win32_open(const char *fileName, int fileFlags, ...);

24 25
static int
openFlagsToCreateFileFlags(int openFlags)
26
{
Bruce Momjian's avatar
Bruce Momjian committed
27
	switch (openFlags & (O_CREAT | O_TRUNC | O_EXCL))
28 29
	{
		case 0:
Bruce Momjian's avatar
Bruce Momjian committed
30 31
		case O_EXCL:
			return OPEN_EXISTING;
32

Bruce Momjian's avatar
Bruce Momjian committed
33 34
		case O_CREAT:
			return OPEN_ALWAYS;
35 36

		case O_TRUNC:
Bruce Momjian's avatar
Bruce Momjian committed
37 38
		case O_TRUNC | O_EXCL:
			return TRUNCATE_EXISTING;
39

Bruce Momjian's avatar
Bruce Momjian committed
40 41
		case O_CREAT | O_TRUNC:
			return CREATE_ALWAYS;
42

Bruce Momjian's avatar
Bruce Momjian committed
43 44 45
		case O_CREAT | O_EXCL:
		case O_CREAT | O_TRUNC | O_EXCL:
			return CREATE_NEW;
46 47 48 49 50 51 52
	}

	/* will never get here */
	return 0;
}

/*
Bruce Momjian's avatar
Bruce Momjian committed
53 54
 *	 - file attribute setting, based on fileMode?
 *	 - handle other flags? (eg FILE_FLAG_NO_BUFFERING/FILE_FLAG_WRITE_THROUGH)
55
 */
Bruce Momjian's avatar
Bruce Momjian committed
56 57
int
win32_open(const char *fileName, int fileFlags,...)
58
{
Bruce Momjian's avatar
Bruce Momjian committed
59 60
	int			fd;
	HANDLE		h;
61 62 63
	SECURITY_ATTRIBUTES sa;

	/* Check that we can handle the request */
Bruce Momjian's avatar
Bruce Momjian committed
64 65
	assert((fileFlags & ((O_RDONLY | O_WRONLY | O_RDWR) | O_APPEND |
						 (O_RANDOM | O_SEQUENTIAL | O_TEMPORARY) |
66
						 _O_SHORT_LIVED | O_SYNC |
Bruce Momjian's avatar
Bruce Momjian committed
67
	  (O_CREAT | O_TRUNC | O_EXCL) | (O_TEXT | O_BINARY))) == fileFlags);
68

Bruce Momjian's avatar
Bruce Momjian committed
69 70 71
	sa.nLength = sizeof(sa);
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = NULL;
72 73

	if ((h = CreateFile(fileName,
Bruce Momjian's avatar
Bruce Momjian committed
74 75 76
	/* cannot use O_RDONLY, as it == 0 */
				  (fileFlags & O_RDWR) ? (GENERIC_WRITE | GENERIC_READ) :
				 ((fileFlags & O_WRONLY) ? GENERIC_WRITE : GENERIC_READ),
77
				/* These flags allow concurrent rename/unlink */
Bruce Momjian's avatar
Bruce Momjian committed
78
				(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),
79 80
						&sa,
						openFlagsToCreateFileFlags(fileFlags),
Bruce Momjian's avatar
Bruce Momjian committed
81 82 83 84
						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) |
85 86
			 ((fileFlags & O_TEMPORARY) ? FILE_FLAG_DELETE_ON_CLOSE : 0)|
					((fileFlags & O_SYNC) ? FILE_FLAG_WRITE_THROUGH : 0),
87 88 89 90
						NULL)) == INVALID_HANDLE_VALUE)
	{
		switch (GetLastError())
		{
Bruce Momjian's avatar
Bruce Momjian committed
91
				/* EMFILE, ENFILE should not occur from CreateFile. */
92
			case ERROR_PATH_NOT_FOUND:
Bruce Momjian's avatar
Bruce Momjian committed
93 94 95 96 97 98 99 100 101
			case ERROR_FILE_NOT_FOUND:
				errno = ENOENT;
				break;
			case ERROR_FILE_EXISTS:
				errno = EEXIST;
				break;
			case ERROR_ACCESS_DENIED:
				errno = EACCES;
				break;
102 103 104 105 106 107 108
			default:
				errno = EINVAL;
		}
		return -1;
	}

	/* _open_osfhandle will, on error, set errno accordingly */
Bruce Momjian's avatar
Bruce Momjian committed
109 110 111
	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 */
112 113 114 115
	return fd;
}

#endif