diff options
Diffstat (limited to 'otherlibs/unix/sendrecv.c')
-rw-r--r-- | otherlibs/unix/sendrecv.c | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/otherlibs/unix/sendrecv.c b/otherlibs/unix/sendrecv.c index b6f35b262..e81080928 100644 --- a/otherlibs/unix/sendrecv.c +++ b/otherlibs/unix/sendrecv.c @@ -14,6 +14,7 @@ #include <mlvalues.h> #include <alloc.h> #include <memory.h> +#include <signals.h> #include "unixsupport.h" #ifdef HAS_SOCKETS @@ -30,34 +31,47 @@ value unix_recv(sock, buff, ofs, len, flags) /* ML */ value sock, buff, ofs, len, flags; { int ret; - buff = unix_freeze_buffer(buff); + long numbytes; + char iobuf[UNIX_BUFFER_SIZE]; + Push_roots(r, 1); + + r[0] = buff; + numbytes = Long_val(len); + if (numbytes > UNIX_BUFFER_SIZE) numbytes = UNIX_BUFFER_SIZE; enter_blocking_section(); - ret = recv(Int_val(sock), &Byte(buff, Long_val(ofs)), Int_val(len), + ret = recv(Int_val(sock), iobuf, (int) numbytes, convert_flag_list(flags, msg_flag_table)); leave_blocking_section(); if (ret == -1) uerror("recv", Nothing); + bcopy(iobuf, &Byte(r[0], Long_val(ofs)), ret); + Pop_roots(); return Val_int(ret); } value unix_recvfrom(sock, buff, ofs, len, flags) /* ML */ value sock, buff, ofs, len, flags; { - int retcode; + int ret; + long numbytes; + char iobuf[UNIX_BUFFER_SIZE]; value res; - Push_roots(a, 1); + Push_roots(r, 1); - buff = unix_freeze_buffer(buff); + r[0] = buff; + numbytes = Long_val(len); + if (numbytes > UNIX_BUFFER_SIZE) numbytes = UNIX_BUFFER_SIZE; sock_addr_len = sizeof(sock_addr); enter_blocking_section(); - retcode = recvfrom(Int_val(sock), &Byte(buff, Long_val(ofs)), Int_val(len), - convert_flag_list(flags, msg_flag_table), - &sock_addr.s_gen, &sock_addr_len); + ret = recvfrom(Int_val(sock), iobuf, (int) numbytes, + convert_flag_list(flags, msg_flag_table), + &sock_addr.s_gen, &sock_addr_len); leave_blocking_section(); - if (retcode == -1) uerror("recvfrom", Nothing); - a[0] = alloc_sockaddr(); + if (ret == -1) uerror("recvfrom", Nothing); + bcopy(iobuf, &Byte(r[0], Long_val(ofs)), ret); + r[0] = alloc_sockaddr(); res = alloc_tuple(2); - Field(res, 0) = Val_int(retcode); - Field(res, 1) = a[0]; + Field(res, 0) = Val_int(ret); + Field(res, 1) = r[0]; Pop_roots(); return res; } @@ -66,9 +80,14 @@ value unix_send(sock, buff, ofs, len, flags) /* ML */ value sock, buff, ofs, len, flags; { int ret; - buff = unix_freeze_buffer(buff); + long numbytes; + char iobuf[UNIX_BUFFER_SIZE]; + + numbytes = Long_val(len); + if (numbytes > UNIX_BUFFER_SIZE) numbytes = UNIX_BUFFER_SIZE; + bcopy(&Byte(buff, Long_val(ofs)), iobuf, numbytes); enter_blocking_section(); - ret = send(Int_val(sock), &Byte(buff, Long_val(ofs)), Int_val(len), + ret = send(Int_val(sock), iobuf, (int) numbytes, convert_flag_list(flags, msg_flag_table)); leave_blocking_section(); if (ret == -1) uerror("send", Nothing); @@ -79,11 +98,16 @@ value unix_sendto_native(sock, buff, ofs, len, flags, dest) value sock, buff, ofs, len, flags, dest; { int ret; + long numbytes; + char iobuf[UNIX_BUFFER_SIZE]; + get_sockaddr(dest); - buff = unix_freeze_buffer(buff); + numbytes = Long_val(len); + if (numbytes > UNIX_BUFFER_SIZE) numbytes = UNIX_BUFFER_SIZE; + bcopy(&Byte(buff, Long_val(ofs)), iobuf, numbytes); enter_blocking_section(); - ret = sendto(Int_val(sock), &Byte(buff, Long_val(ofs)), - Int_val(len), convert_flag_list(flags, msg_flag_table), + ret = sendto(Int_val(sock), iobuf, (int) numbytes, + convert_flag_list(flags, msg_flag_table), &sock_addr.s_gen, sock_addr_len); leave_blocking_section(); if (ret == -1) uerror("sendto", Nothing); |