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