📄 posixwin.c
字号:
C_tm.tm_mday = C_unfix(C_block_item(v, 3)), \ C_tm.tm_mon = C_unfix(C_block_item(v, 4)), \ C_tm.tm_year = C_unfix(C_block_item(v, 5)), \ C_tm.tm_wday = C_unfix(C_block_item(v, 6)), \ C_tm.tm_yday = C_unfix(C_block_item(v, 7)), \ C_tm.tm_isdst = (C_block_item(v, 8) != C_SCHEME_FALSE))#define C_tm_set(v) (C_tm_set_08(v), &C_tm)#define C_asctime(v) (asctime(C_tm_set(v)))#define C_mktime(v) ((C_temporary_flonum = mktime(C_tm_set(v))) != -1)#define TIME_STRING_MAXLENGTH 255static char C_time_string [TIME_STRING_MAXLENGTH + 1];#undef TIME_STRING_MAXLENGTH#define C_strftime(v, f) \ (strftime(C_time_string, sizeof(C_time_string), C_c_string(f), C_tm_set(v)) ? C_time_string : NULL)/* mapping from Win32 error codes to errno*/typedef struct{ DWORD win32; int libc;} errmap_t;static errmap_t errmap[] ={ {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_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}, {0, 0}};static void C_fcallset_errno(DWORD w32err){ errmap_t *map = errmap; for (; errmap->win32; ++map) { if (errmap->win32 == w32err) { errno = errmap->libc; return; } }}static int C_fcallset_last_errno(){ set_errno(GetLastError()); return 0;}/* Functions for creating process with redirected I/O */static int C_fcallzero_handles(){ C_rd0 = C_wr0 = C_wr0_ = INVALID_HANDLE_VALUE; C_rd1 = C_wr1 = C_rd1_ = INVALID_HANDLE_VALUE; C_save0 = C_save1 = INVALID_HANDLE_VALUE; return 1;}static int C_fcallclose_handles(){ if (C_rd0 != INVALID_HANDLE_VALUE) CloseHandle(C_rd0); if (C_rd1 != INVALID_HANDLE_VALUE) CloseHandle(C_rd1); if (C_wr0 != INVALID_HANDLE_VALUE) CloseHandle(C_wr0); if (C_wr1 != INVALID_HANDLE_VALUE) CloseHandle(C_wr1); if (C_rd1_ != INVALID_HANDLE_VALUE) CloseHandle(C_rd1_); if (C_wr0_ != INVALID_HANDLE_VALUE) CloseHandle(C_wr0_); if (C_save0 != INVALID_HANDLE_VALUE) { SetStdHandle(STD_INPUT_HANDLE, C_save0); CloseHandle(C_save0); } if (C_save1 != INVALID_HANDLE_VALUE) { SetStdHandle(STD_OUTPUT_HANDLE, C_save1); CloseHandle(C_save1); } return zero_handles();}static int C_fcallredir_io(){ SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; zero_handles(); C_save0 = GetStdHandle(STD_INPUT_HANDLE); C_save1 = GetStdHandle(STD_OUTPUT_HANDLE); if (!CreatePipe(&C_rd0, &C_wr0, &sa, 0) || !SetStdHandle(STD_INPUT_HANDLE, C_rd0) || !DuplicateHandle(GetCurrentProcess(), C_wr0, GetCurrentProcess(), &C_wr0_, 0, FALSE, DUPLICATE_SAME_ACCESS) || !CreatePipe(&C_rd1, &C_wr1, &sa, 0) || !SetStdHandle(STD_OUTPUT_HANDLE, C_wr1) || !DuplicateHandle(GetCurrentProcess(), C_rd1, GetCurrentProcess(), &C_rd1_, 0, FALSE, DUPLICATE_SAME_ACCESS)) { set_last_errno(); close_handles(); return 0; } CloseHandle(C_wr0); C_wr0 = INVALID_HANDLE_VALUE; CloseHandle(C_rd1); C_rd1 = INVALID_HANDLE_VALUE; return 1;}static int C_fcallrun_process(char *cmdline){ PROCESS_INFORMATION pi; STARTUPINFO si; ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); C_wr0_ = C_rd1_ = INVALID_HANDLE_VALUE; /* these handles are saved */ if (CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) { CloseHandle(pi.hThread); SetStdHandle(STD_INPUT_HANDLE, C_save0); SetStdHandle(STD_OUTPUT_HANDLE, C_save1); C_save0 = C_save1 = INVALID_HANDLE_VALUE; CloseHandle(C_rd0); CloseHandle(C_wr1); C_rd0 = C_wr1 = INVALID_HANDLE_VALUE; return (int)pi.hProcess; } else return set_last_errno();}static int C_fcallpipe_write(int hpipe, void* buf, int count){ DWORD done = 0; if (WriteFile((HANDLE)hpipe, buf, count, &done, NULL)) return 1; else return set_last_errno();}static int C_fcallpipe_read(int hpipe){ DWORD done = 0; /* TODO: if (!pipe_ready(hpipe)) go_to_sleep; */ if (ReadFile((HANDLE)hpipe, &C_rdbuf, 1, &done, NULL)) { if (done > 0) /* not EOF yet */ return 1; else return -1; } return set_last_errno();}static int C_fcallpipe_ready(int hpipe){ DWORD avail = 0; if (PeekNamedPipe((HANDLE)hpipe, NULL, 0, NULL, &avail, NULL) && avail) return 1; else { Sleep(0); /* give pipe a chance */ if (PeekNamedPipe((HANDLE)hpipe, NULL, 0, NULL, &avail, NULL)) return (avail > 0); else return 0; }}#define C_zero_handles() C_fix(zero_handles())#define C_close_handles() C_fix(close_handles())#define C_redir_io() (redir_io() ? C_SCHEME_TRUE : C_SCHEME_FALSE)#define C_run_process(cmdline) C_fix(run_process(C_c_string(cmdline)))#define C_pipe_write(h, b, n) (pipe_write(C_unfix(h), C_c_string(b), C_unfix(n)) ? C_SCHEME_TRUE : C_SCHEME_FALSE)#define C_pipe_read(h) C_fix(pipe_read(C_unfix(h)))#define C_pipe_ready(h) (pipe_ready(C_unfix(h)) ? C_SCHEME_TRUE : C_SCHEME_FALSE)#define close_handle(h) CloseHandle((HANDLE)h)static int C_fcallprocess_wait(int h, int t){ if (WaitForSingleObject((HANDLE)h, (t ? 0 : INFINITE)) == WAIT_OBJECT_0) { DWORD ret; if (GetExitCodeProcess((HANDLE)h, &ret)) { CloseHandle((HANDLE)h); C_exstatus = ret; return 1; } } return set_last_errno();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -