~ubuntu-branches/ubuntu/saucy/postfix/saucy

« back to all changes in this revision

Viewing changes to src/util/unix_pass_trigger.c

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2011-02-22 11:20:43 UTC
  • mfrom: (1.1.27 upstream)
  • Revision ID: james.westby@ubuntu.com-20110222112043-c34ht219w3ybrilr
Tags: 2.8.0-2
* a little more lintian cleanup
* Fix missing format strings in smtp-sink.c

Show diffs side-by-side

added added

removed removed

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