2 #include "jimiocompat.h"
4 void Jim_SetResultErrno(Jim_Interp
*interp
, const char *msg
)
6 Jim_SetResultFormatted(interp
, "%s: %s", msg
, strerror(Jim_Errno()));
9 #if defined(__MINGW32__)
14 switch (GetLastError()) {
15 case ERROR_FILE_NOT_FOUND
: return ENOENT
;
16 case ERROR_PATH_NOT_FOUND
: return ENOENT
;
17 case ERROR_TOO_MANY_OPEN_FILES
: return EMFILE
;
18 case ERROR_ACCESS_DENIED
: return EACCES
;
19 case ERROR_INVALID_HANDLE
: return EBADF
;
20 case ERROR_BAD_ENVIRONMENT
: return E2BIG
;
21 case ERROR_BAD_FORMAT
: return ENOEXEC
;
22 case ERROR_INVALID_ACCESS
: return EACCES
;
23 case ERROR_INVALID_DRIVE
: return ENOENT
;
24 case ERROR_CURRENT_DIRECTORY
: return EACCES
;
25 case ERROR_NOT_SAME_DEVICE
: return EXDEV
;
26 case ERROR_NO_MORE_FILES
: return ENOENT
;
27 case ERROR_WRITE_PROTECT
: return EROFS
;
28 case ERROR_BAD_UNIT
: return ENXIO
;
29 case ERROR_NOT_READY
: return EBUSY
;
30 case ERROR_BAD_COMMAND
: return EIO
;
31 case ERROR_CRC
: return EIO
;
32 case ERROR_BAD_LENGTH
: return EIO
;
33 case ERROR_SEEK
: return EIO
;
34 case ERROR_WRITE_FAULT
: return EIO
;
35 case ERROR_READ_FAULT
: return EIO
;
36 case ERROR_GEN_FAILURE
: return EIO
;
37 case ERROR_SHARING_VIOLATION
: return EACCES
;
38 case ERROR_LOCK_VIOLATION
: return EACCES
;
39 case ERROR_SHARING_BUFFER_EXCEEDED
: return ENFILE
;
40 case ERROR_HANDLE_DISK_FULL
: return ENOSPC
;
41 case ERROR_NOT_SUPPORTED
: return ENODEV
;
42 case ERROR_REM_NOT_LIST
: return EBUSY
;
43 case ERROR_DUP_NAME
: return EEXIST
;
44 case ERROR_BAD_NETPATH
: return ENOENT
;
45 case ERROR_NETWORK_BUSY
: return EBUSY
;
46 case ERROR_DEV_NOT_EXIST
: return ENODEV
;
47 case ERROR_TOO_MANY_CMDS
: return EAGAIN
;
48 case ERROR_ADAP_HDW_ERR
: return EIO
;
49 case ERROR_BAD_NET_RESP
: return EIO
;
50 case ERROR_UNEXP_NET_ERR
: return EIO
;
51 case ERROR_NETNAME_DELETED
: return ENOENT
;
52 case ERROR_NETWORK_ACCESS_DENIED
: return EACCES
;
53 case ERROR_BAD_DEV_TYPE
: return ENODEV
;
54 case ERROR_BAD_NET_NAME
: return ENOENT
;
55 case ERROR_TOO_MANY_NAMES
: return ENFILE
;
56 case ERROR_TOO_MANY_SESS
: return EIO
;
57 case ERROR_SHARING_PAUSED
: return EAGAIN
;
58 case ERROR_REDIR_PAUSED
: return EAGAIN
;
59 case ERROR_FILE_EXISTS
: return EEXIST
;
60 case ERROR_CANNOT_MAKE
: return ENOSPC
;
61 case ERROR_OUT_OF_STRUCTURES
: return ENFILE
;
62 case ERROR_ALREADY_ASSIGNED
: return EEXIST
;
63 case ERROR_INVALID_PASSWORD
: return EPERM
;
64 case ERROR_NET_WRITE_FAULT
: return EIO
;
65 case ERROR_NO_PROC_SLOTS
: return EAGAIN
;
66 case ERROR_DISK_CHANGE
: return EXDEV
;
67 case ERROR_BROKEN_PIPE
: return EPIPE
;
68 case ERROR_OPEN_FAILED
: return ENOENT
;
69 case ERROR_DISK_FULL
: return ENOSPC
;
70 case ERROR_NO_MORE_SEARCH_HANDLES
: return EMFILE
;
71 case ERROR_INVALID_TARGET_HANDLE
: return EBADF
;
72 case ERROR_INVALID_NAME
: return ENOENT
;
73 case ERROR_PROC_NOT_FOUND
: return ESRCH
;
74 case ERROR_WAIT_NO_CHILDREN
: return ECHILD
;
75 case ERROR_CHILD_NOT_COMPLETE
: return ECHILD
;
76 case ERROR_DIRECT_ACCESS_HANDLE
: return EBADF
;
77 case ERROR_SEEK_ON_DEVICE
: return ESPIPE
;
78 case ERROR_BUSY_DRIVE
: return EAGAIN
;
79 case ERROR_DIR_NOT_EMPTY
: return EEXIST
;
80 case ERROR_NOT_LOCKED
: return EACCES
;
81 case ERROR_BAD_PATHNAME
: return ENOENT
;
82 case ERROR_LOCK_FAILED
: return EACCES
;
83 case ERROR_ALREADY_EXISTS
: return EEXIST
;
84 case ERROR_FILENAME_EXCED_RANGE
: return ENAMETOOLONG
;
85 case ERROR_BAD_PIPE
: return EPIPE
;
86 case ERROR_PIPE_BUSY
: return EAGAIN
;
87 case ERROR_PIPE_NOT_CONNECTED
: return EPIPE
;
88 case ERROR_DIRECTORY
: return ENOTDIR
;
93 pidtype
waitpid(pidtype pid
, int *status
, int nohang
)
95 DWORD ret
= WaitForSingleObject(pid
, nohang
? 0 : INFINITE
);
96 if (ret
== WAIT_TIMEOUT
|| ret
== WAIT_FAILED
) {
97 /* WAIT_TIMEOUT can only happend with WNOHANG */
100 GetExitCodeProcess(pid
, &ret
);
106 int Jim_MakeTempFile(Jim_Interp
*interp
, const char *filename_template
, int unlink_file
)
111 if (!GetTempPath(MAX_PATH
, name
) || !GetTempFileName(name
, filename_template
? filename_template
: "JIM", 0, name
)) {
115 handle
= CreateFile(name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
116 CREATE_ALWAYS
, FILE_ATTRIBUTE_TEMPORARY
| (unlink_file
? FILE_FLAG_DELETE_ON_CLOSE
: 0),
119 if (handle
== INVALID_HANDLE_VALUE
) {
123 Jim_SetResultString(interp
, name
, -1);
124 return _open_osfhandle((int)handle
, _O_RDWR
| _O_TEXT
);
127 Jim_SetResultErrno(interp
, name
);
132 int Jim_OpenForWrite(const char *filename
, int append
)
134 if (strcmp(filename
, "/dev/null") == 0) {
137 int fd
= _open(filename
, _O_WRONLY
| _O_CREAT
| _O_TEXT
| (append
? _O_APPEND
: _O_TRUNC
), _S_IREAD
| _S_IWRITE
);
138 if (fd
>= 0 && append
) {
139 /* Note that _O_APPEND doesn't actually work. need to do it manually */
140 _lseek(fd
, 0L, SEEK_END
);
145 int Jim_OpenForRead(const char *filename
)
147 if (strcmp(filename
, "/dev/null") == 0) {
150 return _open(filename
, _O_RDONLY
| _O_TEXT
, 0);
153 #elif defined(HAVE_UNISTD_H)
155 /* Unix-specific implementation */
157 int Jim_MakeTempFile(Jim_Interp
*interp
, const char *filename_template
, int unlink_file
)
161 Jim_Obj
*filenameObj
;
163 if (filename_template
== NULL
) {
164 const char *tmpdir
= getenv("TMPDIR");
165 if (tmpdir
== NULL
|| *tmpdir
== '\0' || access(tmpdir
, W_OK
) != 0) {
168 filenameObj
= Jim_NewStringObj(interp
, tmpdir
, -1);
169 if (tmpdir
[0] && tmpdir
[strlen(tmpdir
) - 1] != '/') {
170 Jim_AppendString(interp
, filenameObj
, "/", 1);
172 Jim_AppendString(interp
, filenameObj
, "tcl.tmp.XXXXXX", -1);
175 filenameObj
= Jim_NewStringObj(interp
, filename_template
, -1);
178 /* Update the template name directly with the filename */
179 mask
= umask(S_IXUSR
| S_IRWXG
| S_IRWXO
);
181 fd
= mkstemp(filenameObj
->bytes
);
183 if (mktemp(filenameObj
->bytes
) == NULL
) {
187 fd
= open(filenameObj
->bytes
, O_RDWR
| O_CREAT
| O_TRUNC
);
192 Jim_SetResultErrno(interp
, Jim_String(filenameObj
));
193 Jim_FreeNewObj(interp
, filenameObj
);
197 remove(Jim_String(filenameObj
));
200 Jim_SetResult(interp
, filenameObj
);
204 int Jim_OpenForWrite(const char *filename
, int append
)
206 return open(filename
, O_WRONLY
| O_CREAT
| (append
? O_APPEND
: O_TRUNC
), 0666);
209 int Jim_OpenForRead(const char *filename
)
211 return open(filename
, O_RDONLY
, 0);