Postfix3.3.1
vstream.h
[詳解]
1 #ifndef _VSTREAM_H_INCLUDED_
2 #define _VSTREAM_H_INCLUDED_
3 
4 /*++
5 /* NAME
6 /* vstream 3h
7 /* SUMMARY
8 /* simple buffered I/O package
9 /* SYNOPSIS
10 /* #include <vstream.h>
11 /* DESCRIPTION
12 /* .nf
13 
14  /*
15  * System library.
16  */
17 #include <sys/time.h>
18 #include <time.h>
19 #include <fcntl.h>
20 #include <stdarg.h>
21 #include <setjmp.h>
22 #include <unistd.h>
23 
24  /*
25  * Utility library.
26  */
27 #include <vbuf.h>
28 #include <check_arg.h>
29 
30  /*
31  * Simple buffered stream. The members of this structure are not part of the
32  * official interface and can change without prior notice.
33  */
34 typedef ssize_t (*VSTREAM_RW_FN) (int, void *, size_t, int, void *);
35 typedef pid_t(*VSTREAM_WAITPID_FN) (pid_t, WAIT_STATUS_T *, int);
36 
37 #ifdef NO_SIGSETJMP
38 #define VSTREAM_JMP_BUF jmp_buf
39 #else
40 #define VSTREAM_JMP_BUF sigjmp_buf
41 #endif
42 
43 typedef struct VSTREAM {
44  VBUF buf; /* generic intelligent buffer */
45  int fd; /* file handle, no 256 limit */
46  VSTREAM_RW_FN read_fn; /* buffer fill action */
47  VSTREAM_RW_FN write_fn; /* buffer fill action */
48  ssize_t req_bufsize; /* requested read/write buffer size */
49  void *context; /* application context */
50  off_t offset; /* cached seek info */
51  char *path; /* give it at least try */
52  int read_fd; /* read channel (double-buffered) */
53  int write_fd; /* write channel (double-buffered) */
54  VBUF read_buf; /* read buffer (double-buffered) */
55  VBUF write_buf; /* write buffer (double-buffered) */
56  pid_t pid; /* vstream_popen/close() */
57  VSTREAM_WAITPID_FN waitpid_fn; /* vstream_popen/close() */
58  int timeout; /* read/write timeout */
59  VSTREAM_JMP_BUF *jbuf; /* exception handling */
60  struct timeval iotime; /* time of last fill/flush */
61  struct timeval time_limit; /* read/write time limit */
62 } VSTREAM;
63 
64 extern VSTREAM vstream_fstd[]; /* pre-defined streams */
65 
66 #define VSTREAM_IN (&vstream_fstd[0])
67 #define VSTREAM_OUT (&vstream_fstd[1])
68 #define VSTREAM_ERR (&vstream_fstd[2])
69 
70 #define VSTREAM_FLAG_RD_ERR VBUF_FLAG_RD_ERR /* read error */
71 #define VSTREAM_FLAG_WR_ERR VBUF_FLAG_WR_ERR /* write error */
72 #define VSTREAM_FLAG_RD_TIMEOUT VBUF_FLAG_RD_TIMEOUT /* read timeout */
73 #define VSTREAM_FLAG_WR_TIMEOUT VBUF_FLAG_WR_TIMEOUT /* write timeout */
74 
75 #define VSTREAM_FLAG_ERR VBUF_FLAG_ERR /* some I/O error */
76 #define VSTREAM_FLAG_EOF VBUF_FLAG_EOF /* end of file */
77 #define VSTREAM_FLAG_TIMEOUT VBUF_FLAG_TIMEOUT /* timeout error */
78 #define VSTREAM_FLAG_FIXED VBUF_FLAG_FIXED /* fixed-size buffer */
79 #define VSTREAM_FLAG_BAD VBUF_FLAG_BAD
80 
81 #define VSTREAM_FLAG_READ (1<<8) /* read buffer */
82 #define VSTREAM_FLAG_WRITE (1<<9) /* write buffer */
83 #define VSTREAM_FLAG_SEEK (1<<10) /* seek info valid */
84 #define VSTREAM_FLAG_NSEEK (1<<11) /* can't seek this file */
85 #define VSTREAM_FLAG_DOUBLE (1<<12) /* double buffer */
86 #define VSTREAM_FLAG_DEADLINE (1<<13) /* deadline active */
87 
88 #define VSTREAM_PURGE_READ (1<<0) /* flush unread data */
89 #define VSTREAM_PURGE_WRITE (1<<1) /* flush unwritten data */
90 #define VSTREAM_PURGE_BOTH (VSTREAM_PURGE_READ|VSTREAM_PURGE_WRITE)
91 
92 #define VSTREAM_BUFSIZE 4096
93 
94 extern VSTREAM *vstream_fopen(const char *, int, mode_t);
95 extern int vstream_fclose(VSTREAM *);
96 extern off_t WARN_UNUSED_RESULT vstream_fseek(VSTREAM *, off_t, int);
97 extern off_t vstream_ftell(VSTREAM *);
98 extern int vstream_fpurge(VSTREAM *, int);
99 extern int vstream_fflush(VSTREAM *);
100 extern int vstream_fputs(const char *, VSTREAM *);
101 extern VSTREAM *vstream_fdopen(int, int);
102 extern int vstream_fdclose(VSTREAM *);
103 
104 #define vstream_fread(v, b, n) vbuf_read(&(v)->buf, (b), (n))
105 #define vstream_fwrite(v, b, n) vbuf_write(&(v)->buf, (b), (n))
106 
107 #define VSTREAM_PUTC(ch, vp) VBUF_PUT(&(vp)->buf, (ch))
108 #define VSTREAM_GETC(vp) VBUF_GET(&(vp)->buf)
109 #define vstream_ungetc(vp, ch) vbuf_unget(&(vp)->buf, (ch))
110 #define VSTREAM_EOF VBUF_EOF
111 
112 #define VSTREAM_PUTCHAR(ch) VSTREAM_PUTC((ch), VSTREAM_OUT)
113 #define VSTREAM_GETCHAR() VSTREAM_GETC(VSTREAM_IN)
114 
115 #define vstream_fileno(vp) ((vp)->fd)
116 #define vstream_req_bufsize(vp) ((const ssize_t) ((vp)->req_bufsize))
117 #define vstream_context(vp) ((vp)->context)
118 #define vstream_rd_error(vp) vbuf_rd_error(&(vp)->buf)
119 #define vstream_wr_error(vp) vbuf_wr_error(&(vp)->buf)
120 #define vstream_ferror(vp) vbuf_error(&(vp)->buf)
121 #define vstream_feof(vp) vbuf_eof(&(vp)->buf)
122 #define vstream_rd_timeout(vp) vbuf_rd_timeout(&(vp)->buf)
123 #define vstream_wr_timeout(vp) vbuf_wr_timeout(&(vp)->buf)
124 #define vstream_ftimeout(vp) vbuf_timeout(&(vp)->buf)
125 #define vstream_clearerr(vp) vbuf_clearerr(&(vp)->buf)
126 #define VSTREAM_PATH(vp) ((vp)->path ? (const char *) (vp)->path : "unknown_stream")
127 #define vstream_ftime(vp) ((time_t) ((vp)->iotime.tv_sec))
128 #define vstream_ftimeval(vp) ((vp)->iotime)
129 
130 #define vstream_fstat(vp, fl) ((vp)->buf.flags & (fl))
131 
132 extern void vstream_control(VSTREAM *, int,...);
133 
134 /* Legacy API: type-unchecked arguments, internal use. */
135 #define VSTREAM_CTL_END 0
136 #define VSTREAM_CTL_READ_FN 1
137 #define VSTREAM_CTL_WRITE_FN 2
138 #define VSTREAM_CTL_PATH 3
139 #define VSTREAM_CTL_DOUBLE 4
140 #define VSTREAM_CTL_READ_FD 5
141 #define VSTREAM_CTL_WRITE_FD 6
142 #define VSTREAM_CTL_WAITPID_FN 7
143 #define VSTREAM_CTL_TIMEOUT 8
144 #define VSTREAM_CTL_EXCEPT 9
145 #define VSTREAM_CTL_CONTEXT 10
146 #ifdef F_DUPFD
147 #define VSTREAM_CTL_DUPFD 11
148 #endif
149 #define VSTREAM_CTL_BUFSIZE 12
150 #define VSTREAM_CTL_SWAP_FD 13
151 #define VSTREAM_CTL_START_DEADLINE 14
152 #define VSTREAM_CTL_STOP_DEADLINE 15
153 
154 /* Safer API: type-checked arguments, external use. */
155 #define CA_VSTREAM_CTL_END VSTREAM_CTL_END
156 #define CA_VSTREAM_CTL_READ_FN(v) VSTREAM_CTL_READ_FN, CHECK_VAL(VSTREAM_CTL, VSTREAM_RW_FN, (v))
157 #define CA_VSTREAM_CTL_WRITE_FN(v) VSTREAM_CTL_WRITE_FN, CHECK_VAL(VSTREAM_CTL, VSTREAM_RW_FN, (v))
158 #define CA_VSTREAM_CTL_PATH(v) VSTREAM_CTL_PATH, CHECK_CPTR(VSTREAM_CTL, char, (v))
159 #define CA_VSTREAM_CTL_DOUBLE VSTREAM_CTL_DOUBLE
160 #define CA_VSTREAM_CTL_READ_FD(v) VSTREAM_CTL_READ_FD, CHECK_VAL(VSTREAM_CTL, int, (v))
161 #define CA_VSTREAM_CTL_WRITE_FD(v) VSTREAM_CTL_WRITE_FD, CHECK_VAL(VSTREAM_CTL, int, (v))
162 #define CA_VSTREAM_CTL_WAITPID_FN(v) VSTREAM_CTL_WAITPID_FN, CHECK_VAL(VSTREAM_CTL, VSTREAM_WAITPID_FN, (v))
163 #define CA_VSTREAM_CTL_TIMEOUT(v) VSTREAM_CTL_TIMEOUT, CHECK_VAL(VSTREAM_CTL, int, (v))
164 #define CA_VSTREAM_CTL_EXCEPT VSTREAM_CTL_EXCEPT
165 #define CA_VSTREAM_CTL_CONTEXT(v) VSTREAM_CTL_CONTEXT, CHECK_PTR(VSTREAM_CTL, void, (v))
166 #ifdef F_DUPFD
167 #define CA_VSTREAM_CTL_DUPFD(v) VSTREAM_CTL_DUPFD, CHECK_VAL(VSTREAM_CTL, int, (v))
168 #endif
169 #define CA_VSTREAM_CTL_BUFSIZE(v) VSTREAM_CTL_BUFSIZE, CHECK_VAL(VSTREAM_CTL, ssize_t, (v))
170 #define CA_VSTREAM_CTL_SWAP_FD(v) VSTREAM_CTL_SWAP_FD, CHECK_PTR(VSTREAM_CTL, VSTREAM, (v))
171 #define CA_VSTREAM_CTL_START_DEADLINE VSTREAM_CTL_START_DEADLINE
172 #define CA_VSTREAM_CTL_STOP_DEADLINE VSTREAM_CTL_STOP_DEADLINE
173 
174 CHECK_VAL_HELPER_DCL(VSTREAM_CTL, ssize_t);
175 CHECK_VAL_HELPER_DCL(VSTREAM_CTL, int);
177 CHECK_VAL_HELPER_DCL(VSTREAM_CTL, VSTREAM_RW_FN);
178 CHECK_PTR_HELPER_DCL(VSTREAM_CTL, void);
179 CHECK_PTR_HELPER_DCL(VSTREAM_CTL, VSTREAM);
180 CHECK_CPTR_HELPER_DCL(VSTREAM_CTL, char);
181 
182 extern VSTREAM *PRINTFLIKE(1, 2) vstream_printf(const char *,...);
183 extern VSTREAM *PRINTFLIKE(2, 3) vstream_fprintf(VSTREAM *, const char *,...);
184 
185 extern VSTREAM *vstream_popen(int,...);
186 extern int vstream_pclose(VSTREAM *);
187 
188 #define vstream_ispipe(vp) ((vp)->pid != 0)
189 
190 /* Legacy API: type-unchecked arguments, internal use. */
191 #define VSTREAM_POPEN_END 0 /* terminator */
192 #define VSTREAM_POPEN_COMMAND 1 /* command is string */
193 #define VSTREAM_POPEN_ARGV 2 /* command is array */
194 #define VSTREAM_POPEN_UID 3 /* privileges */
195 #define VSTREAM_POPEN_GID 4 /* privileges */
196 #define VSTREAM_POPEN_ENV 5 /* extra environment */
197 #define VSTREAM_POPEN_SHELL 6 /* alternative shell */
198 #define VSTREAM_POPEN_WAITPID_FN 7 /* child catcher, waitpid() compat. */
199 #define VSTREAM_POPEN_EXPORT 8 /* exportable environment */
200 
201 /* Safer API: type-checked arguments, external use. */
202 #define CA_VSTREAM_POPEN_END VSTREAM_POPEN_END
203 #define CA_VSTREAM_POPEN_COMMAND(v) VSTREAM_POPEN_COMMAND, CHECK_CPTR(VSTREAM_PPN, char, (v))
204 #define CA_VSTREAM_POPEN_ARGV(v) VSTREAM_POPEN_ARGV, CHECK_PPTR(VSTREAM_PPN, char, (v))
205 #define CA_VSTREAM_POPEN_UID(v) VSTREAM_POPEN_UID, CHECK_VAL(VSTREAM_PPN, uid_t, (v))
206 #define CA_VSTREAM_POPEN_GID(v) VSTREAM_POPEN_GID, CHECK_VAL(VSTREAM_PPN, gid_t, (v))
207 #define CA_VSTREAM_POPEN_ENV(v) VSTREAM_POPEN_ENV, CHECK_PPTR(VSTREAM_PPN, char, (v))
208 #define CA_VSTREAM_POPEN_SHELL(v) VSTREAM_POPEN_SHELL, CHECK_CPTR(VSTREAM_PPN, char, (v))
209 #define CA_VSTREAM_POPEN_WAITPID_FN(v) VSTREAM_POPEN_WAITPID_FN, CHECK_VAL(VSTREAM_PPN, VSTREAM_WAITPID_FN, (v))
210 #define CA_VSTREAM_POPEN_EXPORT(v) VSTREAM_POPEN_EXPORT, CHECK_PPTR(VSTREAM_PPN, char, (v))
211 
212 CHECK_VAL_HELPER_DCL(VSTREAM_PPN, uid_t);
213 CHECK_VAL_HELPER_DCL(VSTREAM_PPN, gid_t);
215 CHECK_PPTR_HELPER_DCL(VSTREAM_PPN, char);
216 CHECK_CPTR_HELPER_DCL(VSTREAM_PPN, char);
217 
218 extern VSTREAM *vstream_vprintf(const char *, va_list);
219 extern VSTREAM *vstream_vfprintf(VSTREAM *, const char *, va_list);
220 
221 extern ssize_t vstream_peek(VSTREAM *);
222 extern ssize_t vstream_bufstat(VSTREAM *, int);
223 
224 #define VSTREAM_BST_FLAG_IN (1<<0)
225 #define VSTREAM_BST_FLAG_OUT (1<<1)
226 #define VSTREAM_BST_FLAG_PEND (1<<2)
227 
228 #define VSTREAM_BST_MASK_DIR (VSTREAM_BST_FLAG_IN | VSTREAM_BST_FLAG_OUT)
229 #define VSTREAM_BST_IN_PEND (VSTREAM_BST_FLAG_IN | VSTREAM_BST_FLAG_PEND)
230 #define VSTREAM_BST_OUT_PEND (VSTREAM_BST_FLAG_OUT | VSTREAM_BST_FLAG_PEND)
231 
232 #define vstream_peek(vp) vstream_bufstat((vp), VSTREAM_BST_IN_PEND)
233 
234 extern const char *vstream_peek_data(VSTREAM *);
235 
236  /*
237  * Exception handling. We use pointer to jmp_buf to avoid a lot of unused
238  * baggage for streams that don't need this functionality.
239  *
240  * XXX sigsetjmp()/siglongjmp() save and restore the signal mask which can
241  * avoid surprises in code that manipulates signals, but unfortunately some
242  * systems have bugs in their implementation.
243  */
244 #ifdef NO_SIGSETJMP
245 #define vstream_setjmp(stream) setjmp((stream)->jbuf[0])
246 #define vstream_longjmp(stream, val) longjmp((stream)->jbuf[0], (val))
247 #else
248 #define vstream_setjmp(stream) sigsetjmp((stream)->jbuf[0], 1)
249 #define vstream_longjmp(stream, val) siglongjmp((stream)->jbuf[0], (val))
250 #endif
251 
252  /*
253  * Tweaks and workarounds.
254  */
255 extern int vstream_tweak_sock(VSTREAM *);
256 extern int vstream_tweak_tcp(VSTREAM *);
257 
258 #define vstream_flags(stream) ((const int) (stream)->buf.flags)
259 
260 /* LICENSE
261 /* .ad
262 /* .fi
263 /* The Secure Mailer license must be distributed with this software.
264 /* AUTHOR(S)
265 /* Wietse Venema
266 /* IBM T.J. Watson Research
267 /* P.O. Box 704
268 /* Yorktown Heights, NY 10598, USA
269 /*
270 /* Wietse Venema
271 /* Google, Inc.
272 /* 111 8th Avenue
273 /* New York, NY 10011, USA
274 /*--*/
275 
276 #endif
struct timeval time_limit
Definition: vstream.h:61
VSTREAM_JMP_BUF * jbuf
Definition: vstream.h:59
CHECK_PPTR_HELPER_DCL(VSTREAM_PPN, char)
VSTREAM_RW_FN read_fn
Definition: vstream.h:46
int fd
Definition: vstream.h:45
VBUF write_buf
Definition: vstream.h:55
char * path
Definition: vstream.h:51
VSTREAM vstream_fstd[]
Definition: vstream.c:496
VSTREAM * PRINTFLIKE(1, 2) vstream_printf(const char *
int timeout
Definition: vstream.h:58
int vstream_fputs(const char *, VSTREAM *)
Definition: vstream.c:1360
VBUF read_buf
Definition: vstream.h:54
pid_t pid
Definition: vstream.h:56
VSTREAM_RW_FN write_fn
Definition: vstream.h:47
int vstream_pclose(VSTREAM *)
const char * vstream_peek_data(VSTREAM *)
Definition: vstream.c:1593
VSTREAM * vstream_fprintf(VSTREAM *stream, const char *fmt,...)
Definition: vstream.c:1348
int read_fd
Definition: vstream.h:52
void * context
Definition: vstream.h:49
#define WARN_UNUSED_RESULT
Definition: sys_defs.h:1662
VSTREAM * vstream_vprintf(const char *, va_list)
Definition: vstream.c:1521
VSTREAM * vstream_printf(const char *fmt,...)
Definition: vstream.c:1335
ssize_t req_bufsize
Definition: vstream.h:48
Definition: vbuf.h:37
int vstream_fpurge(VSTREAM *, int)
Definition: vstream.c:1041
int vstream_fflush(VSTREAM *)
Definition: vstream.c:1257
ssize_t(* VSTREAM_RW_FN)(int, void *, size_t, int, void *)
Definition: vstream.h:34
VSTREAM * vstream_vfprintf(VSTREAM *, const char *, va_list)
Definition: vstream.c:1531
VBUF buf
Definition: vstream.h:44
off_t offset
Definition: vstream.h:50
CHECK_VAL_HELPER_DCL(VSTREAM_CTL, ssize_t)
int vstream_fclose(VSTREAM *)
Definition: vstream.c:1268
VSTREAM * vstream_fopen(const char *, int, mode_t)
Definition: vstream.c:1241
VSTREAM * vstream_fdopen(int, int)
Definition: vstream.c:1204
#define vstream_peek(vp)
Definition: vstream.h:232
ssize_t vstream_bufstat(VSTREAM *, int)
Definition: vstream.c:1539
int vstream_tweak_tcp(VSTREAM *)
Definition: vstream_tweak.c:86
struct VSTREAM VSTREAM
int int
Definition: smtpd_proxy.h:21
int vstream_tweak_sock(VSTREAM *)
Definition: vstream_tweak.c:60
VSTREAM_WAITPID_FN waitpid_fn
Definition: vstream.h:57
struct timeval iotime
Definition: vstream.h:60
off_t WARN_UNUSED_RESULT vstream_fseek(VSTREAM *, off_t, int)
Definition: vstream.c:1093
pid_t(* VSTREAM_WAITPID_FN)(pid_t, WAIT_STATUS_T *, int)
Definition: vstream.h:35
VSTREAM VSTREAM const char VSTREAM * vstream_popen(int,...)
void vstream_control(VSTREAM *, int,...)
Definition: vstream.c:1372
int write_fd
Definition: vstream.h:53
#define VSTREAM_JMP_BUF
Definition: vstream.h:40
off_t vstream_ftell(VSTREAM *)
Definition: vstream.c:1157
int WAIT_STATUS_T
Definition: sys_defs.h:1436
int vstream_fdclose(VSTREAM *)
Definition: vstream.c:1309
CHECK_CPTR_HELPER_DCL(VSTREAM_CTL, char)
CHECK_PTR_HELPER_DCL(VSTREAM_CTL, void)