2 * Copyright (c) 2000-2002, 2004 Sendmail, Inc. and its suppliers.
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
10 * By using this file, you agree to the terms and conditions set
11 * forth in the LICENSE file which can be found at the top level of
12 * the sendmail distribution.
14 * $Id: io.h,v 1.24 2004/03/03 19:14:49 ca Exp $
17 #pragma ident "%Z%%M% %I% %E% SMI"
20 * @(#)stdio.h 5.17 (Berkeley) 6/3/91
28 #include <sm/varargs.h>
30 /* mode for sm io (exposed) */
31 #define SM_IO_RDWR 1 /* read-write */
32 #define SM_IO_RDONLY 2 /* read-only */
33 #define SM_IO_WRONLY 3 /* write-only */
34 #define SM_IO_APPEND 4 /* write-only from eof */
35 #define SM_IO_APPENDRW 5 /* read-write from eof */
36 #define SM_IO_RDWRTR 6 /* read-write with truncation indicated */
38 # define SM_IO_BINARY 0x0 /* binary mode: not used in Unix */
39 #define SM_IS_BINARY(mode) (((mode) & SM_IO_BINARY) != 0)
40 #define SM_IO_MODE(mode) ((mode) & 0x0f)
42 #define SM_IO_RDWR_B (SM_IO_RDWR|SM_IO_BINARY)
43 #define SM_IO_RDONLY_B (SM_IO_RDONLY|SM_IO_BINARY)
44 #define SM_IO_WRONLY_B (SM_IO_WRONLY|SM_IO_BINARY)
45 #define SM_IO_APPEND_B (SM_IO_APPEND|SM_IO_BINARY)
46 #define SM_IO_APPENDRW_B (SM_IO_APPENDRW|SM_IO_BINARY)
47 #define SM_IO_RDWRTR_B (SM_IO_RDWRTR|SM_IO_BINARY)
49 /* for sm_io_fseek, et al api's (exposed) */
50 #define SM_IO_SEEK_SET 0
51 #define SM_IO_SEEK_CUR 1
52 #define SM_IO_SEEK_END 2
54 /* flags for info what's with different types (exposed) */
55 #define SM_IO_WHAT_MODE 1
56 #define SM_IO_WHAT_VECTORS 2
57 #define SM_IO_WHAT_FD 3
58 #define SM_IO_WHAT_TYPE 4
59 #define SM_IO_WHAT_ISTYPE 5
60 #define SM_IO_IS_READABLE 6
61 #define SM_IO_WHAT_TIMEOUT 7
62 #define SM_IO_WHAT_SIZE 8
64 /* info flags (exposed) */
65 #define SM_IO_FTYPE_CREATE 1
66 #define SM_IO_FTYPE_MODIFY 2
67 #define SM_IO_FTYPE_DELETE 3
69 #define SM_IO_SL_PRIO 1
71 #define SM_IO_OPEN_MAX 20
73 /* for internal buffers */
76 unsigned char *smb_base
;
81 ** sm I/O state variables (internal only).
83 ** The following always hold:
85 ** if (flags&(SMLBF|SMWR)) == (SMLBF|SMWR),
86 ** lbfsize is -bf.size, else lbfsize is 0
87 ** if flags&SMRD, w is 0
88 ** if flags&SMWR, r is 0
90 ** This ensures that the getc and putc macros (or inline functions) never
91 ** try to write or read from a file that is in `read' or `write' mode.
92 ** (Moreover, they can, and do, automatically switch from read mode to
93 ** write mode, and back, on "r+" and "w+" files.)
95 ** lbfsize is used only to make the inline line-buffered output stream
96 ** code as compact as possible.
98 ** ub, up, and ur are used when ungetc() pushes back more characters
99 ** than fit in the current bf, or when ungetc() pushes back a character
100 ** that does not match the previous one in bf. When this happens,
101 ** ub.base becomes non-nil (i.e., a stream has ungetc() data iff
102 ** ub.base!=NULL) and up and ur save the current values of p and r.
105 typedef struct sm_file SM_FILE_T
;
109 const char *sm_magic
; /* This SM_FILE_T is free when NULL */
110 unsigned char *f_p
; /* current position in (some) buffer */
111 int f_r
; /* read space left for getc() */
112 int f_w
; /* write space left for putc() */
113 long f_flags
; /* flags, below */
114 short f_file
; /* fileno, if Unix fd, else -1 */
115 struct smbuf f_bf
; /* the buffer (>= 1 byte, if !NULL) */
116 int f_lbfsize
; /* 0 or -bf.size, for inline putc */
118 /* These can be used for any purpose by a file type implementation: */
123 int (*f_close
) __P((SM_FILE_T
*));
124 ssize_t (*f_read
) __P((SM_FILE_T
*, char *, size_t));
125 off_t (*f_seek
) __P((SM_FILE_T
*, off_t
, int));
126 ssize_t (*f_write
) __P((SM_FILE_T
*, const char *, size_t));
127 int (*f_open
) __P((SM_FILE_T
*, const void *, int,
129 int (*f_setinfo
) __P((SM_FILE_T
*, int , void *));
130 int (*f_getinfo
) __P((SM_FILE_T
*, int , void *));
132 int f_timeoutstate
; /* either blocking or non-blocking */
133 char *f_type
; /* for by-type lookups */
134 struct sm_file
*f_flushfp
; /* flush this before reading parent */
135 struct sm_file
*f_modefp
; /* sync mode with this fp */
137 /* separate buffer for long sequences of ungetc() */
138 struct smbuf f_ub
; /* ungetc buffer */
139 unsigned char *f_up
; /* saved f_p when f_p is doing ungetc */
140 int f_ur
; /* saved f_r when f_r is counting ungetc */
142 /* tricks to meet minimum requirements even when malloc() fails */
143 unsigned char f_ubuf
[3]; /* guarantee an ungetc() buffer */
144 unsigned char f_nbuf
[1]; /* guarantee a getc() buffer */
146 /* Unix stdio files get aligned to block boundaries on fseek() */
147 int f_blksize
; /* stat.st_blksize (may be != bf.size) */
148 off_t f_lseekoff
; /* current lseek offset */
149 int f_dup_cnt
; /* count file dup'd */
153 extern SM_FILE_T SmIoF
[];
154 extern const char SmFileMagic
[];
155 extern SM_FILE_T SmFtStdio_def
;
156 extern SM_FILE_T SmFtStdiofd_def
;
157 extern SM_FILE_T SmFtString_def
;
158 extern SM_FILE_T SmFtSyslog_def
;
159 extern SM_FILE_T SmFtRealStdio_def
;
161 #define SMIOIN_FILENO 0
162 #define SMIOOUT_FILENO 1
163 #define SMIOERR_FILENO 2
164 #define SMIOSTDIN_FILENO 3
165 #define SMIOSTDOUT_FILENO 4
166 #define SMIOSTDERR_FILENO 5
168 /* Common predefined and already (usually) open files (exposed) */
169 #define smioin (&SmIoF[SMIOIN_FILENO])
170 #define smioout (&SmIoF[SMIOOUT_FILENO])
171 #define smioerr (&SmIoF[SMIOERR_FILENO])
172 #define smiostdin (&SmIoF[SMIOSTDIN_FILENO])
173 #define smiostdout (&SmIoF[SMIOSTDOUT_FILENO])
174 #define smiostderr (&SmIoF[SMIOSTDERR_FILENO])
176 #define SmFtStdio (&SmFtStdio_def)
177 #define SmFtStdiofd (&SmFtStdiofd_def)
178 #define SmFtString (&SmFtString_def)
179 #define SmFtSyslog (&SmFtSyslog_def)
180 #define SmFtRealStdio (&SmFtRealStdio_def)
183 # define SM_IO_SET_TYPE(f, name, open, close, read, write, seek, get, set, timeout) \
184 (f) = {SmFileMagic, (unsigned char *) 0, 0, 0, 0L, -1, {0}, 0, (void *) 0,\
185 0, (close), (read), (seek), (write), (open), (set), (get), (timeout),\
187 # define SM_IO_INIT_TYPE(f, name, open, close, read, write, seek, get, set, timeout)
190 # define SM_IO_SET_TYPE(f, name, open, close, read, write, seek, get, set, timeout) (f)
191 # define SM_IO_INIT_TYPE(f, name, open, close, read, write, seek, get, set, timeout) \
192 (f).sm_magic = SmFileMagic; \
193 (f).f_p = (unsigned char *) 0; \
198 (f).f_bf.smb_base = (unsigned char *) 0; \
199 (f).f_bf.smb_size = 0; \
201 (f).f_cookie = (void *) 0; \
203 (f).f_close = (close); \
204 (f).f_read = (read); \
205 (f).f_seek = (seek); \
206 (f).f_write = (write); \
207 (f).f_open = (open); \
208 (f).f_setinfo = (set); \
209 (f).f_getinfo = (get); \
210 (f).f_timeout = (timeout); \
211 (f).f_timeoutstate = 0; \
214 #endif /* __STDC__ */
219 #define SMFBF 0x000001 /* XXXX fully buffered */
220 #define SMLBF 0x000002 /* line buffered */
221 #define SMNBF 0x000004 /* unbuffered */
222 #define SMNOW 0x000008 /* Flush each write; take read now */
223 #define SMRD 0x000010 /* OK to read */
224 #define SMWR 0x000020 /* OK to write */
225 /* RD and WR are never simultaneously asserted */
226 #define SMRW 0x000040 /* open for reading & writing */
227 #define SMFEOF 0x000080 /* found EOF */
228 #define SMERR 0x000100 /* found error */
229 #define SMMBF 0x000200 /* buf is from malloc */
230 #define SMAPP 0x000400 /* fdopen()ed in append mode */
231 #define SMSTR 0x000800 /* this is an snprintf string */
232 #define SMOPT 0x001000 /* do fseek() optimisation */
233 #define SMNPT 0x002000 /* do not do fseek() optimisation */
234 #define SMOFF 0x004000 /* set iff offset is in fact correct */
235 #define SMALC 0x010000 /* allocate string space dynamically */
237 #define SMMODEMASK 0x0070 /* read/write mode */
239 /* defines for timeout constants */
240 #define SM_TIME_IMMEDIATE (0)
241 #define SM_TIME_FOREVER (-1)
242 #define SM_TIME_DEFAULT (-2)
244 /* timeout state for blocking */
245 #define SM_TIME_BLOCK (0) /* XXX just bool? */
246 #define SM_TIME_NONBLOCK (1)
248 /* Exposed buffering type flags */
249 #define SM_IO_FBF 0 /* setvbuf should set fully buffered */
250 #define SM_IO_LBF 1 /* setvbuf should set line buffered */
251 #define SM_IO_NBF 2 /* setvbuf should set unbuffered */
253 /* setvbuf buffered, but through at lower file type layers */
257 ** size of buffer used by setbuf.
258 ** If underlying filesystem blocksize is discoverable that is used instead
261 #define SM_IO_BUFSIZ 4096
263 #define SM_IO_EOF (-1)
265 /* Functions defined in ANSI C standard. */
267 SM_FILE_T
*sm_io_autoflush
__P((SM_FILE_T
*, SM_FILE_T
*));
268 void sm_io_automode
__P((SM_FILE_T
*, SM_FILE_T
*));
269 void sm_io_clearerr
__P((SM_FILE_T
*));
270 int sm_io_close
__P((SM_FILE_T
*, int SM_NONVOLATILE
));
271 SM_FILE_T
*sm_io_dup
__P((SM_FILE_T
*));
272 int sm_io_eof
__P((SM_FILE_T
*));
273 int sm_io_error
__P((SM_FILE_T
*));
274 char *sm_io_fgets
__P((SM_FILE_T
*, int, char *, int));
275 int sm_io_flush
__P((SM_FILE_T
*, int SM_NONVOLATILE
));
278 sm_io_fprintf
__P((SM_FILE_T
*, int, const char *, ...));
280 int sm_io_fputs
__P((SM_FILE_T
*, int, const char *));
283 sm_io_fscanf
__P((SM_FILE_T
*, int, const char *, ...));
285 int sm_io_getc
__P((SM_FILE_T
*, int));
286 int sm_io_getinfo
__P((SM_FILE_T
*, int, void *));
287 SM_FILE_T
*sm_io_open
__P((const SM_FILE_T
*, int SM_NONVOLATILE
, const void *,
289 int sm_io_purge
__P((SM_FILE_T
*));
290 int sm_io_putc
__P((SM_FILE_T
*, int, int));
291 size_t sm_io_read
__P((SM_FILE_T
*, int, void *, size_t));
292 SM_FILE_T
*sm_io_reopen
__P((const SM_FILE_T
*, int SM_NONVOLATILE
,
293 const void *, int, const void *, SM_FILE_T
*));
294 void sm_io_rewind
__P((SM_FILE_T
*, int));
295 int sm_io_seek
__P((SM_FILE_T
*, int SM_NONVOLATILE
, long SM_NONVOLATILE
,
296 int SM_NONVOLATILE
));
297 int sm_io_setinfo
__P((SM_FILE_T
*, int, void *));
298 int sm_io_setvbuf
__P((SM_FILE_T
*, int, char *, int, size_t));
301 sm_io_sscanf
__P((const char *, char const *, ...));
303 long sm_io_tell
__P((SM_FILE_T
*, int SM_NONVOLATILE
));
304 int sm_io_ungetc
__P((SM_FILE_T
*, int, int));
305 int sm_io_vfprintf
__P((SM_FILE_T
*, int, const char *, va_list));
306 size_t sm_io_write
__P((SM_FILE_T
*, int, const void *, size_t));
308 void sm_strio_init
__P((SM_FILE_T
*, char *, size_t));
317 sm_io_stdioopen
__P((
341 ** Functions internal to the implementation.
345 int sm_rget
__P((SM_FILE_T
*, int));
346 int sm_vfscanf
__P((SM_FILE_T
*, int SM_NONVOLATILE
, const char *,
347 va_list SM_NONVOLATILE
));
348 int sm_wbuf
__P((SM_FILE_T
*, int, int));
352 ** The macros are here so that we can
353 ** define function versions in the library.
356 #define sm_getc(f, t) \
362 ** This has been tuned to generate reasonable code on the vax using pcc.
363 ** (It also generates reasonable x86 code using gcc.)
366 #define sm_putc(f, t, c) \
368 (f)->f_w >= (f)->f_lbfsize ? \
369 (*(f)->f_p = (c)), *(f)->f_p != '\n' ? \
371 sm_wbuf(f, t, '\n') : \
372 sm_wbuf(f, t, (int)(c)) : \
373 (*(f)->f_p = (c), (int)*(f)->f_p++))
375 #define sm_eof(p) (((p)->f_flags & SMFEOF) != 0)
376 #define sm_error(p) (((p)->f_flags & SMERR) != 0)
377 #define sm_clearerr(p) ((void)((p)->f_flags &= ~(SMERR|SMFEOF)))
379 #define sm_io_eof(p) sm_eof(p)
380 #define sm_io_error(p) sm_error(p)
382 #define sm_io_clearerr(p) sm_clearerr(p)
385 # ifndef _POSIX_SOURCE
386 # define sm_io_getc(fp, t) sm_getc(fp, t)
387 # define sm_io_putc(fp, t, x) sm_putc(fp, t, x)
388 # endif /* _POSIX_SOURCE */