1 /** @file posixy_wrapper.cc
2 * @brief Provides wrappers with POSIXy semantics.
4 /* Copyright (C) 2007 Lemur Consulting Ltd
5 * Copyright (C) 2007,2012 Olly Betts
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #ifdef __WIN32__ /* Ignore the whole file except for __WIN32__ */
26 #include "posixy_wrapper.h"
30 #include "safeerrno.h"
31 #include "safefcntl.h"
32 #include "safewindows.h"
34 /** Call GetLastError() and set errno appropriately. */
36 set_errno_from_getlasterror()
39 unsigned long winerr
= GetLastError();
41 case ERROR_FILENAME_EXCED_RANGE
:
42 case ERROR_FILE_NOT_FOUND
:
43 case ERROR_PATH_NOT_FOUND
:
44 case ERROR_INVALID_DRIVE
:
45 case ERROR_NO_MORE_FILES
:
46 case ERROR_BAD_NETPATH
:
47 case ERROR_BAD_NET_NAME
:
48 case ERROR_BAD_PATHNAME
:
51 case ERROR_ARENA_TRASHED
:
52 case ERROR_NOT_ENOUGH_MEMORY
:
53 case ERROR_INVALID_BLOCK
:
54 case ERROR_NOT_ENOUGH_QUOTA
:
57 case ERROR_LOCK_VIOLATION
:
58 case ERROR_LOCK_FAILED
:
59 case ERROR_SEEK_ON_DEVICE
:
60 case ERROR_NETWORK_ACCESS_DENIED
:
61 case ERROR_NOT_LOCKED
:
62 case ERROR_ACCESS_DENIED
:
63 case ERROR_CANNOT_MAKE
:
65 case ERROR_DRIVE_LOCKED
:
66 case ERROR_CURRENT_DIRECTORY
:
69 case ERROR_INVALID_FUNCTION
:
70 case ERROR_INVALID_ACCESS
:
71 case ERROR_NEGATIVE_SEEK
:
72 case ERROR_INVALID_DATA
:
73 case ERROR_INVALID_PARAMETER
:
76 case ERROR_NO_PROC_SLOTS
:
77 case ERROR_NESTING_NOT_ALLOWED
:
78 case ERROR_MAX_THRDS_REACHED
:
81 case ERROR_INVALID_HANDLE
:
82 case ERROR_INVALID_TARGET_HANDLE
:
83 case ERROR_DIRECT_ACCESS_HANDLE
:
86 case ERROR_ALREADY_EXISTS
:
87 case ERROR_FILE_EXISTS
:
90 case ERROR_BROKEN_PIPE
:
96 case ERROR_TOO_MANY_OPEN_FILES
:
99 case ERROR_WAIT_NO_CHILDREN
:
100 case ERROR_CHILD_NOT_COMPLETE
:
103 case ERROR_DIR_NOT_EMPTY
:
106 case ERROR_BAD_ENVIRONMENT
:
109 case ERROR_BAD_FORMAT
:
112 case ERROR_NOT_SAME_DEVICE
:
116 if (winerr
>= ERROR_WRITE_PROTECT
&& winerr
<= ERROR_SHARING_BUFFER_EXCEEDED
)
118 else if (winerr
>= ERROR_INVALID_STARTING_CODESEG
&& winerr
<= ERROR_INFLOOP_IN_RELOC_CHAIN
)
124 /* Some versions of Microsoft's C++ compiler earlier than 2005 do not have
135 posixy_unlink(const char * filename
)
137 /* We must use DeleteFile as this can delete files that are open. */
138 if (DeleteFile(filename
) != 0) {
142 return set_errno_from_getlasterror();
146 posixy_open(const char *filename
, int flags
)
148 /* Translate POSIX read mode to Windows access mode */
149 DWORD dwDesiredAccess
= GENERIC_READ
;
150 switch (flags
& (O_RDONLY
| O_RDWR
| O_WRONLY
)) {
152 dwDesiredAccess
= GENERIC_READ
;
155 dwDesiredAccess
= GENERIC_READ
| GENERIC_WRITE
;
158 dwDesiredAccess
= GENERIC_WRITE
;
161 /* Subsequent operations may open this file to read, write or delete it */
162 DWORD dwShareMode
= FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
;
164 /* Translate POSIX creation mode to Windows creation mode */
165 DWORD dwCreationDisposition
= OPEN_EXISTING
;
166 switch (flags
& (O_CREAT
| O_TRUNC
| O_EXCL
)) {
168 dwCreationDisposition
= OPEN_EXISTING
;
172 dwCreationDisposition
= OPEN_ALWAYS
;
175 case O_CREAT
| O_TRUNC
:
176 dwCreationDisposition
= CREATE_ALWAYS
;
179 case O_CREAT
| O_EXCL
:
180 case O_CREAT
| O_TRUNC
| O_EXCL
:
181 dwCreationDisposition
= CREATE_NEW
;
185 case O_TRUNC
| O_EXCL
:
186 dwCreationDisposition
= TRUNCATE_EXISTING
;
195 dwCreationDisposition
,
196 FILE_ATTRIBUTE_NORMAL
,
198 if (handleWin
== INVALID_HANDLE_VALUE
) {
199 return set_errno_from_getlasterror();
202 /* Return a standard file descriptor. */
203 return _open_osfhandle((intptr_t)handleWin
, flags
|O_BINARY
);
207 posixy_rename(const char *from
, const char *to
)
209 if (MoveFileEx(from
, to
, MOVEFILE_REPLACE_EXISTING
) != 0) {
213 return set_errno_from_getlasterror();