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 /* -------------------------------------------------------------------------- */
28 typedef void sigfunc(int); /* for signal handlers */
30 sigfunc* sig_catch(int sig, void (*f)(int))
32 struct sigaction act, oact;
35 sigemptyset(&act.sa_mask);
36 sigaction(sig, &act, &oact);
37 return oact.sa_handler;
40 static void catch_alrm(int x) {
45 fd_timeout_read (int fd, void *buf, size_t nbytes)
50 sig = sig_catch(SIGALRM, catch_alrm);
51 if (libspamc_timeout > 0) {
52 alarm(libspamc_timeout);
56 nred = read (fd, buf, nbytes);
57 } while(nred < 0 && errno == EAGAIN);
59 if(nred < 0 && errno == EINTR)
62 if (libspamc_timeout > 0) {
66 /* restore old signal handler */
67 sig_catch(SIGALRM, sig);
73 ssl_timeout_read (SSL *ssl, void *buf, int nbytes)
78 sig = sig_catch(SIGALRM, catch_alrm);
79 if (libspamc_timeout > 0) {
80 alarm(libspamc_timeout);
85 nred = SSL_read (ssl, buf, nbytes);
87 nred = 0; /* never used */
89 } while(nred < 0 && errno == EAGAIN);
91 if(nred < 0 && errno == EINTR)
94 if (libspamc_timeout > 0) {
98 /* restore old signal handler */
99 sig_catch(SIGALRM, sig);
104 /* -------------------------------------------------------------------------- */
107 full_read (int fd, unsigned char *buf, int min, int len)
112 for (total = 0; total < min; ) {
113 thistime = fd_timeout_read (fd, buf+total, len-total);
117 } else if (thistime == 0) {
118 /* EOF, but we didn't read the minimum. return what we've read
119 * so far and next read (if there is one) will return 0. */
129 full_write (int fd, const unsigned char *buf, int len)
134 for (total = 0; total < len; ) {
135 thistime = write (fd, buf+total, len-total);
138 if(EINTR == errno || EAGAIN == errno) continue;
139 return thistime; /* always an error for writes */