Postfix3.3.1
mail_flow.c
[詳解]
1 /*++
2 /* NAME
3 /* mail_flow 3
4 /* SUMMARY
5 /* global mail flow control
6 /* SYNOPSIS
7 /* #include <mail_flow.h>
8 /*
9 /* ssize_t mail_flow_get(count)
10 /* ssize_t count;
11 /*
12 /* ssize_t mail_flow_put(count)
13 /* ssize_t count;
14 /*
15 /* ssize_t mail_flow_count()
16 /* DESCRIPTION
17 /* This module implements a simple flow control mechanism that
18 /* is based on tokens that are consumed by mail receiving processes
19 /* and that are produced by mail sending processes.
20 /*
21 /* mail_flow_get() attempts to read specified number of tokens. The
22 /* result is > 0 for success, < 0 for failure. In the latter case,
23 /* the process is expected to slow down a little.
24 /*
25 /* mail_flow_put() produces the specified number of tokens. The
26 /* token producing process is expected to produce new tokens
27 /* whenever it falls idle and no more tokens are available.
28 /*
29 /* mail_flow_count() returns the number of available tokens.
30 /* BUGS
31 /* The producer needs to wake up periodically to ensure that
32 /* tokens are not lost due to leakage.
33 /* LICENSE
34 /* .ad
35 /* .fi
36 /* The Secure Mailer license must be distributed with this software.
37 /* AUTHOR(S)
38 /* Wietse Venema
39 /* IBM T.J. Watson Research
40 /* P.O. Box 704
41 /* Yorktown Heights, NY 10598, USA
42 /*--*/
43 
44 /* System library. */
45 
46 #include <sys_defs.h>
47 #include <sys/stat.h>
48 #include <unistd.h>
49 #include <stdlib.h>
50 #include <string.h>
51 
52 /* Utility library. */
53 
54 #include <msg.h>
55 #include <iostuff.h>
56 #include <warn_stat.h>
57 
58 /* Global library. */
59 
60 #include <mail_flow.h>
61 
62 /* Master library. */
63 
64 #include <master_proto.h>
65 
66 #define BUFFER_SIZE 1024
67 
68 /* mail_flow_get - read N tokens */
69 
70 ssize_t mail_flow_get(ssize_t len)
71 {
72  const char *myname = "mail_flow_get";
73  char buf[BUFFER_SIZE];
74  struct stat st;
75  ssize_t count;
76  ssize_t n = 0;
77 
78  /*
79  * Sanity check.
80  */
81  if (len <= 0)
82  msg_panic("%s: bad length %ld", myname, (long) len);
83 
84  /*
85  * Silence some wild claims.
86  */
87  if (fstat(MASTER_FLOW_WRITE, &st) < 0)
88  msg_fatal("fstat flow pipe write descriptor: %m");
89 
90  /*
91  * Read and discard N bytes. XXX AIX read() can return 0 when an open
92  * pipe is empty.
93  */
94  for (count = len; count > 0; count -= n)
95  if ((n = read(MASTER_FLOW_READ, buf, count > BUFFER_SIZE ?
96  BUFFER_SIZE : count)) <= 0)
97  return (-1);
98  if (msg_verbose)
99  msg_info("%s: %ld %ld", myname, (long) len, (long) (len - count));
100  return (len - count);
101 }
102 
103 /* mail_flow_put - put N tokens */
104 
105 ssize_t mail_flow_put(ssize_t len)
106 {
107  const char *myname = "mail_flow_put";
108  char buf[BUFFER_SIZE];
109  ssize_t count;
110  ssize_t n = 0;
111 
112  /*
113  * Sanity check.
114  */
115  if (len <= 0)
116  msg_panic("%s: bad length %ld", myname, (long) len);
117 
118  /*
119  * Write or discard N bytes.
120  */
121  memset(buf, 0, len > BUFFER_SIZE ? BUFFER_SIZE : len);
122 
123  for (count = len; count > 0; count -= n)
124  if ((n = write(MASTER_FLOW_WRITE, buf, count > BUFFER_SIZE ?
125  BUFFER_SIZE : count)) < 0)
126  return (-1);
127  if (msg_verbose)
128  msg_info("%s: %ld %ld", myname, (long) len, (long) (len - count));
129  return (len - count);
130 }
131 
132 /* mail_flow_count - return number of available tokens */
133 
134 ssize_t mail_flow_count(void)
135 {
136  const char *myname = "mail_flow_count";
137  ssize_t count;
138 
139  if ((count = peekfd(MASTER_FLOW_READ)) < 0)
140  msg_warn("%s: %m", myname);
141  return (count);
142 }
int msg_verbose
Definition: msg.c:177
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
ssize_t mail_flow_count(void)
Definition: mail_flow.c:134
#define stat(p, s)
Definition: warn_stat.h:18
#define MASTER_FLOW_WRITE
Definition: master_proto.h:44
#define MASTER_FLOW_READ
Definition: master_proto.h:43
ssize_t mail_flow_put(ssize_t len)
Definition: mail_flow.c:105
ssize_t mail_flow_get(ssize_t len)
Definition: mail_flow.c:70
void msg_warn(const char *fmt,...)
Definition: msg.c:215
#define BUFFER_SIZE
Definition: mail_flow.c:66
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
ssize_t peekfd(int)
Definition: peekfd.c:60
#define fstat(f, s)
Definition: warn_stat.h:20
void msg_info(const char *fmt,...)
Definition: msg.c:199