summaryrefslogtreecommitdiff
path: root/gnu/dist/postfix/src/util/inet_trigger.c
diff options
context:
space:
mode:
authorperry <perry@NetBSD.org>2002-02-02 23:10:24 +0000
committerperry <perry@NetBSD.org>2002-02-02 23:10:24 +0000
commit6f59dc7aebbf705da79e61ef3fd24b48ed99d327 (patch)
treec6e9fd356c8aac78b966a9dd53f5d0d14d5e62cd /gnu/dist/postfix/src/util/inet_trigger.c
parentecf43984517b4cfb837e78958769cc8207ea5288 (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.c49
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);
}