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 <io.h>
00028
00029 #include "safeerrno.h"
00030 #include "safefcntl.h"
00031 #include "safewindows.h"
00032
00034 static int
00035 msvc_set_errno_from_getlasterror()
00036 {
00037 int e;
00038 unsigned long winerr = GetLastError();
00039 switch (winerr) {
00040 case ERROR_FILENAME_EXCED_RANGE:
00041 case ERROR_FILE_NOT_FOUND:
00042 case ERROR_PATH_NOT_FOUND:
00043 case ERROR_INVALID_DRIVE:
00044 case ERROR_NO_MORE_FILES:
00045 case ERROR_BAD_NETPATH:
00046 case ERROR_BAD_NET_NAME:
00047 case ERROR_BAD_PATHNAME:
00048 e = ENOENT;
00049 break;
00050 case ERROR_ARENA_TRASHED:
00051 case ERROR_NOT_ENOUGH_MEMORY:
00052 case ERROR_INVALID_BLOCK:
00053 case ERROR_NOT_ENOUGH_QUOTA:
00054 e = ENOMEM;
00055 break;
00056 case ERROR_LOCK_VIOLATION:
00057 case ERROR_LOCK_FAILED:
00058 case ERROR_SEEK_ON_DEVICE:
00059 case ERROR_NETWORK_ACCESS_DENIED:
00060 case ERROR_NOT_LOCKED:
00061 case ERROR_ACCESS_DENIED:
00062 case ERROR_CANNOT_MAKE:
00063 case ERROR_FAIL_I24:
00064 case ERROR_DRIVE_LOCKED:
00065 case ERROR_CURRENT_DIRECTORY:
00066 e = EACCES;
00067 break;
00068 case ERROR_INVALID_FUNCTION:
00069 case ERROR_INVALID_ACCESS:
00070 case ERROR_NEGATIVE_SEEK:
00071 case ERROR_INVALID_DATA:
00072 case ERROR_INVALID_PARAMETER:
00073 e = EINVAL;
00074 break;
00075 case ERROR_NO_PROC_SLOTS:
00076 case ERROR_NESTING_NOT_ALLOWED:
00077 case ERROR_MAX_THRDS_REACHED:
00078 e = EAGAIN;
00079 break;
00080 case ERROR_INVALID_HANDLE:
00081 case ERROR_INVALID_TARGET_HANDLE:
00082 case ERROR_DIRECT_ACCESS_HANDLE:
00083 e = EBADF;
00084 break;
00085 case ERROR_ALREADY_EXISTS:
00086 case ERROR_FILE_EXISTS:
00087 e = EEXIST;
00088 break;
00089 case ERROR_BROKEN_PIPE:
00090 e = EPIPE;
00091 break;
00092 case ERROR_DISK_FULL:
00093 e = ENOSPC;
00094 break;
00095 case ERROR_TOO_MANY_OPEN_FILES:
00096 e = EMFILE;
00097 break;
00098 case ERROR_WAIT_NO_CHILDREN:
00099 case ERROR_CHILD_NOT_COMPLETE:
00100 e = ECHILD;
00101 break;
00102 case ERROR_DIR_NOT_EMPTY:
00103 e = ENOTEMPTY;
00104 break;
00105 case ERROR_BAD_ENVIRONMENT:
00106 e = E2BIG;
00107 break;
00108 case ERROR_BAD_FORMAT:
00109 e = ENOEXEC;
00110 break;
00111 case ERROR_NOT_SAME_DEVICE:
00112 e = EXDEV;
00113 break;
00114 default:
00115 if (winerr >= ERROR_WRITE_PROTECT && winerr <= ERROR_SHARING_BUFFER_EXCEEDED)
00116 e = EACCES;
00117 else if (winerr >= ERROR_INVALID_STARTING_CODESEG && winerr <= ERROR_INFLOOP_IN_RELOC_CHAIN)
00118 e = ENOEXEC;
00119 else
00120 e = EINVAL;
00121 break;
00122 }
00123
00124
00125 #ifdef _set_errno
00126 _set_errno(e);
00127 #else
00128 errno = e;
00129 #endif
00130 return -1;
00131 }
00132
00137 int
00138 msvc_posix_unlink(const char * filename)
00139 {
00140
00141 if (DeleteFile(filename) != 0) {
00142 return 0;
00143 }
00144
00145 return msvc_set_errno_from_getlasterror();
00146 }
00147
00149 int
00150 msvc_posix_open(const char *filename, int flags)
00151 {
00152
00153 DWORD dwDesiredAccess = GENERIC_READ;
00154 switch (flags & (O_RDONLY | O_RDWR | O_WRONLY))
00155 {
00156 case O_RDONLY:
00157 dwDesiredAccess = GENERIC_READ;
00158 break;
00159 case O_RDWR:
00160 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
00161 break;
00162 case O_WRONLY:
00163 dwDesiredAccess = GENERIC_WRITE;
00164 break;
00165 }
00166
00167 DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
00168
00169
00170 DWORD dwCreationDisposition = OPEN_EXISTING;
00171 switch (flags & (O_CREAT | O_TRUNC | O_EXCL))
00172 {
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__