int win_CRT_fd_of_filedescr(value handle) { if (CRT_fd_val(handle) != NO_CRT_FD) { return CRT_fd_val(handle); } else { int fd = _open_osfhandle((long) Handle_val(handle), O_BINARY); if (fd == -1) uerror("channel_of_descr", Nothing); return fd; } }
CAMLprim value win_handle_fd(value vfd) { int crt_fd = Int_val(vfd); value res = win_alloc_handle_or_socket((HANDLE) _get_osfhandle(crt_fd)); CRT_fd_val(res) = crt_fd; return res; }
value win_alloc_socket(SOCKET s) { value res = alloc_custom(&win_handle_ops, sizeof(struct filedescr), 0, 1); Socket_val(res) = s; Descr_kind_val(res) = KIND_SOCKET; CRT_fd_val(res) = NO_CRT_FD; return res; }
value win_alloc_handle(HANDLE h) { value res = alloc_custom(&win_handle_ops, sizeof(struct filedescr), 0, 1); Handle_val(res) = h; Descr_kind_val(res) = KIND_HANDLE; CRT_fd_val(res) = NO_CRT_FD; return res; }
CAMLprim value win_handle_fd(value vfd) { int crt_fd = Int_val(vfd); /* PR#4750: do not use the _or_socket variant as it can cause performance degradation and this function is only used with the standard handles 0, 1, 2, which are not sockets. */ value res = win_alloc_handle((HANDLE) _get_osfhandle(crt_fd)); CRT_fd_val(res) = crt_fd; return res; }
CAMLprim value unix_dup2(value fd1, value fd2) { HANDLE oldh, newh; oldh = Handle_val(fd2); if (! DuplicateHandle(GetCurrentProcess(), Handle_val(fd1), GetCurrentProcess(), &newh, 0L, TRUE, DUPLICATE_SAME_ACCESS)) { win32_maperr(GetLastError()); return -1; } Handle_val(fd2) = newh; if (Descr_kind_val(fd2) == KIND_SOCKET) closesocket((SOCKET) oldh); else CloseHandle(oldh); Descr_kind_val(fd2) = Descr_kind_val(fd1); /* Reflect the dup2 on the CRT fds, if any */ if (CRT_fd_val(fd1) != NO_CRT_FD || CRT_fd_val(fd2) != NO_CRT_FD) _dup2(win_CRT_fd_of_filedescr(fd1), win_CRT_fd_of_filedescr(fd2)); return Val_unit; }
CAMLprim value win_filedescr_of_channel(value vchan) { CAMLparam1(vchan); CAMLlocal1(fd); struct channel * chan; HANDLE h; chan = Channel(vchan); if (chan->fd == -1) uerror("descr_of_channel", Nothing); h = (HANDLE) _get_osfhandle(chan->fd); if (chan->flags & CHANNEL_FLAG_FROM_SOCKET) fd = win_alloc_socket((SOCKET) h); else fd = win_alloc_handle(h); CRT_fd_val(fd) = chan->fd; CAMLreturn(fd); }