2 * This code is copyright 2001 by Craig Hughes
3 * Portions copyright 2002 by Brad Jorsch
4 * It is licensed under the same license as Perl itself. The text of this
5 * license is included in the SpamAssassin distribution in the file named
12 #include <sys/types.h>
18 /* Dec 13 2001 jm: added safe full-read and full-write functions. These
19 * can cope with networks etc., where a write or read may not read all
20 * the data that's there, in one call.
22 /* Aug 14, 2002 bj: EINTR and EAGAIN aren't fatal, are they? */
23 /* Aug 14, 2002 bj: moved these to utils.c */
24 /* Jan 13, 2003 ym: added timeout functionality */
26 typedef void sigfunc(int); /* for signal handlers */
28 sigfunc* sig_catch(int sig, void (*f)(int))
30 struct sigaction act, oact;
33 sigemptyset(&act.sa_mask);
34 sigaction(sig, &act, &oact);
35 return oact.sa_handler;
38 static void catch_alrm(int x) {
42 ssize_t timeout_read(ssize_t (*reader)(int d, void *buf, size_t nbytes),
43 int fd, void *buf, size_t nbytes) {
47 sig = sig_catch(SIGALRM, catch_alrm);
48 if (libspamc_timeout > 0) {
49 alarm(libspamc_timeout);
53 nred = reader(fd, buf, nbytes);
54 } while(nred < 0 && errno == EAGAIN);
56 if(nred < 0 && errno == EINTR)
59 if (libspamc_timeout > 0) {
63 /* restore old signal handler */
64 sig_catch(SIGALRM, sig);
70 full_read (int fd, unsigned char *buf, int min, int len)
76 for (total = 0; total < min; ) {
77 thistime = timeout_read (read, fd, buf+total, len-total);
81 } else if (thistime == 0) {
82 /* EOF, but we didn't read the minimum. return what we've read
83 * so far and next read (if there is one) will return 0. */
93 full_write (int fd, const unsigned char *buf, int len)
98 for (total = 0; total < len; ) {
99 thistime = write (fd, buf+total, len-total);
102 if(EINTR == errno || EAGAIN == errno) continue;
103 return thistime; /* always an error for writes */