postgresql/src/port/open.c

152 lines
3.6 KiB
C
Raw Normal View History

/*-------------------------------------------------------------------------
*
* open.c
* Win32 open() replacement
*
*
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/port/open.c,v 1.20 2007/04/13 10:30:30 mha Exp $
*
*-------------------------------------------------------------------------
*/
#ifdef WIN32
#include "c.h"
#include <windows.h>
#include <fcntl.h>
#include <assert.h>
static int
openFlagsToCreateFileFlags(int openFlags)
{
2004-08-29 07:07:03 +02:00
switch (openFlags & (O_CREAT | O_TRUNC | O_EXCL))
{
/* O_EXCL is meaningless without O_CREAT */
case 0:
2004-08-29 07:07:03 +02:00
case O_EXCL:
return OPEN_EXISTING;
2004-08-29 07:07:03 +02:00
case O_CREAT:
return OPEN_ALWAYS;
/* O_EXCL is meaningless without O_CREAT */
case O_TRUNC:
2004-08-29 07:07:03 +02:00
case O_TRUNC | O_EXCL:
return TRUNCATE_EXISTING;
2004-08-29 07:07:03 +02:00
case O_CREAT | O_TRUNC:
return CREATE_ALWAYS;
/* O_TRUNC is meaningless with O_CREAT */
2004-08-29 07:07:03 +02:00
case O_CREAT | O_EXCL:
case O_CREAT | O_TRUNC | O_EXCL:
return CREATE_NEW;
}
/* will never get here */
return 0;
}
/*
2004-08-29 07:07:03 +02:00
* - file attribute setting, based on fileMode?
*/
2004-08-29 07:07:03 +02:00
int
pgwin32_open(const char *fileName, int fileFlags,...)
{
2004-08-29 07:07:03 +02:00
int fd;
HANDLE h;
SECURITY_ATTRIBUTES sa;
/* Check that we can handle the request */
2004-08-29 07:07:03 +02:00
assert((fileFlags & ((O_RDONLY | O_WRONLY | O_RDWR) | O_APPEND |
(O_RANDOM | O_SEQUENTIAL | O_TEMPORARY) |
_O_SHORT_LIVED | O_DSYNC | O_DIRECT |
2005-10-15 04:49:52 +02:00
(O_CREAT | O_TRUNC | O_EXCL) | (O_TEXT | O_BINARY))) == fileFlags);
2004-08-29 07:07:03 +02:00
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
if ((h = CreateFile(fileName,
2004-08-29 07:07:03 +02:00
/* cannot use O_RDONLY, as it == 0 */
2005-10-15 04:49:52 +02:00
(fileFlags & O_RDWR) ? (GENERIC_WRITE | GENERIC_READ) :
((fileFlags & O_WRONLY) ? GENERIC_WRITE : GENERIC_READ),
/* These flags allow concurrent rename/unlink */
(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),
&sa,
openFlagsToCreateFileFlags(fileFlags),
2004-08-29 07:07:03 +02:00
FILE_ATTRIBUTE_NORMAL |
2005-10-15 04:49:52 +02:00
((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) |
((fileFlags & O_DIRECT) ? FILE_FLAG_NO_BUFFERING : 0) |
((fileFlags & O_DSYNC) ? FILE_FLAG_WRITE_THROUGH : 0),
NULL)) == INVALID_HANDLE_VALUE)
{
switch (GetLastError())
{
2004-08-29 07:07:03 +02:00
/* EMFILE, ENFILE should not occur from CreateFile. */
case ERROR_PATH_NOT_FOUND:
2004-08-29 07:07:03 +02:00
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)
2004-08-29 07:07:03 +02:00
CloseHandle(h); /* will not affect errno */
else if (fileFlags & (O_TEXT | O_BINARY) &&
2006-10-04 02:30:14 +02:00
_setmode(fd, fileFlags & (O_TEXT | O_BINARY)) < 0)
{
_close(fd);
return -1;
}
return fd;
}
FILE *
pgwin32_fopen(const char *fileName, const char *mode)
{
2006-10-04 02:30:14 +02:00
int openmode = 0;
int fd;
if (strstr(mode, "r+"))
openmode |= O_RDWR;
else if (strchr(mode, 'r'))
openmode |= O_RDONLY;
if (strstr(mode, "w+"))
openmode |= O_RDWR | O_CREAT | O_TRUNC;
else if (strchr(mode, 'w'))
openmode |= O_WRONLY | O_CREAT | O_TRUNC;
if (strchr(mode, 'a'))
openmode |= O_WRONLY | O_CREAT | O_APPEND;
if (strchr(mode, 'b'))
openmode |= O_BINARY;
if (strchr(mode, 't'))
openmode |= O_TEXT;
2006-10-04 02:30:14 +02:00
fd = pgwin32_open(fileName, openmode);
if (fd == -1)
return NULL;
return _fdopen(fd, mode);
}
#endif