1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-21 00:42:43 +03:00
Files
postgres/src/port/win32error.c
Magnus Hagander 9951741bbe Attempt to handle pending-delete files on Windows
These files are deleted but not yet gone from the filesystem. Operations
on them will return ERROR_DELETE_PENDING.

With this we start treating that as ENOENT, meaning files does not
exist (which is the state it will soon reach). This should be safe in
every case except when we try to recreate a file with exactly the same
name. This is an operation that PostgreSQL does very seldom, so
hopefully that won't happen much -- and even if it does, this treatment
should be no worse than treating it as an unhandled error.

We've been un able to reproduce the bug reliably, so pushing this to
master to get buildfarm coverage and other testing. Once it's proven to
be stable, it should be considered for backpatching.

Discussion: https://postgr.es/m/20160712083220.1426.58667%40wrigleys.postgresql.org

Patch by me and Michael Paquier
2017-01-04 10:48:30 +01:00

210 lines
2.9 KiB
C

/*-------------------------------------------------------------------------
*
* win32error.c
* Map win32 error codes to errno values
*
* Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/port/win32error.c
*
*-------------------------------------------------------------------------
*/
#ifndef FRONTEND
#include "postgres.h"
#else
#include "postgres_fe.h"
#endif
static const struct
{
DWORD winerr;
int doserr;
} doserrors[] =
{
{
ERROR_INVALID_FUNCTION, EINVAL
},
{
ERROR_FILE_NOT_FOUND, ENOENT
},
{
ERROR_PATH_NOT_FOUND, ENOENT
},
{
ERROR_TOO_MANY_OPEN_FILES, EMFILE
},
{
ERROR_ACCESS_DENIED, EACCES
},
{
ERROR_INVALID_HANDLE, EBADF
},
{
ERROR_ARENA_TRASHED, ENOMEM
},
{
ERROR_NOT_ENOUGH_MEMORY, ENOMEM
},
{
ERROR_INVALID_BLOCK, ENOMEM
},
{
ERROR_BAD_ENVIRONMENT, E2BIG
},
{
ERROR_BAD_FORMAT, ENOEXEC
},
{
ERROR_INVALID_ACCESS, EINVAL
},
{
ERROR_INVALID_DATA, EINVAL
},
{
ERROR_INVALID_DRIVE, ENOENT
},
{
ERROR_CURRENT_DIRECTORY, EACCES
},
{
ERROR_NOT_SAME_DEVICE, EXDEV
},
{
ERROR_NO_MORE_FILES, ENOENT
},
{
ERROR_LOCK_VIOLATION, EACCES
},
{
ERROR_SHARING_VIOLATION, EACCES
},
{
ERROR_BAD_NETPATH, ENOENT
},
{
ERROR_NETWORK_ACCESS_DENIED, EACCES
},
{
ERROR_BAD_NET_NAME, ENOENT
},
{
ERROR_FILE_EXISTS, EEXIST
},
{
ERROR_CANNOT_MAKE, EACCES
},
{
ERROR_FAIL_I24, EACCES
},
{
ERROR_INVALID_PARAMETER, EINVAL
},
{
ERROR_NO_PROC_SLOTS, EAGAIN
},
{
ERROR_DRIVE_LOCKED, EACCES
},
{
ERROR_BROKEN_PIPE, EPIPE
},
{
ERROR_DISK_FULL, ENOSPC
},
{
ERROR_INVALID_TARGET_HANDLE, EBADF
},
{
ERROR_INVALID_HANDLE, EINVAL
},
{
ERROR_WAIT_NO_CHILDREN, ECHILD
},
{
ERROR_CHILD_NOT_COMPLETE, ECHILD
},
{
ERROR_DIRECT_ACCESS_HANDLE, EBADF
},
{
ERROR_NEGATIVE_SEEK, EINVAL
},
{
ERROR_SEEK_ON_DEVICE, EACCES
},
{
ERROR_DIR_NOT_EMPTY, ENOTEMPTY
},
{
ERROR_NOT_LOCKED, EACCES
},
{
ERROR_BAD_PATHNAME, ENOENT
},
{
ERROR_MAX_THRDS_REACHED, EAGAIN
},
{
ERROR_LOCK_FAILED, EACCES
},
{
ERROR_ALREADY_EXISTS, EEXIST
},
{
ERROR_FILENAME_EXCED_RANGE, ENOENT
},
{
ERROR_NESTING_NOT_ALLOWED, EAGAIN
},
{
ERROR_NOT_ENOUGH_QUOTA, ENOMEM
},
{
ERROR_DELETE_PENDING, ENOENT
}
};
void
_dosmaperr(unsigned long e)
{
int i;
if (e == 0)
{
errno = 0;
return;
}
for (i = 0; i < lengthof(doserrors); i++)
{
if (doserrors[i].winerr == e)
{
int doserr = doserrors[i].doserr;
#ifndef FRONTEND
ereport(DEBUG5,
(errmsg_internal("mapped win32 error code %lu to %d",
e, doserr)));
#elif FRONTEND_DEBUG
fprintf(stderr, "mapped win32 error code %lu to %d", e, doserr);
#endif
errno = doserr;
return;
}
}
#ifndef FRONTEND
ereport(LOG,
(errmsg_internal("unrecognized win32 error code: %lu",
e)));
#else
fprintf(stderr, "unrecognized win32 error code: %lu", e);
#endif
errno = EINVAL;
return;
}