-
Notifications
You must be signed in to change notification settings - Fork 50
unix: add Cstruct_unix.{read,write,writev,send,recv} #302
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
99f6a02
87382a1
6002721
2390134
f70b3ac
7d77f0a
04e45e2
3e6d7e4
284960a
ec807a7
fa5ffe7
2cf81f3
4a04478
44ec8fc
803ba0c
aeca686
5920235
471ca03
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#include <caml/mlvalues.h> | ||
#include <caml/memory.h> | ||
#include <caml/custom.h> | ||
#include <caml/callback.h> | ||
#include <caml/alloc.h> | ||
#include <caml/unixsupport.h> | ||
#include <caml/bigarray.h> | ||
#include <caml/threads.h> | ||
|
||
#include <stdio.h> | ||
#include <errno.h> | ||
|
||
CAMLprim value stub_cstruct_read(value val_fd, value val_c) | ||
{ | ||
CAMLparam2(val_fd, val_c); | ||
CAMLlocal3(val_buf, val_ofs, val_len); | ||
uint8_t *buf; | ||
size_t len; | ||
ssize_t n = 0; | ||
#ifdef WIN32 | ||
int win32err = 0; | ||
SOCKET s; | ||
HANDLE h; | ||
DWORD numread; | ||
int ok; | ||
#endif | ||
val_buf = Field(val_c, 0); | ||
val_ofs = Field(val_c, 1); | ||
val_len = Field(val_c, 2); | ||
|
||
buf = (uint8_t *)Caml_ba_data_val(val_buf) + Long_val(val_ofs); | ||
len = (size_t)Long_val(val_len); | ||
|
||
#ifdef WIN32 | ||
switch (Descr_kind_val(val_fd)) | ||
{ | ||
case KIND_SOCKET: | ||
s = Socket_val(val_fd); | ||
|
||
caml_release_runtime_system(); | ||
n = recv(s, buf, len, 0); | ||
win32err = WSAGetLastError(); | ||
caml_acquire_runtime_system(); | ||
|
||
if (n == SOCKET_ERROR) | ||
{ | ||
win32_maperr(win32err); | ||
uerror("stub_cstruct_read", Nothing); | ||
} | ||
break; | ||
case KIND_HANDLE: | ||
h = Handle_val(val_fd); | ||
caml_release_runtime_system(); | ||
ok = ReadFile(h, buf, len, &numread, NULL); | ||
win32err = GetLastError(); | ||
n = numread; | ||
caml_acquire_runtime_system(); | ||
|
||
if (!ok) | ||
{ | ||
win32_maperr(win32err); | ||
uerror("stub_cstruct_read", Nothing); | ||
} | ||
break; | ||
default: | ||
caml_failwith("unknown Descr_kind_val"); | ||
} | ||
#else | ||
caml_release_runtime_system(); | ||
n = read(Int_val(val_fd), buf, len); | ||
caml_acquire_runtime_system(); | ||
if (n < 0) | ||
uerror("stub_cstruct_read", Nothing); | ||
#endif | ||
CAMLreturn(Val_int(n)); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#include <caml/mlvalues.h> | ||
#include <caml/memory.h> | ||
#include <caml/custom.h> | ||
#include <caml/callback.h> | ||
#include <caml/alloc.h> | ||
#include <caml/unixsupport.h> | ||
#include <caml/bigarray.h> | ||
#include <caml/threads.h> | ||
|
||
#include <stdio.h> | ||
|
||
#ifdef WIN32 | ||
#define WIN32_LEAN_AND_MEAN | ||
#include <winsock2.h> | ||
#include <ws2tcpip.h> | ||
#include <NTSecAPI.h> | ||
#else | ||
#include <sys/socket.h> | ||
#include <netinet/in.h> | ||
#include <errno.h> | ||
#endif | ||
|
||
static int msg_flag_table[] = { | ||
MSG_OOB, MSG_DONTROUTE, MSG_PEEK /* XXX */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what's the XXX for here? Incomplete flags? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cause we assume how stdlib ordered things and also because we redefine them, would be nice if stdlib exposed them as not static so we could just use caml_msg_flag_table or something There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The stdlib does expose them -- as OCaml values. Just add a type definition in unix_cstruct.mli instead and get rid of the XXX:
This will create an alias to Unix.msg_flag that also checks that it's exactly the same as what is specified there.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah that's smart ! yes we should do that. |
||
}; | ||
|
||
CAMLprim value stub_cstruct_recv(value val_fd, value val_c, value val_flags) | ||
{ | ||
CAMLparam3(val_fd, val_c, val_flags); | ||
CAMLlocal3(val_buf, val_ofs, val_len); | ||
uint8_t *buf; | ||
size_t len; | ||
ssize_t n = 0; | ||
int cv_flags; | ||
#ifdef WIN32 | ||
int win32err = 0; | ||
SOCKET s = Socket_val(val_fd); | ||
#endif | ||
|
||
val_buf = Field(val_c, 0); | ||
val_ofs = Field(val_c, 1); | ||
val_len = Field(val_c, 2); | ||
|
||
buf = (uint8_t *)Caml_ba_data_val(val_buf) + Long_val(val_ofs); | ||
len = (size_t)Long_val(val_len); | ||
cv_flags = caml_convert_flag_list(val_flags, msg_flag_table); | ||
#ifdef WIN32 | ||
if (Descr_kind_val(val_fd) != KIND_SOCKET) | ||
unix_error(EINVAL, "stub_cstruct_recv", Nothing); | ||
|
||
caml_release_runtime_system(); | ||
n = recv(s, buf, len, cv_flags); | ||
win32err = WSAGetLastError(); | ||
caml_acquire_runtime_system(); | ||
|
||
if (n == SOCKET_ERROR) | ||
{ | ||
win32_maperr(win32err); | ||
uerror("stub_cstruct_recv", Nothing); | ||
} | ||
#else | ||
caml_release_runtime_system(); | ||
n = recv(Int_val(val_fd), buf, len, cv_flags); | ||
caml_acquire_runtime_system(); | ||
|
||
if (n < 0) | ||
uerror("stub_cstruct_recv", Nothing); | ||
#endif | ||
CAMLreturn(Val_int(n)); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#include <caml/mlvalues.h> | ||
#include <caml/memory.h> | ||
#include <caml/custom.h> | ||
#include <caml/callback.h> | ||
#include <caml/alloc.h> | ||
#include <caml/unixsupport.h> | ||
#include <caml/bigarray.h> | ||
#include <caml/threads.h> | ||
#include <caml/socketaddr.h> | ||
|
||
#ifdef WIN32 | ||
#define WIN32_LEAN_AND_MEAN | ||
#include <winsock2.h> | ||
#else | ||
#include <sys/socket.h> | ||
#endif | ||
|
||
static int msg_flag_table[] = { | ||
MSG_OOB, MSG_DONTROUTE, MSG_PEEK /* XXX */ | ||
}; | ||
|
||
CAMLprim value stub_cstruct_recvfrom(value val_fd, value val_c, value val_flags) | ||
{ | ||
CAMLparam3(val_fd, val_c, val_flags); | ||
CAMLlocal5(val_buf, val_ofs, val_len, val_addr, val_res); | ||
uint8_t *buf; | ||
size_t len; | ||
ssize_t n; | ||
int cv_flags; | ||
union sock_addr_union addr; | ||
socklen_param_type addr_len; | ||
#ifdef WIN32 | ||
int win32err = 0; | ||
SOCKET s = Socket_val(val_fd); | ||
#endif | ||
|
||
val_buf = Field(val_c, 0); | ||
val_ofs = Field(val_c, 1); | ||
val_len = Field(val_c, 2); | ||
cv_flags = caml_convert_flag_list(val_flags, msg_flag_table); | ||
|
||
buf = (uint8_t *)Caml_ba_data_val(val_buf) + Long_val(val_ofs); | ||
len = Long_val(val_len); | ||
addr_len = sizeof(addr); | ||
#ifdef WIN32 | ||
if (Descr_kind_val(val_fd) != KIND_SOCKET) | ||
unix_error(EINVAL, "stub_cstruct_recvfrom", Nothing); | ||
|
||
caml_release_runtime_system(); | ||
n = recvfrom(s, buf, len, cv_flags, &addr.s_gen, &addr_len); | ||
win32err = WSAGetLastError(); | ||
caml_acquire_runtime_system(); | ||
|
||
if (n == SOCKET_ERROR) | ||
{ | ||
win32_maperr(win32err); | ||
uerror("stub_cstruct_recvfrom", Nothing); | ||
} | ||
#else | ||
caml_release_runtime_system(); | ||
n = recvfrom(Int_val(val_fd), buf, len, cv_flags, &addr.s_gen, &addr_len); | ||
caml_acquire_runtime_system(); | ||
|
||
if (n == -1) | ||
uerror("stub_cstruct_recvfrom", Nothing); | ||
#endif | ||
|
||
val_addr = alloc_sockaddr(&addr, addr_len, -1); | ||
val_res = caml_alloc_small(2, 0); | ||
Field(val_res, 0) = Val_int(n); | ||
Field(val_res, 1) = val_addr; | ||
|
||
CAMLreturn (val_res); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#include <caml/mlvalues.h> | ||
#include <caml/memory.h> | ||
#include <caml/custom.h> | ||
#include <caml/callback.h> | ||
#include <caml/alloc.h> | ||
#include <caml/unixsupport.h> | ||
#include <caml/bigarray.h> | ||
#include <caml/threads.h> | ||
|
||
#include <stdio.h> | ||
|
||
#ifdef WIN32 | ||
#define WIN32_LEAN_AND_MEAN | ||
#include <winsock2.h> | ||
#include <ws2tcpip.h> | ||
#include <NTSecAPI.h> | ||
#else | ||
#include <sys/socket.h> | ||
#include <netinet/in.h> | ||
#include <errno.h> | ||
#endif | ||
|
||
static int msg_flag_table[] = { | ||
MSG_OOB, MSG_DONTROUTE, MSG_PEEK /* XXX */ | ||
}; | ||
|
||
CAMLprim value stub_cstruct_send(value val_fd, value val_c, value val_flags) | ||
{ | ||
CAMLparam3(val_fd, val_c, val_flags); | ||
CAMLlocal3(val_buf, val_ofs, val_len); | ||
uint8_t *buf; | ||
size_t len; | ||
ssize_t n = 0; | ||
int cv_flags = caml_convert_flag_list(val_flags, msg_flag_table); | ||
#ifdef WIN32 | ||
int win32err = 0; | ||
SOCKET s = Socket_val(val_fd); | ||
#endif | ||
|
||
val_buf = Field(val_c, 0); | ||
val_ofs = Field(val_c, 1); | ||
val_len = Field(val_c, 2); | ||
|
||
buf = (uint8_t *)Caml_ba_data_val(val_buf) + Long_val(val_ofs); | ||
len = (size_t)Long_val(val_len); | ||
|
||
#ifdef WIN32 | ||
if (Descr_kind_val(val_fd) != KIND_SOCKET) | ||
unix_error(EINVAL, "stub_cstruct_send", Nothing); | ||
|
||
caml_release_runtime_system(); | ||
n = send(s, buf, len, cv_flags); | ||
win32err = WSAGetLastError(); | ||
caml_acquire_runtime_system(); | ||
|
||
if (n == SOCKET_ERROR) | ||
{ | ||
win32_maperr(win32err); | ||
uerror("stub_cstruct_send", Nothing); | ||
} | ||
#else | ||
caml_release_runtime_system(); | ||
n = send(Int_val(val_fd), buf, len, cv_flags); | ||
caml_acquire_runtime_system(); | ||
if (n < 0) | ||
uerror("stub_cstruct_send", Nothing); | ||
#endif | ||
CAMLreturn(Val_int(n)); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#include <caml/mlvalues.h> | ||
#include <caml/memory.h> | ||
#include <caml/custom.h> | ||
#include <caml/callback.h> | ||
#include <caml/alloc.h> | ||
#include <caml/unixsupport.h> | ||
#include <caml/bigarray.h> | ||
#include <caml/threads.h> | ||
#include <caml/socketaddr.h> | ||
|
||
#ifdef WIN32 | ||
#define WIN32_LEAN_AND_MEAN | ||
#include <winsock2.h> | ||
#else | ||
#include <sys/socket.h> | ||
#endif | ||
|
||
static int msg_flag_table[] = { /* XXX */ | ||
MSG_OOB, MSG_DONTROUTE, MSG_PEEK | ||
}; | ||
|
||
CAMLprim value stub_cstruct_sendto(value val_fd, value val_c, value val_flags, value val_daddr) | ||
{ | ||
CAMLparam4(val_fd, val_c, val_flags, val_daddr); | ||
CAMLlocal5(val_buf, val_ofs, val_len, val_addr, val_res); | ||
union sock_addr_union addr; | ||
socklen_param_type addr_len; | ||
uint8_t *buf; | ||
size_t len; | ||
ssize_t n; | ||
int cv_flags; | ||
#ifdef WIN32 | ||
int win32err = 0; | ||
SOCKET s = Socket_val(val_fd); | ||
#endif | ||
|
||
val_buf = Field(val_c, 0); | ||
val_ofs = Field(val_c, 1); | ||
val_len = Field(val_c, 2); | ||
|
||
buf = (uint8_t *)Caml_ba_data_val(val_buf) + Long_val(val_ofs); | ||
len = Long_val(val_len); | ||
get_sockaddr(val_daddr, &addr, &addr_len); | ||
cv_flags = caml_convert_flag_list(val_flags, msg_flag_table); | ||
|
||
#ifdef WIN32 | ||
if (Descr_kind_val(val_fd) != KIND_SOCKET) | ||
unix_error(EINVAL, "stub_cstruct_sendto", Nothing); | ||
|
||
caml_release_runtime_system(); | ||
n = sendto(s, buf, len, cv_flags, &addr.s_gen, addr_len); | ||
win32err = WSAGetLastError(); | ||
caml_acquire_runtime_system(); | ||
|
||
if (n == SOCKET_ERROR) | ||
{ | ||
win32_maperr(win32err); | ||
uerror("stub_cstruct_sendto", Nothing); | ||
} | ||
#else | ||
caml_release_runtime_system(); | ||
n = sendto(Int_val(val_fd), buf, len, cv_flags, &addr.s_gen, addr_len); | ||
caml_acquire_runtime_system(); | ||
|
||
if (n == -1) | ||
uerror("stub_cstruct_sendto", Nothing); | ||
#endif | ||
CAMLreturn (Val_int(n)); | ||
} |
Uh oh!
There was an error while loading. Please reload this page.