Sync usage with man page.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / util / fifo_trigger.c
blobe0198ff79c5ddc95daf481af6949d28825f0cf7e
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* fifo_trigger 3
6 /* SUMMARY
7 /* wakeup fifo server
8 /* SYNOPSIS
9 /* #include <trigger.h>
11 /* int fifo_trigger(service, buf, len, timeout)
12 /* const char *service;
13 /* const char *buf;
14 /* ssize_t len;
15 /* int timeout;
16 /* DESCRIPTION
17 /* fifo_trigger() wakes up the named fifo server by writing
18 /* the contents of the specified buffer to the fifo. There is
19 /* no guarantee that the written data will actually be received.
21 /* Arguments:
22 /* .IP service
23 /* Name of the communication endpoint.
24 /* .IP buf
25 /* Address of data to be written.
26 /* .IP len
27 /* Amount of data to be written.
28 /* .IP timeout
29 /* Deadline in seconds. Specify a value <= 0 to disable
30 /* the time limit.
31 /* DIAGNOSTICS
32 /* The result is zero when the fifo could be opened, -1 otherwise.
33 /* BUGS
34 /* LICENSE
35 /* .ad
36 /* .fi
37 /* The Secure Mailer license must be distributed with this software.
38 /* AUTHOR(S)
39 /* Wietse Venema
40 /* IBM T.J. Watson Research
41 /* P.O. Box 704
42 /* Yorktown Heights, NY 10598, USA
43 /*--*/
45 /* System library. */
47 #include <sys_defs.h>
48 #include <fcntl.h>
49 #include <unistd.h>
51 /* Utility library. */
53 #include <msg.h>
54 #include <iostuff.h>
55 #include <safe_open.h>
56 #include <trigger.h>
58 /* fifo_trigger - wakeup fifo server */
60 int fifo_trigger(const char *service, const char *buf, ssize_t len, int timeout)
62 static VSTRING *why;
63 const char *myname = "fifo_trigger";
64 VSTREAM *fp;
65 int fd;
67 if (why == 0)
68 why = vstring_alloc(1);
71 * Write the request to the service fifo. According to POSIX, the open
72 * shall always return immediately, and shall return an error when no
73 * process is reading from the FIFO.
75 * Use safe_open() so that we don't follow symlinks, and so that we don't
76 * open files with multiple hard links. We're not (yet) going to bother
77 * the caller with safe_open() specific quirks such as the why argument.
79 if ((fp = safe_open(service, O_WRONLY | O_NONBLOCK, 0,
80 (struct stat *) 0, -1, -1, why)) == 0) {
81 if (msg_verbose)
82 msg_info("%s: open %s: %s", myname, service, vstring_str(why));
83 return (-1);
85 fd = vstream_fileno(fp);
88 * Write the request...
90 non_blocking(fd, timeout > 0 ? NON_BLOCKING : BLOCKING);
91 if (write_buf(fd, buf, len, timeout) < 0)
92 if (msg_verbose)
93 msg_warn("%s: write %s: %m", myname, service);
96 * Disconnect.
98 if (vstream_fclose(fp))
99 if (msg_verbose)
100 msg_warn("%s: close %s: %m", myname, service);
101 return (0);
104 #ifdef TEST
107 * Set up a FIFO listener, and keep triggering until the listener becomes
108 * idle, which should never happen.
110 #include <signal.h>
111 #include <stdlib.h>
113 #include "events.h"
114 #include "listen.h"
116 #define TEST_FIFO "test-fifo"
118 int trig_count;
119 int wakeup_count;
121 static void cleanup(void)
123 unlink(TEST_FIFO);
124 exit(1);
127 static void handler(int sig)
129 msg_fatal("got signal %d after %d triggers %d wakeups",
130 sig, trig_count, wakeup_count);
133 static void read_event(int unused_event, char *context)
135 int fd = CAST_CHAR_PTR_TO_INT(context);
136 char ch;
138 wakeup_count++;
140 if (read(fd, &ch, 1) != 1)
141 msg_fatal("read %s: %m", TEST_FIFO);
144 int main(int unused_argc, char **unused_argv)
146 int listen_fd;
148 listen_fd = fifo_listen(TEST_FIFO, 0600, NON_BLOCKING);
149 msg_cleanup(cleanup);
150 event_enable_read(listen_fd, read_event, CAST_INT_TO_CHAR_PTR(listen_fd));
151 signal(SIGINT, handler);
152 signal(SIGALRM, handler);
153 for (;;) {
154 alarm(10);
155 if (fifo_trigger(TEST_FIFO, "", 1, 0) < 0)
156 msg_fatal("trigger %s: %m", TEST_FIFO);
157 trig_count++;
158 if (fifo_trigger(TEST_FIFO, "", 1, 0) < 0)
159 msg_fatal("trigger %s: %m", TEST_FIFO);
160 trig_count++;
161 if (fifo_trigger(TEST_FIFO, "", 1, 0) < 0)
162 msg_fatal("trigger %s: %m", TEST_FIFO);
163 trig_count++;
164 event_loop(-1);
165 event_loop(-1);
166 event_loop(-1);
170 #endif