xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/unix_trigger.c (revision e89934bbf778a6d6d6894877c4da59d0c7835b0f)
1 /*	$NetBSD: unix_trigger.c,v 1.2 2017/02/14 01:16:49 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	unix_trigger 3
6 /* SUMMARY
7 /*	wakeup UNIX-domain server
8 /* SYNOPSIS
9 /*	#include <trigger.h>
10 /*
11 /*	int	unix_trigger(service, buf, len, timeout)
12 /*	const char *service;
13 /*	const char *buf;
14 /*	ssize_t	len;
15 /*	int	timeout;
16 /* DESCRIPTION
17 /*	unix_trigger() wakes up the named UNIX-domain server by making
18 /*	a brief connection to it and writing the named buffer.
19 /*
20 /*	The connection is closed by a background thread. Some kernels
21 /*	cannot handle client-side disconnect before the server has
22 /*	received the message.
23 /*
24 /*	Arguments:
25 /* .IP service
26 /*	Name of the communication endpoint.
27 /* .IP buf
28 /*	Address of data to be written.
29 /* .IP len
30 /*	Amount of data to be written.
31 /* .IP timeout
32 /*	Deadline in seconds. Specify a value <= 0 to disable
33 /*	the time limit.
34 /* DIAGNOSTICS
35 /*	The result is zero in case of success, -1 in case of problems.
36 /* SEE ALSO
37 /*	unix_connect(3), UNIX-domain client
38 /* LICENSE
39 /* .ad
40 /* .fi
41 /*	The Secure Mailer license must be distributed with this software.
42 /* AUTHOR(S)
43 /*	Wietse Venema
44 /*	IBM T.J. Watson Research
45 /*	P.O. Box 704
46 /*	Yorktown Heights, NY 10598, USA
47 /*--*/
48 
49 /* System library. */
50 
51 #include <sys_defs.h>
52 #include <sys/socket.h>
53 #include <unistd.h>
54 #include <string.h>
55 
56 /* Utility library. */
57 
58 #include <msg.h>
59 #include <connect.h>
60 #include <iostuff.h>
61 #include <mymalloc.h>
62 #include <events.h>
63 #include <trigger.h>
64 
65 struct unix_trigger {
66     int     fd;
67     char   *service;
68 };
69 
70 /* unix_trigger_event - disconnect from peer */
71 
unix_trigger_event(int event,void * context)72 static void unix_trigger_event(int event, void *context)
73 {
74     struct unix_trigger *up = (struct unix_trigger *) context;
75     static const char *myname = "unix_trigger_event";
76 
77     /*
78      * Disconnect.
79      */
80     if (event == EVENT_TIME)
81 	msg_warn("%s: read timeout for service %s", myname, up->service);
82     event_disable_readwrite(up->fd);
83     event_cancel_timer(unix_trigger_event, context);
84     if (close(up->fd) < 0)
85 	msg_warn("%s: close %s: %m", myname, up->service);
86     myfree(up->service);
87     myfree((void *) up);
88 }
89 
90 /* unix_trigger - wakeup UNIX-domain server */
91 
unix_trigger(const char * service,const char * buf,ssize_t len,int timeout)92 int     unix_trigger(const char *service, const char *buf, ssize_t len, int timeout)
93 {
94     const char *myname = "unix_trigger";
95     struct unix_trigger *up;
96     int     fd;
97 
98     if (msg_verbose > 1)
99 	msg_info("%s: service %s", myname, service);
100 
101     /*
102      * Connect...
103      */
104     if ((fd = unix_connect(service, BLOCKING, timeout)) < 0) {
105 	if (msg_verbose)
106 	    msg_warn("%s: connect to %s: %m", myname, service);
107 	return (-1);
108     }
109     close_on_exec(fd, CLOSE_ON_EXEC);
110 
111     /*
112      * Stash away context.
113      */
114     up = (struct unix_trigger *) mymalloc(sizeof(*up));
115     up->fd = fd;
116     up->service = mystrdup(service);
117 
118     /*
119      * Write the request...
120      */
121     if (write_buf(fd, buf, len, timeout) < 0
122 	|| write_buf(fd, "", 1, timeout) < 0)
123 	if (msg_verbose)
124 	    msg_warn("%s: write to %s: %m", myname, service);
125 
126     /*
127      * Wakeup when the peer disconnects, or when we lose patience.
128      */
129     if (timeout > 0)
130 	event_request_timer(unix_trigger_event, (void *) up, timeout + 100);
131     event_enable_read(fd, unix_trigger_event, (void *) up);
132     return (0);
133 }
134