X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=blobdiff_plain;f=src%2Fsrc%2Fexim.c;h=f09b26902a3a7b77b818b741503f0501c3a870f9;hp=419561c8500fd5cb6bf651c96272aeb9d529fb22;hb=2cee425af0f8c425a410ff12a51f05a175a0c80b;hpb=6c4545562d5b520ad23d9470382dde4b2af9671f diff --git a/src/src/exim.c b/src/src/exim.c index 419561c85..f09b26902 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -5839,4 +5839,50 @@ exim_exit(EXIT_SUCCESS); /* Never returns */ return 0; /* To stop compiler warning */ } +/************************************************* +* read as much as requested * +*************************************************/ + +/* The syscall read(2) doesn't always returns as much as we want. For +several reasons it might get less. (Not talking about signals, as syscalls +are restartable). When reading from a network or pipe connection the sender +might send in smaller chunks, with delays between these chunks. The read(2) +may return such a chunk. + +The more the writer writes and the smaller the pipe between write and read is, +the more we get the chance of reading leass than requested. (See bug 2130) + +This function read(2)s until we got all the data we *requested*. + +Note: This function may block. Use it only if you're sure about the +amount of data you will get. + +Argument: + fd the file descriptor to read from + buffer pointer to a buffer of size len + len the requested(!) amount of bytes + +Returns: the amount of bytes read +*/ +ssize_t +readn(int fd, void *buffer, size_t len) +{ + void *next = buffer; + void *end = buffer + len; + + while (next < end) + { + ssize_t got = read(fd, next, end - next); + + /* I'm not sure if there are signals that can interrupt us, + for now I assume the worst */ + if (got == -1 && errno == EINTR) continue; + if (got <= 0) return next - buffer; + next += got; + } + + return len; +} + + /* End of exim.c */