xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/vstream.h (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
1 /*	$NetBSD: vstream.h,v 1.1.1.2 2011/03/02 19:32:46 tron Exp $	*/
2 
3 #ifndef _VSTREAM_H_INCLUDED_
4 #define _VSTREAM_H_INCLUDED_
5 
6 /*++
7 /* NAME
8 /*	vstream 3h
9 /* SUMMARY
10 /*	simple buffered I/O package
11 /* SYNOPSIS
12 /*	#include <vstream.h>
13 /* DESCRIPTION
14 /* .nf
15 
16  /*
17   * System library.
18   */
19 #include <sys/time.h>
20 #include <time.h>
21 #include <fcntl.h>
22 #include <stdarg.h>
23 #include <setjmp.h>
24 #include <unistd.h>
25 
26  /*
27   * Utility library.
28   */
29 #include <vbuf.h>
30 
31  /*
32   * Simple buffered stream. The members of this structure are not part of the
33   * official interface and can change without prior notice.
34   */
35 typedef ssize_t (*VSTREAM_FN) (int, void *, size_t, int, void *);
36 typedef int (*VSTREAM_WAITPID_FN) (pid_t, WAIT_STATUS_T *, int);
37 
38 #ifdef NO_SIGSETJMP
39 #define VSTREAM_JMP_BUF	jmp_buf
40 #else
41 #define VSTREAM_JMP_BUF	sigjmp_buf
42 #endif
43 
44 typedef struct VSTREAM {
45     VBUF    buf;			/* generic intelligent buffer */
46     int     fd;				/* file handle, no 256 limit */
47     VSTREAM_FN read_fn;			/* buffer fill action */
48     VSTREAM_FN write_fn;		/* buffer fill action */
49     ssize_t req_bufsize;		/* requested read/write buffer size */
50     void   *context;			/* application context */
51     off_t   offset;			/* cached seek info */
52     char   *path;			/* give it at least try */
53     int     read_fd;			/* read channel (double-buffered) */
54     int     write_fd;			/* write channel (double-buffered) */
55     VBUF    read_buf;			/* read buffer (double-buffered) */
56     VBUF    write_buf;			/* write buffer (double-buffered) */
57     pid_t   pid;			/* vstream_popen/close() */
58     VSTREAM_WAITPID_FN waitpid_fn;	/* vstream_popen/close() */
59     int     timeout;			/* read/write timout */
60     VSTREAM_JMP_BUF *jbuf;		/* exception handling */
61     struct timeval iotime;		/* time of last fill/flush */
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_ERR	VBUF_FLAG_ERR	/* some I/O error */
71 #define VSTREAM_FLAG_EOF	VBUF_FLAG_EOF	/* end of file */
72 #define VSTREAM_FLAG_TIMEOUT	VBUF_FLAG_TIMEOUT	/* timeout error */
73 #define VSTREAM_FLAG_FIXED	VBUF_FLAG_FIXED	/* fixed-size buffer */
74 #define VSTREAM_FLAG_BAD	VBUF_FLAG_BAD
75 
76 #define VSTREAM_FLAG_READ	(1<<8)	/* read buffer */
77 #define VSTREAM_FLAG_WRITE	(1<<9)	/* write buffer */
78 #define VSTREAM_FLAG_SEEK	(1<<10)	/* seek info valid */
79 #define VSTREAM_FLAG_NSEEK	(1<<11)	/* can't seek this file */
80 #define VSTREAM_FLAG_DOUBLE	(1<<12)	/* double buffer */
81 
82 #define VSTREAM_PURGE_READ	(1<<0)	/* flush unread data */
83 #define VSTREAM_PURGE_WRITE	(1<<1)	/* flush unwritten data */
84 #define VSTREAM_PURGE_BOTH	(VSTREAM_PURGE_READ|VSTREAM_PURGE_WRITE)
85 
86 #define VSTREAM_BUFSIZE		4096
87 
88 extern VSTREAM *vstream_fopen(const char *, int, mode_t);
89 extern int vstream_fclose(VSTREAM *);
90 extern off_t vstream_fseek(VSTREAM *, off_t, int);
91 extern off_t vstream_ftell(VSTREAM *);
92 extern int vstream_fpurge(VSTREAM *, int);
93 extern int vstream_fflush(VSTREAM *);
94 extern int vstream_fputs(const char *, VSTREAM *);
95 extern VSTREAM *vstream_fdopen(int, int);
96 extern int vstream_fdclose(VSTREAM *);
97 
98 #define vstream_fread(v, b, n)	vbuf_read(&(v)->buf, (b), (n))
99 #define vstream_fwrite(v, b, n)	vbuf_write(&(v)->buf, (b), (n))
100 
101 #define VSTREAM_PUTC(ch, vp)	VBUF_PUT(&(vp)->buf, (ch))
102 #define VSTREAM_GETC(vp)	VBUF_GET(&(vp)->buf)
103 #define vstream_ungetc(vp, ch)	vbuf_unget(&(vp)->buf, (ch))
104 #define VSTREAM_EOF		VBUF_EOF
105 
106 #define VSTREAM_PUTCHAR(ch)	VSTREAM_PUTC((ch), VSTREAM_OUT)
107 #define VSTREAM_GETCHAR()	VSTREAM_GETC(VSTREAM_IN)
108 
109 #define vstream_fileno(vp)	((vp)->fd)
110 #define vstream_req_bufsize(vp)	((const ssize_t) ((vp)->req_bufsize))
111 #define vstream_context(vp)	((vp)->context)
112 #define vstream_ferror(vp)	vbuf_error(&(vp)->buf)
113 #define vstream_feof(vp)	vbuf_eof(&(vp)->buf)
114 #define vstream_ftimeout(vp)	vbuf_timeout(&(vp)->buf)
115 #define vstream_clearerr(vp)	vbuf_clearerr(&(vp)->buf)
116 #define VSTREAM_PATH(vp)	((vp)->path ? (const char *) (vp)->path : "unknown_stream")
117 #define vstream_ftime(vp)	((time_t) ((vp)->iotime.tv_sec))
118 #define vstream_ftimeval(vp)	((vp)->iotime)
119 
120 extern void vstream_control(VSTREAM *, int,...);
121 
122 #define VSTREAM_CTL_END		0
123 #define VSTREAM_CTL_READ_FN	1
124 #define VSTREAM_CTL_WRITE_FN	2
125 #define VSTREAM_CTL_PATH	3
126 #define VSTREAM_CTL_DOUBLE	4
127 #define VSTREAM_CTL_READ_FD	5
128 #define VSTREAM_CTL_WRITE_FD	6
129 #define VSTREAM_CTL_WAITPID_FN	7
130 #define VSTREAM_CTL_TIMEOUT	8
131 #define VSTREAM_CTL_EXCEPT	9
132 #define VSTREAM_CTL_CONTEXT	10
133 #ifdef F_DUPFD
134 #define VSTREAM_CTL_DUPFD	11
135 #endif
136 #define VSTREAM_CTL_BUFSIZE	12
137 #define VSTREAM_CTL_SWAP_FD	13
138 
139 extern VSTREAM *PRINTFLIKE(1, 2) vstream_printf(const char *,...);
140 extern VSTREAM *PRINTFLIKE(2, 3) vstream_fprintf(VSTREAM *, const char *,...);
141 
142 extern VSTREAM *vstream_popen(int,...);
143 extern int vstream_pclose(VSTREAM *);
144 
145 #define vstream_ispipe(vp)	((vp)->pid != 0)
146 
147 #define VSTREAM_POPEN_END	0	/* terminator */
148 #define VSTREAM_POPEN_COMMAND	1	/* command is string */
149 #define VSTREAM_POPEN_ARGV	2	/* command is array */
150 #define VSTREAM_POPEN_UID	3	/* privileges */
151 #define VSTREAM_POPEN_GID	4	/* privileges */
152 #define VSTREAM_POPEN_ENV	5	/* extra environment */
153 #define VSTREAM_POPEN_SHELL	6	/* alternative shell */
154 #define VSTREAM_POPEN_WAITPID_FN 7	/* child catcher, waitpid() compat. */
155 #define VSTREAM_POPEN_EXPORT	8	/* exportable environment */
156 
157 extern VSTREAM *vstream_vfprintf(VSTREAM *, const char *, va_list);
158 
159 extern ssize_t vstream_peek(VSTREAM *);
160 extern ssize_t vstream_bufstat(VSTREAM *, int);
161 
162 #define VSTREAM_BST_FLAG_IN		(1<<0)
163 #define VSTREAM_BST_FLAG_OUT		(1<<1)
164 #define VSTREAM_BST_FLAG_PEND		(1<<2)
165 
166 #define VSTREAM_BST_MASK_DIR	(VSTREAM_BST_FLAG_IN | VSTREAM_BST_FLAG_OUT)
167 #define VSTREAM_BST_IN_PEND	(VSTREAM_BST_FLAG_IN | VSTREAM_BST_FLAG_PEND)
168 #define VSTREAM_BST_OUT_PEND	(VSTREAM_BST_FLAG_OUT | VSTREAM_BST_FLAG_PEND)
169 
170 #define vstream_peek(vp) vstream_bufstat((vp), VSTREAM_BST_IN_PEND)
171 
172  /*
173   * Exception handling. We use pointer to jmp_buf to avoid a lot of unused
174   * baggage for streams that don't need this functionality.
175   *
176   * XXX sigsetjmp()/siglongjmp() save and restore the signal mask which can
177   * avoid surprises in code that manipulates signals, but unfortunately some
178   * systems have bugs in their implementation.
179   */
180 #ifdef NO_SIGSETJMP
181 #define vstream_setjmp(stream)		setjmp((stream)->jbuf[0])
182 #define vstream_longjmp(stream, val)	longjmp((stream)->jbuf[0], (val))
183 #else
184 #define vstream_setjmp(stream)		sigsetjmp((stream)->jbuf[0], 1)
185 #define vstream_longjmp(stream, val)	siglongjmp((stream)->jbuf[0], (val))
186 #endif
187 
188  /*
189   * Tweaks and workarounds.
190   */
191 extern int vstream_tweak_sock(VSTREAM *);
192 extern int vstream_tweak_tcp(VSTREAM *);
193 
194 /* LICENSE
195 /* .ad
196 /* .fi
197 /*	The Secure Mailer license must be distributed with this software.
198 /* AUTHOR(S)
199 /*	Wietse Venema
200 /*	IBM T.J. Watson Research
201 /*	P.O. Box 704
202 /*	Yorktown Heights, NY 10598, USA
203 /*--*/
204 
205 #endif
206