Fix pg_dump bug in the database-level collation patch. "datcollate" and
[PostgreSQL.git] / src / port / open.c
blob3aa064208da6f2ab58691dcd712a89afbb9b7c18
1 /*-------------------------------------------------------------------------
3 * open.c
4 * Win32 open() replacement
7 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
9 * $PostgreSQL$
11 *-------------------------------------------------------------------------
14 #ifdef WIN32
16 #ifndef FRONTEND
17 #include "postgres.h"
18 #else
19 #include "postgres_fe.h"
20 #endif
22 #include <windows.h>
23 #include <fcntl.h>
24 #include <assert.h>
27 static int
28 openFlagsToCreateFileFlags(int openFlags)
30 switch (openFlags & (O_CREAT | O_TRUNC | O_EXCL))
32 /* O_EXCL is meaningless without O_CREAT */
33 case 0:
34 case O_EXCL:
35 return OPEN_EXISTING;
37 case O_CREAT:
38 return OPEN_ALWAYS;
40 /* O_EXCL is meaningless without O_CREAT */
41 case O_TRUNC:
42 case O_TRUNC | O_EXCL:
43 return TRUNCATE_EXISTING;
45 case O_CREAT | O_TRUNC:
46 return CREATE_ALWAYS;
48 /* O_TRUNC is meaningless with O_CREAT */
49 case O_CREAT | O_EXCL:
50 case O_CREAT | O_TRUNC | O_EXCL:
51 return CREATE_NEW;
54 /* will never get here */
55 return 0;
59 * - file attribute setting, based on fileMode?
61 int
62 pgwin32_open(const char *fileName, int fileFlags,...)
64 int fd;
65 HANDLE h = INVALID_HANDLE_VALUE;
66 SECURITY_ATTRIBUTES sa;
67 int loops = 0;
69 /* Check that we can handle the request */
70 assert((fileFlags & ((O_RDONLY | O_WRONLY | O_RDWR) | O_APPEND |
71 (O_RANDOM | O_SEQUENTIAL | O_TEMPORARY) |
72 _O_SHORT_LIVED | O_DSYNC | O_DIRECT |
73 (O_CREAT | O_TRUNC | O_EXCL) | (O_TEXT | O_BINARY))) == fileFlags);
75 sa.nLength = sizeof(sa);
76 sa.bInheritHandle = TRUE;
77 sa.lpSecurityDescriptor = NULL;
79 while ((h = CreateFile(fileName,
80 /* cannot use O_RDONLY, as it == 0 */
81 (fileFlags & O_RDWR) ? (GENERIC_WRITE | GENERIC_READ) :
82 ((fileFlags & O_WRONLY) ? GENERIC_WRITE : GENERIC_READ),
83 /* These flags allow concurrent rename/unlink */
84 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),
85 &sa,
86 openFlagsToCreateFileFlags(fileFlags),
87 FILE_ATTRIBUTE_NORMAL |
88 ((fileFlags & O_RANDOM) ? FILE_FLAG_RANDOM_ACCESS : 0) |
89 ((fileFlags & O_SEQUENTIAL) ? FILE_FLAG_SEQUENTIAL_SCAN : 0) |
90 ((fileFlags & _O_SHORT_LIVED) ? FILE_ATTRIBUTE_TEMPORARY : 0) |
91 ((fileFlags & O_TEMPORARY) ? FILE_FLAG_DELETE_ON_CLOSE : 0) |
92 ((fileFlags & O_DIRECT) ? FILE_FLAG_NO_BUFFERING : 0) |
93 ((fileFlags & O_DSYNC) ? FILE_FLAG_WRITE_THROUGH : 0),
94 NULL)) == INVALID_HANDLE_VALUE)
97 * Sharing violation or locking error can indicate antivirus, backup
98 * or similar software that's locking the file. Try again for 30 seconds
99 * before giving up.
101 DWORD err = GetLastError();
102 if (err == ERROR_SHARING_VIOLATION ||
103 err == ERROR_LOCK_VIOLATION)
105 pg_usleep(100000);
106 loops++;
108 #ifndef FRONTEND
109 if (loops == 50)
110 ereport(LOG,
111 (errmsg("could not open file \"%s\": %s", fileName,
112 (err == ERROR_SHARING_VIOLATION)?_("sharing violation"):_("lock violation")),
113 errdetail("Continuing to retry for 30 seconds."),
114 errhint("You might have antivirus, backup, or similar software interfering with the database system.")));
115 #endif
117 if (loops < 300)
118 continue;
121 _dosmaperr(err);
122 return -1;
125 /* _open_osfhandle will, on error, set errno accordingly */
126 if ((fd = _open_osfhandle((long) h, fileFlags & O_APPEND)) < 0)
127 CloseHandle(h); /* will not affect errno */
128 else if (fileFlags & (O_TEXT | O_BINARY) &&
129 _setmode(fd, fileFlags & (O_TEXT | O_BINARY)) < 0)
131 _close(fd);
132 return -1;
135 return fd;
138 FILE *
139 pgwin32_fopen(const char *fileName, const char *mode)
141 int openmode = 0;
142 int fd;
144 if (strstr(mode, "r+"))
145 openmode |= O_RDWR;
146 else if (strchr(mode, 'r'))
147 openmode |= O_RDONLY;
148 if (strstr(mode, "w+"))
149 openmode |= O_RDWR | O_CREAT | O_TRUNC;
150 else if (strchr(mode, 'w'))
151 openmode |= O_WRONLY | O_CREAT | O_TRUNC;
152 if (strchr(mode, 'a'))
153 openmode |= O_WRONLY | O_CREAT | O_APPEND;
155 if (strchr(mode, 'b'))
156 openmode |= O_BINARY;
157 if (strchr(mode, 't'))
158 openmode |= O_TEXT;
160 fd = pgwin32_open(fileName, openmode);
161 if (fd == -1)
162 return NULL;
163 return _fdopen(fd, mode);
166 #endif