~yolanda.robla/ubuntu/saucy/postfix/dep-8-tests

« back to all changes in this revision

Viewing changes to src/util/unix_pass_trigger.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones, Wietse Venema, LaMont Jones
  • Date: 2013-03-04 09:03:31 UTC
  • mfrom: (1.1.38)
  • Revision ID: package-import@ubuntu.com-20130304090331-y185njqiuuazwgei
Tags: 2.10.0-1
[Wietse Venema]

* New upstream version

[LaMont Jones]

* Fix fumbled merge to actually have the right maintainer address. 
  Closes: #699877
* Fix how we copy $smtp_tls_CApath into the chroot.  LP: #1139159

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[2];
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[0] = pair[0];
133
 
    up->pair[1] = pair[1];
134
 
 
135
 
    /*
136
 
     * Write the request...
137
 
     */
138
 
    if (write_buf(pair[1], buf, len, timeout) < 0
139
 
        || write_buf(pair[1], "", 1, timeout) < 0)
140
 
        if (msg_verbose)
141
 
            msg_warn("%s: write to %s: %m", myname, service);
142
 
 
143
 
    /*
144
 
     * Wakeup when the peer disconnects, or when we lose patience.
145
 
     */
146
 
    if (timeout > 0)
147
 
        event_request_timer(unix_pass_trigger_event, (char *) up, timeout + 100);
148
 
    event_enable_read(fd, unix_pass_trigger_event, (char *) up);
149
 
    return (0);
150
 
}