25 #if defined(WIN32) || defined(__CYGWIN__)
33 #if defined(WIN32) || defined(__CYGWIN__)
38 #include <w32api/winioctl.h>
42 #if defined(WIN32) && !defined(__CYGWIN__)
46 #if defined(WIN32) || defined(__CYGWIN__)
52 pgrename(
const char *from,
const char *to)
63 #if defined(WIN32) && !defined(__CYGWIN__)
64 while (!MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING))
66 while (rename(from, to) < 0)
69 #if defined(WIN32) && !defined(__CYGWIN__)
70 DWORD
err = GetLastError();
82 if (
err != ERROR_ACCESS_DENIED &&
83 err != ERROR_SHARING_VIOLATION &&
84 err != ERROR_LOCK_VIOLATION)
104 lstat_error_was_status_delete_pending(
void)
108 #if defined(WIN32) && !defined(__CYGWIN__)
119 pgunlink(
const char *path)
132 if (unlink(path) == 0)
153 if (
lstat(path, &st) < 0)
155 if (lstat_error_was_status_delete_pending())
170 while ((is_lnk ? rmdir(path) : unlink(path)) < 0)
182 #define rename(from, to) pgrename(from, to)
183 #define unlink(path) pgunlink(path)
187 #if defined(WIN32) && !defined(__CYGWIN__)
199 WORD ReparseDataLength;
202 WORD SubstituteNameOffset;
203 WORD SubstituteNameLength;
204 WORD PrintNameOffset;
205 WORD PrintNameLength;
207 } REPARSE_JUNCTION_DATA_BUFFER;
209 #define REPARSE_JUNCTION_DATA_BUFFER_HEADER_SIZE \
210 FIELD_OFFSET(REPARSE_JUNCTION_DATA_BUFFER, SubstituteNameOffset)
219 pgsymlink(
const char *oldpath,
const char *newpath)
223 char buffer[MAX_PATH *
sizeof(WCHAR) + offsetof(REPARSE_JUNCTION_DATA_BUFFER, PathBuffer)];
224 char nativeTarget[MAX_PATH];
225 char *p = nativeTarget;
226 REPARSE_JUNCTION_DATA_BUFFER *reparseBuf = (REPARSE_JUNCTION_DATA_BUFFER *) buffer;
228 CreateDirectory(newpath, 0);
229 dirhandle = CreateFile(newpath, GENERIC_READ | GENERIC_WRITE,
231 FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0);
233 if (dirhandle == INVALID_HANDLE_VALUE)
240 if (memcmp(
"\\??\\", oldpath, 4) != 0)
241 snprintf(nativeTarget,
sizeof(nativeTarget),
"\\??\\%s", oldpath);
243 strlcpy(nativeTarget, oldpath,
sizeof(nativeTarget));
245 while ((p = strchr(p,
'/')) != NULL)
248 len = strlen(nativeTarget) *
sizeof(WCHAR);
249 reparseBuf->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
250 reparseBuf->ReparseDataLength =
len + 12;
251 reparseBuf->Reserved = 0;
252 reparseBuf->SubstituteNameOffset = 0;
253 reparseBuf->SubstituteNameLength =
len;
254 reparseBuf->PrintNameOffset =
len +
sizeof(WCHAR);
255 reparseBuf->PrintNameLength = 0;
256 MultiByteToWideChar(CP_ACP, 0, nativeTarget, -1,
257 reparseBuf->PathBuffer, MAX_PATH);
263 if (!DeviceIoControl(dirhandle,
264 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_ANY_ACCESS),
266 reparseBuf->ReparseDataLength + REPARSE_JUNCTION_DATA_BUFFER_HEADER_SIZE,
275 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
276 FORMAT_MESSAGE_IGNORE_INSERTS |
277 FORMAT_MESSAGE_FROM_SYSTEM,
278 NULL, GetLastError(),
279 MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
280 (LPSTR) &msg, 0, NULL);
284 errmsg(
"could not set junction for \"%s\": %s",
285 nativeTarget, msg)));
287 fprintf(stderr,
_(
"could not set junction for \"%s\": %s\n"),
292 CloseHandle(dirhandle);
293 RemoveDirectory(newpath);
300 CloseHandle(dirhandle);
313 char buffer[MAX_PATH *
sizeof(WCHAR) + offsetof(REPARSE_JUNCTION_DATA_BUFFER, PathBuffer)];
314 REPARSE_JUNCTION_DATA_BUFFER *reparseBuf = (REPARSE_JUNCTION_DATA_BUFFER *) buffer;
318 attr = GetFileAttributes(path);
319 if (attr == INVALID_FILE_ATTRIBUTES)
324 if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) == 0)
332 FILE_SHARE_READ | FILE_SHARE_WRITE,
335 FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
337 if (h == INVALID_HANDLE_VALUE)
343 if (!DeviceIoControl(h,
344 FSCTL_GET_REPARSE_POINT,
355 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
356 FORMAT_MESSAGE_IGNORE_INSERTS |
357 FORMAT_MESSAGE_FROM_SYSTEM,
358 NULL, GetLastError(),
359 MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
360 (LPSTR) &msg, 0, NULL);
364 errmsg(
"could not get junction for \"%s\": %s",
367 fprintf(stderr,
_(
"could not get junction for \"%s\": %s\n"),
378 if (reparseBuf->ReparseTag != IO_REPARSE_TAG_MOUNT_POINT)
384 r = WideCharToMultiByte(CP_ACP, 0,
385 reparseBuf->PathBuffer, -1,
416 memmove(
buf,
buf + 4, strlen(
buf + 4) + 1);
#define FLEXIBLE_ARRAY_MEMBER
int errcode_for_file_access(void)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void err(int eval, const char *fmt,...)
size_t strlcpy(char *dst, const char *src, size_t siz)
void pg_usleep(long microsec)
static pg_noinline void Size size
void _dosmaperr(unsigned long)
int pgreadlink(const char *path, char *buf, size_t size)
int pgsymlink(const char *oldpath, const char *newpath)
PGDLLIMPORT RtlGetLastNtStatus_t pg_RtlGetLastNtStatus