1 /*-------------------------------------------------------------------------
4 * Win32 open() replacement
7 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
11 *-------------------------------------------------------------------------
19 #include "postgres_fe.h"
28 openFlagsToCreateFileFlags(int openFlags
)
30 switch (openFlags
& (O_CREAT
| O_TRUNC
| O_EXCL
))
32 /* O_EXCL is meaningless without O_CREAT */
40 /* O_EXCL is meaningless without O_CREAT */
42 case O_TRUNC
| O_EXCL
:
43 return TRUNCATE_EXISTING
;
45 case O_CREAT
| O_TRUNC
:
48 /* O_TRUNC is meaningless with O_CREAT */
49 case O_CREAT
| O_EXCL
:
50 case O_CREAT
| O_TRUNC
| O_EXCL
:
54 /* will never get here */
59 * - file attribute setting, based on fileMode?
62 pgwin32_open(const char *fileName
, int fileFlags
,...)
65 HANDLE h
= INVALID_HANDLE_VALUE
;
66 SECURITY_ATTRIBUTES sa
;
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 Assert(pgwin32_signal_event
!= NULL
); /* small chance of pg_usleep() */
81 * Since PostgreSQL 12, those concurrent-safe versions of open() and
82 * fopen() can be used by frontends, having as side-effect to switch the
83 * file-translation mode from O_TEXT to O_BINARY if none is specified.
84 * Caller may want to enforce the binary or text mode, but if nothing is
85 * defined make sure that the default mode maps with what versions older
86 * than 12 have been doing.
88 if ((fileFlags
& O_BINARY
) == 0)
92 sa
.nLength
= sizeof(sa
);
93 sa
.bInheritHandle
= TRUE
;
94 sa
.lpSecurityDescriptor
= NULL
;
96 while ((h
= CreateFile(fileName
,
97 /* cannot use O_RDONLY, as it == 0 */
98 (fileFlags
& O_RDWR
) ? (GENERIC_WRITE
| GENERIC_READ
) :
99 ((fileFlags
& O_WRONLY
) ? GENERIC_WRITE
: GENERIC_READ
),
100 /* These flags allow concurrent rename/unlink */
101 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
),
103 openFlagsToCreateFileFlags(fileFlags
),
104 FILE_ATTRIBUTE_NORMAL
|
105 ((fileFlags
& O_RANDOM
) ? FILE_FLAG_RANDOM_ACCESS
: 0) |
106 ((fileFlags
& O_SEQUENTIAL
) ? FILE_FLAG_SEQUENTIAL_SCAN
: 0) |
107 ((fileFlags
& _O_SHORT_LIVED
) ? FILE_ATTRIBUTE_TEMPORARY
: 0) |
108 ((fileFlags
& O_TEMPORARY
) ? FILE_FLAG_DELETE_ON_CLOSE
: 0) |
109 ((fileFlags
& O_DIRECT
) ? FILE_FLAG_NO_BUFFERING
: 0) |
110 ((fileFlags
& O_DSYNC
) ? FILE_FLAG_WRITE_THROUGH
: 0),
111 NULL
)) == INVALID_HANDLE_VALUE
)
114 * Sharing violation or locking error can indicate antivirus, backup
115 * or similar software that's locking the file. Wait a bit and try
116 * again, giving up after 30 seconds.
118 DWORD err
= GetLastError();
120 if (err
== ERROR_SHARING_VIOLATION
||
121 err
== ERROR_LOCK_VIOLATION
)
126 (errmsg("could not open file \"%s\": %s", fileName
,
127 (err
== ERROR_SHARING_VIOLATION
) ? _("sharing violation") : _("lock violation")),
128 errdetail("Continuing to retry for 30 seconds."),
129 errhint("You might have antivirus, backup, or similar software interfering with the database system.")));
141 * ERROR_ACCESS_DENIED is returned if the file is deleted but not yet
142 * gone (Windows NT status code is STATUS_DELETE_PENDING). In that
143 * case we want to wait a bit and try again, giving up after 1 second
144 * (since this condition should never persist very long). However,
145 * there are other commonly-hit cases that return ERROR_ACCESS_DENIED,
146 * so care is needed. In particular that happens if we try to open a
147 * directory, or of course if there's an actual file-permissions
148 * problem. To distinguish these cases, try a stat(). In the
149 * delete-pending case, it will either also get STATUS_DELETE_PENDING,
150 * or it will see the file as gone and fail with ENOENT. In other
151 * cases it will usually succeed. The only somewhat-likely case where
152 * this coding will uselessly wait is if there's a permissions problem
153 * with a containing directory, which we hope will never happen in any
154 * performance-critical code paths.
156 if (err
== ERROR_ACCESS_DENIED
)
162 if (stat(fileName
, &st
) != 0)
175 /* _open_osfhandle will, on error, set errno accordingly */
176 if ((fd
= _open_osfhandle((intptr_t) h
, fileFlags
& O_APPEND
)) < 0)
177 CloseHandle(h
); /* will not affect errno */
178 else if (fileFlags
& (O_TEXT
| O_BINARY
) &&
179 _setmode(fd
, fileFlags
& (O_TEXT
| O_BINARY
)) < 0)
189 pgwin32_fopen(const char *fileName
, const char *mode
)
194 if (strstr(mode
, "r+"))
196 else if (strchr(mode
, 'r'))
197 openmode
|= O_RDONLY
;
198 if (strstr(mode
, "w+"))
199 openmode
|= O_RDWR
| O_CREAT
| O_TRUNC
;
200 else if (strchr(mode
, 'w'))
201 openmode
|= O_WRONLY
| O_CREAT
| O_TRUNC
;
202 if (strchr(mode
, 'a'))
203 openmode
|= O_WRONLY
| O_CREAT
| O_APPEND
;
205 if (strchr(mode
, 'b'))
206 openmode
|= O_BINARY
;
207 if (strchr(mode
, 't'))
210 fd
= pgwin32_open(fileName
, openmode
);
213 return _fdopen(fd
, mode
);