]> granicus.if.org Git - postgresql/blob - src/port/open.c
Fix Win32/Cygwin problems:
[postgresql] / src / port / open.c
1 /*-------------------------------------------------------------------------
2  *
3  * open.c
4  *         Win32 open() replacement
5  *
6  *
7  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
8  *
9  * $PostgreSQL: pgsql/src/port/open.c,v 1.13 2006/06/25 00:18:24 momjian Exp $
10  *
11  *-------------------------------------------------------------------------
12  */
13
14 #ifdef WIN32
15
16 #include "c.h"
17
18 #include <windows.h>
19 #include <fcntl.h>
20 #include <assert.h>
21
22 int                     pgwin32_open(const char *fileName, int fileFlags,...);
23
24 static int
25 openFlagsToCreateFileFlags(int openFlags)
26 {
27         switch (openFlags & (O_CREAT | O_TRUNC | O_EXCL))
28         {
29                 case 0:
30                 case O_EXCL:
31                         return OPEN_EXISTING;
32
33                 case O_CREAT:
34                         return OPEN_ALWAYS;
35
36                 case O_TRUNC:
37                 case O_TRUNC | O_EXCL:
38                         return TRUNCATE_EXISTING;
39
40                 case O_CREAT | O_TRUNC:
41                         return CREATE_ALWAYS;
42
43                 case O_CREAT | O_EXCL:
44                 case O_CREAT | O_TRUNC | O_EXCL:
45                         return CREATE_NEW;
46         }
47
48         /* will never get here */
49         return 0;
50 }
51
52 /*
53  *       - file attribute setting, based on fileMode?
54  *       - handle other flags? (eg FILE_FLAG_NO_BUFFERING/FILE_FLAG_WRITE_THROUGH)
55  */
56 int
57 pgwin32_open(const char *fileName, int fileFlags,...)
58 {
59         int                     fd;
60         HANDLE          h;
61         SECURITY_ATTRIBUTES sa;
62
63         /* Check that we can handle the request */
64         assert((fileFlags & ((O_RDONLY | O_WRONLY | O_RDWR) | O_APPEND |
65                                                  (O_RANDOM | O_SEQUENTIAL | O_TEMPORARY) |
66                                                  _O_SHORT_LIVED | O_DSYNC |
67                   (O_CREAT | O_TRUNC | O_EXCL) | (O_TEXT | O_BINARY))) == fileFlags);
68
69         sa.nLength = sizeof(sa);
70         sa.bInheritHandle = TRUE;
71         sa.lpSecurityDescriptor = NULL;
72
73         if ((h = CreateFile(fileName,
74         /* cannot use O_RDONLY, as it == 0 */
75                                           (fileFlags & O_RDWR) ? (GENERIC_WRITE | GENERIC_READ) :
76                                          ((fileFlags & O_WRONLY) ? GENERIC_WRITE : GENERIC_READ),
77         /* These flags allow concurrent rename/unlink */
78                                         (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),
79                                                 &sa,
80                                                 openFlagsToCreateFileFlags(fileFlags),
81                                                 FILE_ATTRIBUTE_NORMAL |
82                                          ((fileFlags & O_RANDOM) ? FILE_FLAG_RANDOM_ACCESS : 0) |
83                            ((fileFlags & O_SEQUENTIAL) ? FILE_FLAG_SEQUENTIAL_SCAN : 0) |
84                           ((fileFlags & _O_SHORT_LIVED) ? FILE_ATTRIBUTE_TEMPORARY : 0) |
85                                 ((fileFlags & O_TEMPORARY) ? FILE_FLAG_DELETE_ON_CLOSE : 0) |
86                                                 ((fileFlags & O_DSYNC) ? FILE_FLAG_WRITE_THROUGH : 0),
87                                                 NULL)) == INVALID_HANDLE_VALUE)
88         {
89                 switch (GetLastError())
90                 {
91                                 /* EMFILE, ENFILE should not occur from CreateFile. */
92                         case ERROR_PATH_NOT_FOUND:
93                         case ERROR_FILE_NOT_FOUND:
94                                 errno = ENOENT;
95                                 break;
96                         case ERROR_FILE_EXISTS:
97                                 errno = EEXIST;
98                                 break;
99                         case ERROR_ACCESS_DENIED:
100                                 errno = EACCES;
101                                 break;
102                         default:
103                                 errno = EINVAL;
104                 }
105                 return -1;
106         }
107
108         /* _open_osfhandle will, on error, set errno accordingly */
109         if ((fd = _open_osfhandle((long) h, fileFlags & O_APPEND)) < 0 ||
110                 (fileFlags & (O_TEXT | O_BINARY) && (_setmode(fd, fileFlags & (O_TEXT | O_BINARY)) < 0)))
111                 CloseHandle(h);                 /* will not affect errno */
112         return fd;
113 }
114
115 #endif