Sys.Signals module for a Variant type of signals (and a set_signal function that...
[ocaml.git] / otherlibs / unix / write.c
blob633f05fc063e0ca8d5ca7e97895f3fc2ebb557e2
1 /***********************************************************************/
2 /* */
3 /* Objective Caml */
4 /* */
5 /* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
6 /* */
7 /* Copyright 1996 Institut National de Recherche en Informatique et */
8 /* en Automatique. All rights reserved. This file is distributed */
9 /* under the terms of the GNU Library General Public License, with */
10 /* the special exception on linking described in file ../../LICENSE. */
11 /* */
12 /***********************************************************************/
14 /* $Id$ */
16 #include <errno.h>
17 #include <string.h>
18 #include <mlvalues.h>
19 #include <memory.h>
20 #include <signals.h>
21 #include "unixsupport.h"
23 #ifndef EAGAIN
24 #define EAGAIN (-1)
25 #endif
26 #ifndef EWOULDBLOCK
27 #define EWOULDBLOCK (-1)
28 #endif
30 CAMLprim value unix_write(value fd, value buf, value vofs, value vlen)
32 long ofs, len, written;
33 int numbytes, ret;
34 char iobuf[UNIX_BUFFER_SIZE];
36 Begin_root (buf);
37 ofs = Long_val(vofs);
38 len = Long_val(vlen);
39 written = 0;
40 while (len > 0) {
41 numbytes = len > UNIX_BUFFER_SIZE ? UNIX_BUFFER_SIZE : len;
42 memmove (iobuf, &Byte(buf, ofs), numbytes);
43 enter_blocking_section();
44 ret = write(Int_val(fd), iobuf, numbytes);
45 leave_blocking_section();
46 if (ret == -1) {
47 if ((errno == EAGAIN || errno == EWOULDBLOCK) && written > 0) break;
48 uerror("write", Nothing);
50 written += ret;
51 ofs += ret;
52 len -= ret;
54 End_roots();
55 return Val_long(written);
58 /* When an error occurs after the first loop, unix_write reports the
59 error and discards the number of already written characters.
60 In this case, it would be better to discard the error and return the
61 number of bytes written, since most likely, unix_write will be call again,
62 and the error will be reproduced and this time will be reported.
63 This problem is avoided in unix_single_write, which is faithful to the
64 Unix system call. */
66 CAMLprim value unix_single_write(value fd, value buf, value vofs, value vlen)
68 long ofs, len;
69 int numbytes, ret;
70 char iobuf[UNIX_BUFFER_SIZE];
72 Begin_root (buf);
73 ofs = Long_val(vofs);
74 len = Long_val(vlen);
75 ret = 0;
76 if (len > 0) {
77 numbytes = len > UNIX_BUFFER_SIZE ? UNIX_BUFFER_SIZE : len;
78 memmove (iobuf, &Byte(buf, ofs), numbytes);
79 enter_blocking_section();
80 ret = write(Int_val(fd), iobuf, numbytes);
81 leave_blocking_section();
82 if (ret == -1) uerror("single_write", Nothing);
84 End_roots();
85 return Val_int(ret);