diff options
| author | perry <perry@NetBSD.org> | 2002-02-02 23:10:24 +0000 |
|---|---|---|
| committer | perry <perry@NetBSD.org> | 2002-02-02 23:10:24 +0000 |
| commit | 6f59dc7aebbf705da79e61ef3fd24b48ed99d327 (patch) | |
| tree | c6e9fd356c8aac78b966a9dd53f5d0d14d5e62cd /gnu/dist/postfix/src/util/inet_trigger.c | |
| parent | ecf43984517b4cfb837e78958769cc8207ea5288 (diff) | |
Postfix 1.1.2
(Postfix releases are now numbered -- 1.1.2 means 1.1, patchlevel 2.)
Lots of new features, same great security.
Diffstat (limited to 'gnu/dist/postfix/src/util/inet_trigger.c')
| -rw-r--r-- | gnu/dist/postfix/src/util/inet_trigger.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/gnu/dist/postfix/src/util/inet_trigger.c b/gnu/dist/postfix/src/util/inet_trigger.c index e92c2d8dbfb..dddbcb62aac 100644 --- a/gnu/dist/postfix/src/util/inet_trigger.c +++ b/gnu/dist/postfix/src/util/inet_trigger.c @@ -16,6 +16,10 @@ /* a brief connection to it and by writing the contents of the /* named buffer. /* +/* The connection is closed by a background thread. Some kernels +/* cannot handle client-side disconnect before the server has +/* received the message. +/* /* Arguments: /* .IP service /* Name of the communication endpoint. @@ -45,6 +49,7 @@ /* System library. */ #include <sys_defs.h> +#include <sys/socket.h> #include <unistd.h> #include <string.h> @@ -53,13 +58,42 @@ #include <msg.h> #include <connect.h> #include <iostuff.h> +#include <mymalloc.h> +#include <events.h> #include <trigger.h> +struct inet_trigger { + int fd; + char *service; +}; + +/* inet_trigger_event - disconnect from peer */ + +static void inet_trigger_event(int event, char *context) +{ + struct inet_trigger *ip = (struct inet_trigger *) context; + static char *myname = "inet_trigger_event"; + + /* + * Disconnect. + */ + if (event == EVENT_TIME) + msg_warn("%s: read timeout for service %s", myname, ip->service); + event_disable_readwrite(ip->fd); + event_cancel_timer(inet_trigger_event, context); + if (close(ip->fd) < 0) + msg_warn("%s: close %s: %m", myname, ip->service); + myfree(ip->service); + myfree((char *) ip); +} + + /* inet_trigger - wakeup INET-domain server */ int inet_trigger(const char *service, const char *buf, int len, int timeout) { char *myname = "inet_trigger"; + struct inet_trigger *ip; int fd; if (msg_verbose > 1) @@ -73,19 +107,24 @@ int inet_trigger(const char *service, const char *buf, int len, int timeout) msg_warn("%s: connect to %s: %m", myname, service); return (-1); } + close_on_exec(fd, CLOSE_ON_EXEC); + ip = (struct inet_trigger *) mymalloc(sizeof(*ip)); + ip->fd = fd; + ip->service = mystrdup(service); /* * Write the request... */ - if (write_buf(fd, buf, len, timeout) < 0) + if (write_buf(fd, buf, len, timeout) < 0 + || write_buf(fd, "", 1, timeout) < 0) if (msg_verbose) msg_warn("%s: write to %s: %m", myname, service); /* - * Disconnect. + * Wakeup when the peer disconnects, or when we lose patience. */ - if (close(fd) < 0) - if (msg_verbose) - msg_warn("%s: close %s: %m", myname, service); + if (timeout > 0) + event_request_timer(inet_trigger_event, (char *) ip, timeout + 100); + event_enable_read(fd, inet_trigger_event, (char *) ip); return (0); } |
