diff options
-rw-r--r-- | otherlibs/unix/accept.c | 1 | ||||
-rw-r--r-- | otherlibs/unix/connect.c | 1 | ||||
-rw-r--r-- | otherlibs/unix/gethost.c | 1 | ||||
-rw-r--r-- | otherlibs/unix/read.c | 14 | ||||
-rw-r--r-- | otherlibs/unix/sendrecv.c | 58 | ||||
-rw-r--r-- | otherlibs/unix/sleep.c | 1 | ||||
-rw-r--r-- | otherlibs/unix/unixsupport.c | 12 | ||||
-rw-r--r-- | otherlibs/unix/unixsupport.h | 3 | ||||
-rw-r--r-- | otherlibs/unix/wait.c | 1 | ||||
-rw-r--r-- | otherlibs/unix/write.c | 46 |
10 files changed, 97 insertions, 41 deletions
diff --git a/otherlibs/unix/accept.c b/otherlibs/unix/accept.c index b2e1c9d5c..b17af63f7 100644 --- a/otherlibs/unix/accept.c +++ b/otherlibs/unix/accept.c @@ -14,6 +14,7 @@ #include <mlvalues.h> #include <alloc.h> #include <memory.h> +#include <signals.h> #include "unixsupport.h" #ifdef HAS_SOCKETS diff --git a/otherlibs/unix/connect.c b/otherlibs/unix/connect.c index 77b172014..bc2012d86 100644 --- a/otherlibs/unix/connect.c +++ b/otherlibs/unix/connect.c @@ -12,6 +12,7 @@ /* $Id$ */ #include <mlvalues.h> +#include <signals.h> #include "unixsupport.h" #ifdef HAS_SOCKETS diff --git a/otherlibs/unix/gethost.c b/otherlibs/unix/gethost.c index 3f9983da6..b9bc5805a 100644 --- a/otherlibs/unix/gethost.c +++ b/otherlibs/unix/gethost.c @@ -15,6 +15,7 @@ #include <alloc.h> #include <memory.h> #include <fail.h> +#include <signals.h> #include "unixsupport.h" #ifdef HAS_SOCKETS diff --git a/otherlibs/unix/read.c b/otherlibs/unix/read.c index 5401f83ff..d6f2cbd11 100644 --- a/otherlibs/unix/read.c +++ b/otherlibs/unix/read.c @@ -12,16 +12,26 @@ /* $Id$ */ #include <mlvalues.h> +#include <memory.h> +#include <signals.h> #include "unixsupport.h" value unix_read(fd, buf, ofs, len) /* ML */ value fd, buf, ofs, len; { + long numbytes; int ret; - buf = unix_freeze_buffer(buf); + char iobuf[UNIX_BUFFER_SIZE]; + Push_roots(r, 1); + + r[0] = buf; + numbytes = Long_val(len); + if (numbytes > UNIX_BUFFER_SIZE) numbytes = UNIX_BUFFER_SIZE; enter_blocking_section(); - ret = read(Int_val(fd), &Byte(buf, Long_val(ofs)), Int_val(len)); + ret = read(Int_val(fd), iobuf, (int) numbytes); leave_blocking_section(); if (ret == -1) uerror("read", Nothing); + bcopy(iobuf, &Byte(r[0], Long_val(ofs)), ret); + Pop_roots(); return Val_int(ret); } 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); diff --git a/otherlibs/unix/sleep.c b/otherlibs/unix/sleep.c index c09f195f2..1f245bc9d 100644 --- a/otherlibs/unix/sleep.c +++ b/otherlibs/unix/sleep.c @@ -12,6 +12,7 @@ /* $Id$ */ #include <mlvalues.h> +#include <signals.h> #include "unixsupport.h" value unix_sleep(t) /* ML */ diff --git a/otherlibs/unix/unixsupport.c b/otherlibs/unix/unixsupport.c index 9e07366d1..15364f371 100644 --- a/otherlibs/unix/unixsupport.c +++ b/otherlibs/unix/unixsupport.c @@ -278,15 +278,3 @@ void uerror(cmdname, cmdarg) unix_error(errno, cmdname, cmdarg); } -value unix_freeze_buffer(buf) - value buf; -{ - if (Is_young(buf)) { - Push_roots(r, 1); - r[0] = buf; - minor_collection(); - buf = r[0]; - Pop_roots(); - } - return buf; -} diff --git a/otherlibs/unix/unixsupport.h b/otherlibs/unix/unixsupport.h index 78d333375..51e425d2d 100644 --- a/otherlibs/unix/unixsupport.h +++ b/otherlibs/unix/unixsupport.h @@ -15,4 +15,5 @@ extern void unix_error P((int errcode, char * cmdname, value arg)); extern void uerror P((char * cmdname, value arg)); -extern value unix_freeze_buffer P((value)); + +#define UNIX_BUFFER_SIZE 16384 diff --git a/otherlibs/unix/wait.c b/otherlibs/unix/wait.c index 12bfed25d..982db7a14 100644 --- a/otherlibs/unix/wait.c +++ b/otherlibs/unix/wait.c @@ -14,6 +14,7 @@ #include <mlvalues.h> #include <alloc.h> #include <memory.h> +#include <signals.h> #include "unixsupport.h" #include <sys/types.h> diff --git a/otherlibs/unix/write.c b/otherlibs/unix/write.c index 6569fe3a6..5ae80459f 100644 --- a/otherlibs/unix/write.c +++ b/otherlibs/unix/write.c @@ -11,17 +11,45 @@ /* $Id$ */ +#include <errno.h> #include <mlvalues.h> +#include <memory.h> +#include <signals.h> #include "unixsupport.h" -value unix_write(fd, buf, ofs, len) /* ML */ - value fd, buf, ofs, len; +#ifndef EAGAIN +#define EAGAIN (-1) +#endif +#ifndef EWOULDBLOCK +#define EWOULDBLOCK (-1) +#endif + +value unix_write(fd, buf, vofs, vlen) /* ML */ + value fd, buf, vofs, vlen; { - int ret; - buf = unix_freeze_buffer(buf); - enter_blocking_section(); - ret = write(Int_val(fd), &Byte(buf, Long_val(ofs)), Int_val(len)); - leave_blocking_section(); - if (ret == -1) uerror("write", Nothing); - return Val_int(ret); + long ofs, len, written; + int numbytes, ret; + char iobuf[UNIX_BUFFER_SIZE]; + Push_roots(r, 1); + + r[0] = buf; + ofs = Long_val(vofs); + len = Long_val(vlen); + written = 0; + while (len > 0) { + numbytes = len > UNIX_BUFFER_SIZE ? UNIX_BUFFER_SIZE : len; + bcopy(&Byte(r[0], ofs), iobuf, numbytes); + enter_blocking_section(); + ret = write(Int_val(fd), iobuf, numbytes); + leave_blocking_section(); + if (ret == -1) { + if ((errno == EAGAIN || errno == EWOULDBLOCK) && written > 0) break; + uerror("write", Nothing); + } + written += ret; + ofs += ret; + len -= ret; + } + Pop_roots(); + return Val_long(written); } |