00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <config.h>
00024
00025 #ifdef __WIN32__
00026
00027 #include "msvc_posix_wrapper.h"
00028
00029 #include <io.h>
00030
00031 #include "safeerrno.h"
00032 #include "safefcntl.h"
00033 #include "safewindows.h"
00034
00036 static int
00037 msvc_set_errno_from_getlasterror()
00038 {
00039 int e;
00040 unsigned long winerr = GetLastError();
00041 switch (winerr) {
00042 case ERROR_FILENAME_EXCED_RANGE:
00043 case ERROR_FILE_NOT_FOUND:
00044 case ERROR_PATH_NOT_FOUND:
00045 case ERROR_INVALID_DRIVE:
00046 case ERROR_NO_MORE_FILES:
00047 case ERROR_BAD_NETPATH:
00048 case ERROR_BAD_NET_NAME:
00049 case ERROR_BAD_PATHNAME:
00050 e = ENOENT;
00051 break;
00052 case ERROR_ARENA_TRASHED:
00053 case ERROR_NOT_ENOUGH_MEMORY:
00054 case ERROR_INVALID_BLOCK:
00055 case ERROR_NOT_ENOUGH_QUOTA:
00056 e = ENOMEM;
00057 break;
00058 case ERROR_LOCK_VIOLATION:
00059 case ERROR_LOCK_FAILED:
00060 case ERROR_SEEK_ON_DEVICE:
00061 case ERROR_NETWORK_ACCESS_DENIED:
00062 case ERROR_NOT_LOCKED:
00063 case ERROR_ACCESS_DENIED:
00064 case ERROR_CANNOT_MAKE:
00065 case ERROR_FAIL_I24:
00066 case ERROR_DRIVE_LOCKED:
00067 case ERROR_CURRENT_DIRECTORY:
00068 e = EACCES;
00069 break;
00070 case ERROR_INVALID_FUNCTION:
00071 case ERROR_INVALID_ACCESS:
00072 case ERROR_NEGATIVE_SEEK:
00073 case ERROR_INVALID_DATA:
00074 case ERROR_INVALID_PARAMETER:
00075 e = EINVAL;
00076 break;
00077 case ERROR_NO_PROC_SLOTS:
00078 case ERROR_NESTING_NOT_ALLOWED:
00079 case ERROR_MAX_THRDS_REACHED:
00080 e = EAGAIN;
00081 break;
00082 case ERROR_INVALID_HANDLE:
00083 case ERROR_INVALID_TARGET_HANDLE:
00084 case ERROR_DIRECT_ACCESS_HANDLE:
00085 e = EBADF;
00086 break;
00087 case ERROR_ALREADY_EXISTS:
00088 case ERROR_FILE_EXISTS:
00089 e = EEXIST;
00090 break;
00091 case ERROR_BROKEN_PIPE:
00092 e = EPIPE;
00093 break;
00094 case ERROR_DISK_FULL:
00095 e = ENOSPC;
00096 break;
00097 case ERROR_TOO_MANY_OPEN_FILES:
00098 e = EMFILE;
00099 break;
00100 case ERROR_WAIT_NO_CHILDREN:
00101 case ERROR_CHILD_NOT_COMPLETE:
00102 e = ECHILD;
00103 break;
00104 case ERROR_DIR_NOT_EMPTY:
00105 e = ENOTEMPTY;
00106 break;
00107 case ERROR_BAD_ENVIRONMENT:
00108 e = E2BIG;
00109 break;
00110 case ERROR_BAD_FORMAT:
00111 e = ENOEXEC;
00112 break;
00113 case ERROR_NOT_SAME_DEVICE:
00114 e = EXDEV;
00115 break;
00116 default:
00117 if (winerr >= ERROR_WRITE_PROTECT && winerr <= ERROR_SHARING_BUFFER_EXCEEDED)
00118 e = EACCES;
00119 else if (winerr >= ERROR_INVALID_STARTING_CODESEG && winerr <= ERROR_INFLOOP_IN_RELOC_CHAIN)
00120 e = ENOEXEC;
00121 else
00122 e = EINVAL;
00123 break;
00124 }
00125
00126
00127 #ifdef _set_errno
00128 _set_errno(e);
00129 #else
00130 errno = e;
00131 #endif
00132 return -1;
00133 }
00134
00139 int
00140 msvc_posix_unlink(const char * filename)
00141 {
00142
00143 if (DeleteFile(filename) != 0) {
00144 return 0;
00145 }
00146
00147 return msvc_set_errno_from_getlasterror();
00148 }
00149
00151 int
00152 msvc_posix_open(const char *filename, int flags)
00153 {
00154
00155 DWORD dwDesiredAccess = GENERIC_READ;
00156 switch (flags & (O_RDONLY | O_RDWR | O_WRONLY)) {
00157 case O_RDONLY:
00158 dwDesiredAccess = GENERIC_READ;
00159 break;
00160 case O_RDWR:
00161 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
00162 break;
00163 case O_WRONLY:
00164 dwDesiredAccess = GENERIC_WRITE;
00165 break;
00166 }
00167
00168 DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
00169
00170
00171 DWORD dwCreationDisposition = OPEN_EXISTING;
00172 switch (flags & (O_CREAT | O_TRUNC | O_EXCL)) {
00173 case O_EXCL:
00174 dwCreationDisposition = OPEN_EXISTING;
00175 break;
00176
00177 case O_CREAT:
00178 dwCreationDisposition = OPEN_ALWAYS;
00179 break;
00180
00181 case O_CREAT | O_TRUNC:
00182 dwCreationDisposition = CREATE_ALWAYS;
00183 break;
00184
00185 case O_CREAT | O_EXCL:
00186 case O_CREAT | O_TRUNC | O_EXCL:
00187 dwCreationDisposition = CREATE_NEW;
00188 break;
00189
00190 case O_TRUNC:
00191 case O_TRUNC | O_EXCL:
00192 dwCreationDisposition = TRUNCATE_EXISTING;
00193 break;
00194 }
00195
00196 HANDLE handleWin =
00197 CreateFile(filename,
00198 dwDesiredAccess,
00199 dwShareMode,
00200 NULL,
00201 dwCreationDisposition,
00202 FILE_ATTRIBUTE_NORMAL,
00203 NULL);
00204 if (handleWin == INVALID_HANDLE_VALUE) {
00205 return msvc_set_errno_from_getlasterror();
00206 }
00207
00208
00209 return _open_osfhandle((intptr_t)handleWin, flags);
00210 }
00211
00213 int msvc_posix_rename(const char *from, const char *to)
00214 {
00215 if (MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING) != 0) {
00216 return 0;
00217 }
00218
00219 return msvc_set_errno_from_getlasterror();
00220 }
00221
00222 #endif // __WIN32__