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 */