Deleted Added
full compact
io.h (90792) io.h (94334)
1/*
1/*
2 * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
2 * Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
4 * Copyright (c) 1990
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Chris Torek.
9 *
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.
13 *
3 * All rights reserved.
4 * Copyright (c) 1990
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Chris Torek.
9 *
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.
13 *
14 * $Id: io.h,v 1.19 2001/07/10 21:56:46 gshapiro Exp $
14 * $Id: io.h,v 1.23 2002/02/23 19:32:17 gshapiro Exp $
15 */
16
17/*-
18 * @(#)stdio.h 5.17 (Berkeley) 6/3/91
19 */
20
21#ifndef SM_IO_H
22#define SM_IO_H
23
24#include <stdio.h>
25#include <sm/gen.h>
26#include <sm/varargs.h>
27
28/* mode for sm io (exposed) */
29#define SM_IO_RDWR 1 /* read-write */
30#define SM_IO_RDONLY 2 /* read-only */
31#define SM_IO_WRONLY 3 /* write-only */
32#define SM_IO_APPEND 4 /* write-only from eof */
33#define SM_IO_APPENDRW 5 /* read-write from eof */
34#define SM_IO_RDWRTR 6 /* read-write with truncation indicated */
35
36/* for sm_io_fseek, et al api's (exposed) */
37#define SM_IO_SEEK_SET 0
38#define SM_IO_SEEK_CUR 1
39#define SM_IO_SEEK_END 2
40
41/* flags for info what's with different types (exposed) */
42#define SM_IO_WHAT_MODE 1
43#define SM_IO_WHAT_VECTORS 2
44#define SM_IO_WHAT_FD 3
45#define SM_IO_WHAT_TYPE 4
46#define SM_IO_WHAT_ISTYPE 5
47#define SM_IO_IS_READABLE 6
48#define SM_IO_WHAT_TIMEOUT 7
15 */
16
17/*-
18 * @(#)stdio.h 5.17 (Berkeley) 6/3/91
19 */
20
21#ifndef SM_IO_H
22#define SM_IO_H
23
24#include <stdio.h>
25#include <sm/gen.h>
26#include <sm/varargs.h>
27
28/* mode for sm io (exposed) */
29#define SM_IO_RDWR 1 /* read-write */
30#define SM_IO_RDONLY 2 /* read-only */
31#define SM_IO_WRONLY 3 /* write-only */
32#define SM_IO_APPEND 4 /* write-only from eof */
33#define SM_IO_APPENDRW 5 /* read-write from eof */
34#define SM_IO_RDWRTR 6 /* read-write with truncation indicated */
35
36/* for sm_io_fseek, et al api's (exposed) */
37#define SM_IO_SEEK_SET 0
38#define SM_IO_SEEK_CUR 1
39#define SM_IO_SEEK_END 2
40
41/* flags for info what's with different types (exposed) */
42#define SM_IO_WHAT_MODE 1
43#define SM_IO_WHAT_VECTORS 2
44#define SM_IO_WHAT_FD 3
45#define SM_IO_WHAT_TYPE 4
46#define SM_IO_WHAT_ISTYPE 5
47#define SM_IO_IS_READABLE 6
48#define SM_IO_WHAT_TIMEOUT 7
49#define SM_IO_WHAT_SIZE 8
49
50/* info flags (exposed) */
51#define SM_IO_FTYPE_CREATE 1
52#define SM_IO_FTYPE_MODIFY 2
53#define SM_IO_FTYPE_DELETE 3
54
55#define SM_IO_SL_PRIO 1
56
57#define SM_IO_OPEN_MAX 20
58
59/* for internal buffers */
60struct smbuf
61{
62 unsigned char *smb_base;
63 int smb_size;
64};
65
66/*
67** sm I/O state variables (internal only).
68**
69** The following always hold:
70**
71** if (flags&(SMLBF|SMWR)) == (SMLBF|SMWR),
72** lbfsize is -bf.size, else lbfsize is 0
73** if flags&SMRD, w is 0
74** if flags&SMWR, r is 0
75**
76** This ensures that the getc and putc macros (or inline functions) never
77** try to write or read from a file that is in `read' or `write' mode.
78** (Moreover, they can, and do, automatically switch from read mode to
79** write mode, and back, on "r+" and "w+" files.)
80**
81** lbfsize is used only to make the inline line-buffered output stream
82** code as compact as possible.
83**
84** ub, up, and ur are used when ungetc() pushes back more characters
85** than fit in the current bf, or when ungetc() pushes back a character
86** that does not match the previous one in bf. When this happens,
87** ub.base becomes non-nil (i.e., a stream has ungetc() data iff
88** ub.base!=NULL) and up and ur save the current values of p and r.
89*/
90
91typedef struct sm_file SM_FILE_T;
92
93struct sm_file
94{
95 const char *sm_magic; /* This SM_FILE_T is free when NULL */
96 unsigned char *f_p; /* current position in (some) buffer */
97 int f_r; /* read space left for getc() */
98 int f_w; /* write space left for putc() */
99 long f_flags; /* flags, below */
100 short f_file; /* fileno, if Unix fd, else -1 */
101 struct smbuf f_bf; /* the buffer (>= 1 byte, if !NULL) */
102 int f_lbfsize; /* 0 or -bf.size, for inline putc */
103
104 /* These can be used for any purpose by a file type implementation: */
105 void *f_cookie;
106 int f_ival;
107
108 /* operations */
109 int (*f_close) __P((SM_FILE_T *));
110 ssize_t (*f_read) __P((SM_FILE_T *, char *, size_t));
111 off_t (*f_seek) __P((SM_FILE_T *, off_t, int));
112 ssize_t (*f_write) __P((SM_FILE_T *, const char *, size_t));
113 int (*f_open) __P((SM_FILE_T *, const void *, int,
50
51/* info flags (exposed) */
52#define SM_IO_FTYPE_CREATE 1
53#define SM_IO_FTYPE_MODIFY 2
54#define SM_IO_FTYPE_DELETE 3
55
56#define SM_IO_SL_PRIO 1
57
58#define SM_IO_OPEN_MAX 20
59
60/* for internal buffers */
61struct smbuf
62{
63 unsigned char *smb_base;
64 int smb_size;
65};
66
67/*
68** sm I/O state variables (internal only).
69**
70** The following always hold:
71**
72** if (flags&(SMLBF|SMWR)) == (SMLBF|SMWR),
73** lbfsize is -bf.size, else lbfsize is 0
74** if flags&SMRD, w is 0
75** if flags&SMWR, r is 0
76**
77** This ensures that the getc and putc macros (or inline functions) never
78** try to write or read from a file that is in `read' or `write' mode.
79** (Moreover, they can, and do, automatically switch from read mode to
80** write mode, and back, on "r+" and "w+" files.)
81**
82** lbfsize is used only to make the inline line-buffered output stream
83** code as compact as possible.
84**
85** ub, up, and ur are used when ungetc() pushes back more characters
86** than fit in the current bf, or when ungetc() pushes back a character
87** that does not match the previous one in bf. When this happens,
88** ub.base becomes non-nil (i.e., a stream has ungetc() data iff
89** ub.base!=NULL) and up and ur save the current values of p and r.
90*/
91
92typedef struct sm_file SM_FILE_T;
93
94struct sm_file
95{
96 const char *sm_magic; /* This SM_FILE_T is free when NULL */
97 unsigned char *f_p; /* current position in (some) buffer */
98 int f_r; /* read space left for getc() */
99 int f_w; /* write space left for putc() */
100 long f_flags; /* flags, below */
101 short f_file; /* fileno, if Unix fd, else -1 */
102 struct smbuf f_bf; /* the buffer (>= 1 byte, if !NULL) */
103 int f_lbfsize; /* 0 or -bf.size, for inline putc */
104
105 /* These can be used for any purpose by a file type implementation: */
106 void *f_cookie;
107 int f_ival;
108
109 /* operations */
110 int (*f_close) __P((SM_FILE_T *));
111 ssize_t (*f_read) __P((SM_FILE_T *, char *, size_t));
112 off_t (*f_seek) __P((SM_FILE_T *, off_t, int));
113 ssize_t (*f_write) __P((SM_FILE_T *, const char *, size_t));
114 int (*f_open) __P((SM_FILE_T *, const void *, int,
114 const void *));
115 const void *));
115 int (*f_setinfo) __P((SM_FILE_T *, int , void *));
116 int (*f_getinfo) __P((SM_FILE_T *, int , void *));
117 int f_timeout;
118 int f_timeoutstate; /* either blocking or non-blocking */
119 char *f_type; /* for by-type lookups */
116 int (*f_setinfo) __P((SM_FILE_T *, int , void *));
117 int (*f_getinfo) __P((SM_FILE_T *, int , void *));
118 int f_timeout;
119 int f_timeoutstate; /* either blocking or non-blocking */
120 char *f_type; /* for by-type lookups */
120 void *f_self; /* self for reference */
121 struct sm_file *f_flushfp; /* flush this before reading parent */
122 struct sm_file *f_modefp; /* sync mode with this fp */
123
124 /* separate buffer for long sequences of ungetc() */
125 struct smbuf f_ub; /* ungetc buffer */
126 unsigned char *f_up; /* saved f_p when f_p is doing ungetc */
127 int f_ur; /* saved f_r when f_r is counting ungetc */
128
129 /* tricks to meet minimum requirements even when malloc() fails */
130 unsigned char f_ubuf[3]; /* guarantee an ungetc() buffer */
131 unsigned char f_nbuf[1]; /* guarantee a getc() buffer */
132
121 struct sm_file *f_flushfp; /* flush this before reading parent */
122 struct sm_file *f_modefp; /* sync mode with this fp */
123
124 /* separate buffer for long sequences of ungetc() */
125 struct smbuf f_ub; /* ungetc buffer */
126 unsigned char *f_up; /* saved f_p when f_p is doing ungetc */
127 int f_ur; /* saved f_r when f_r is counting ungetc */
128
129 /* tricks to meet minimum requirements even when malloc() fails */
130 unsigned char f_ubuf[3]; /* guarantee an ungetc() buffer */
131 unsigned char f_nbuf[1]; /* guarantee a getc() buffer */
132
133 /* separate buffer for fgetln() when line crosses buffer boundary */
134 struct smbuf f_lb; /* buffer for fgetln() */
135
136 /* Unix stdio files get aligned to block boundaries on fseek() */
137 int f_blksize; /* stat.st_blksize (may be != bf.size) */
138 off_t f_lseekoff; /* current lseek offset */
139 int f_dup_cnt; /* count file dup'd */
140};
141
142__BEGIN_DECLS
143extern SM_FILE_T SmIoF[];
144extern const char SmFileMagic[];
145extern SM_FILE_T SmFtStdio_def;
146extern SM_FILE_T SmFtStdiofd_def;
147extern SM_FILE_T SmFtString_def;
148extern SM_FILE_T SmFtSyslog_def;
149extern SM_FILE_T SmFtRealStdio_def;
150
151#define SMIOIN_FILENO 0
152#define SMIOOUT_FILENO 1
153#define SMIOERR_FILENO 2
154#define SMIOSTDIN_FILENO 3
155#define SMIOSTDOUT_FILENO 4
156#define SMIOSTDERR_FILENO 5
157
158/* Common predefined and already (usually) open files (exposed) */
159#define smioin (&SmIoF[SMIOIN_FILENO])
160#define smioout (&SmIoF[SMIOOUT_FILENO])
161#define smioerr (&SmIoF[SMIOERR_FILENO])
162#define smiostdin (&SmIoF[SMIOSTDIN_FILENO])
163#define smiostdout (&SmIoF[SMIOSTDOUT_FILENO])
164#define smiostderr (&SmIoF[SMIOSTDERR_FILENO])
165
166#define SmFtStdio (&SmFtStdio_def)
167#define SmFtStdiofd (&SmFtStdiofd_def)
168#define SmFtString (&SmFtString_def)
169#define SmFtSyslog (&SmFtSyslog_def)
170#define SmFtRealStdio (&SmFtRealStdio_def)
171
172#ifdef __STDC__
173# define SM_IO_SET_TYPE(f, name, open, close, read, write, seek, get, set, timeout) \
174 (f) = {SmFileMagic, (unsigned char *) 0, 0, 0, 0L, -1, {0}, 0, (void *) 0,\
175 0, (close), (read), (seek), (write), (open), (set), (get), (timeout),\
176 0, (name)}
177# define SM_IO_INIT_TYPE(f, name, open, close, read, write, seek, get, set, timeout)
178
179#else /* __STDC__ */
180# define SM_IO_SET_TYPE(f, name, open, close, read, write, seek, get, set, timeout) (f)
181# define SM_IO_INIT_TYPE(f, name, open, close, read, write, seek, get, set, timeout) \
182 (f).sm_magic = SmFileMagic; \
183 (f).f_p = (unsigned char *) 0; \
184 (f).f_r = 0; \
185 (f).f_w = 0; \
186 (f).f_flags = 0L; \
187 (f).f_file = 0; \
188 (f).f_bf.smb_base = (unsigned char *) 0; \
189 (f).f_bf.smb_size = 0; \
190 (f).f_lbfsize = 0; \
191 (f).f_cookie = (void *) 0; \
192 (f).f_ival = 0; \
193 (f).f_close = (close); \
194 (f).f_read = (read); \
195 (f).f_seek = (seek); \
196 (f).f_write = (write); \
197 (f).f_open = (open); \
198 (f).f_setinfo = (set); \
199 (f).f_getinfo = (get); \
200 (f).f_timeout = (timeout); \
201 (f).f_timeoutstate = 0; \
202 (f).f_type = (name);
203
204#endif /* __STDC__ */
205
206__END_DECLS
207
208/* Internal flags */
209#define SMFBF 0x000001 /* XXXX fully buffered */
210#define SMLBF 0x000002 /* line buffered */
211#define SMNBF 0x000004 /* unbuffered */
212#define SMNOW 0x000008 /* Flush each write; take read now */
213#define SMRD 0x000010 /* OK to read */
214#define SMWR 0x000020 /* OK to write */
215 /* RD and WR are never simultaneously asserted */
216#define SMRW 0x000040 /* open for reading & writing */
217#define SMFEOF 0x000080 /* found EOF */
218#define SMERR 0x000100 /* found error */
219#define SMMBF 0x000200 /* buf is from malloc */
220#define SMAPP 0x000400 /* fdopen()ed in append mode */
221#define SMSTR 0x000800 /* this is an snprintf string */
222#define SMOPT 0x001000 /* do fseek() optimisation */
223#define SMNPT 0x002000 /* do not do fseek() optimisation */
224#define SMOFF 0x004000 /* set iff offset is in fact correct */
225#define SMALC 0x010000 /* allocate string space dynamically */
226
133 /* Unix stdio files get aligned to block boundaries on fseek() */
134 int f_blksize; /* stat.st_blksize (may be != bf.size) */
135 off_t f_lseekoff; /* current lseek offset */
136 int f_dup_cnt; /* count file dup'd */
137};
138
139__BEGIN_DECLS
140extern SM_FILE_T SmIoF[];
141extern const char SmFileMagic[];
142extern SM_FILE_T SmFtStdio_def;
143extern SM_FILE_T SmFtStdiofd_def;
144extern SM_FILE_T SmFtString_def;
145extern SM_FILE_T SmFtSyslog_def;
146extern SM_FILE_T SmFtRealStdio_def;
147
148#define SMIOIN_FILENO 0
149#define SMIOOUT_FILENO 1
150#define SMIOERR_FILENO 2
151#define SMIOSTDIN_FILENO 3
152#define SMIOSTDOUT_FILENO 4
153#define SMIOSTDERR_FILENO 5
154
155/* Common predefined and already (usually) open files (exposed) */
156#define smioin (&SmIoF[SMIOIN_FILENO])
157#define smioout (&SmIoF[SMIOOUT_FILENO])
158#define smioerr (&SmIoF[SMIOERR_FILENO])
159#define smiostdin (&SmIoF[SMIOSTDIN_FILENO])
160#define smiostdout (&SmIoF[SMIOSTDOUT_FILENO])
161#define smiostderr (&SmIoF[SMIOSTDERR_FILENO])
162
163#define SmFtStdio (&SmFtStdio_def)
164#define SmFtStdiofd (&SmFtStdiofd_def)
165#define SmFtString (&SmFtString_def)
166#define SmFtSyslog (&SmFtSyslog_def)
167#define SmFtRealStdio (&SmFtRealStdio_def)
168
169#ifdef __STDC__
170# define SM_IO_SET_TYPE(f, name, open, close, read, write, seek, get, set, timeout) \
171 (f) = {SmFileMagic, (unsigned char *) 0, 0, 0, 0L, -1, {0}, 0, (void *) 0,\
172 0, (close), (read), (seek), (write), (open), (set), (get), (timeout),\
173 0, (name)}
174# define SM_IO_INIT_TYPE(f, name, open, close, read, write, seek, get, set, timeout)
175
176#else /* __STDC__ */
177# define SM_IO_SET_TYPE(f, name, open, close, read, write, seek, get, set, timeout) (f)
178# define SM_IO_INIT_TYPE(f, name, open, close, read, write, seek, get, set, timeout) \
179 (f).sm_magic = SmFileMagic; \
180 (f).f_p = (unsigned char *) 0; \
181 (f).f_r = 0; \
182 (f).f_w = 0; \
183 (f).f_flags = 0L; \
184 (f).f_file = 0; \
185 (f).f_bf.smb_base = (unsigned char *) 0; \
186 (f).f_bf.smb_size = 0; \
187 (f).f_lbfsize = 0; \
188 (f).f_cookie = (void *) 0; \
189 (f).f_ival = 0; \
190 (f).f_close = (close); \
191 (f).f_read = (read); \
192 (f).f_seek = (seek); \
193 (f).f_write = (write); \
194 (f).f_open = (open); \
195 (f).f_setinfo = (set); \
196 (f).f_getinfo = (get); \
197 (f).f_timeout = (timeout); \
198 (f).f_timeoutstate = 0; \
199 (f).f_type = (name);
200
201#endif /* __STDC__ */
202
203__END_DECLS
204
205/* Internal flags */
206#define SMFBF 0x000001 /* XXXX fully buffered */
207#define SMLBF 0x000002 /* line buffered */
208#define SMNBF 0x000004 /* unbuffered */
209#define SMNOW 0x000008 /* Flush each write; take read now */
210#define SMRD 0x000010 /* OK to read */
211#define SMWR 0x000020 /* OK to write */
212 /* RD and WR are never simultaneously asserted */
213#define SMRW 0x000040 /* open for reading & writing */
214#define SMFEOF 0x000080 /* found EOF */
215#define SMERR 0x000100 /* found error */
216#define SMMBF 0x000200 /* buf is from malloc */
217#define SMAPP 0x000400 /* fdopen()ed in append mode */
218#define SMSTR 0x000800 /* this is an snprintf string */
219#define SMOPT 0x001000 /* do fseek() optimisation */
220#define SMNPT 0x002000 /* do not do fseek() optimisation */
221#define SMOFF 0x004000 /* set iff offset is in fact correct */
222#define SMALC 0x010000 /* allocate string space dynamically */
223
227#define SMACCESSMASK 0x0070
228#define SMMODEMASK 0x011C
224#define SMMODEMASK 0x0070 /* read/write mode */
229
230/* defines for timeout constants */
231#define SM_TIME_IMMEDIATE (0)
232#define SM_TIME_FOREVER (-1)
233#define SM_TIME_DEFAULT (-2)
234
235/* timeout state for blocking */
236#define SM_TIME_BLOCK (0) /* XXX just bool? */
237#define SM_TIME_NONBLOCK (1)
238
239/* Exposed buffering type flags */
240#define SM_IO_FBF 0 /* setvbuf should set fully buffered */
241#define SM_IO_LBF 1 /* setvbuf should set line buffered */
242#define SM_IO_NBF 2 /* setvbuf should set unbuffered */
243
244/* setvbuf buffered, but through at lower file type layers */
245#define SM_IO_NOW 3
246
247/*
248** size of buffer used by setbuf.
249** If underlying filesystem blocksize is discoverable that is used instead
250*/
251
252#define SM_IO_BUFSIZ 4096
253
254#define SM_IO_EOF (-1)
255
256/* Functions defined in ANSI C standard. */
257__BEGIN_DECLS
258SM_FILE_T *sm_io_autoflush __P((SM_FILE_T *, SM_FILE_T *));
259void sm_io_automode __P((SM_FILE_T *, SM_FILE_T *));
260void sm_io_clearerr __P((SM_FILE_T *));
261int sm_io_close __P((SM_FILE_T *, int SM_NONVOLATILE));
262SM_FILE_T *sm_io_dup __P((SM_FILE_T *));
263int sm_io_eof __P((SM_FILE_T *));
264int sm_io_error __P((SM_FILE_T *));
265char *sm_io_fgets __P((SM_FILE_T *, int, char *, int));
266int sm_io_flush __P((SM_FILE_T *, int SM_NONVOLATILE));
267
268int PRINTFLIKE(3, 4)
269sm_io_fprintf __P((SM_FILE_T *, int, const char *, ...));
270
271int sm_io_fputs __P((SM_FILE_T *, int, const char *));
272
273int SCANFLIKE(3, 4)
274sm_io_fscanf __P((SM_FILE_T *, int, const char *, ...));
275
276int sm_io_getc __P((SM_FILE_T *, int));
277int sm_io_getinfo __P((SM_FILE_T *, int, void *));
278SM_FILE_T *sm_io_open __P((const SM_FILE_T *, int SM_NONVOLATILE, const void *,
279 int, const void *));
280int sm_io_purge __P((SM_FILE_T *));
281int sm_io_putc __P((SM_FILE_T *, int, int));
282size_t sm_io_read __P((SM_FILE_T *, int, void *, size_t));
283SM_FILE_T *sm_io_reopen __P((const SM_FILE_T *, int SM_NONVOLATILE,
284 const void *, int, const void *, SM_FILE_T *));
285void sm_io_rewind __P((SM_FILE_T *, int));
286int sm_io_seek __P((SM_FILE_T *, int SM_NONVOLATILE, long SM_NONVOLATILE,
287 int SM_NONVOLATILE));
288int sm_io_setinfo __P((SM_FILE_T *, int, void *));
289int sm_io_setvbuf __P((SM_FILE_T *, int, char *, int, size_t));
290
291int SCANFLIKE(2, 3)
292sm_io_sscanf __P((const char *, char const *, ...));
293
294long sm_io_tell __P((SM_FILE_T *, int SM_NONVOLATILE));
295int sm_io_ungetc __P((SM_FILE_T *, int, int));
296int sm_io_vfprintf __P((SM_FILE_T *, int, const char *, va_list));
297size_t sm_io_write __P((SM_FILE_T *, int, const void *, size_t));
298
299void sm_strio_init __P((SM_FILE_T *, char *, size_t));
300
301extern SM_FILE_T *
302sm_io_fopen __P((
303 char *_pathname,
304 int _flags,
305 ...));
306
307extern SM_FILE_T *
308sm_io_stdioopen __P((
309 FILE *_stream,
310 char *_mode));
311
312extern int
313sm_vasprintf __P((
314 char **_str,
315 const char *_fmt,
316 va_list _ap));
317
318extern int
319sm_vsnprintf __P((
320 char *,
321 size_t,
322 const char *,
323 va_list));
324
325extern void
326sm_perror __P((
327 const char *));
328
329__END_DECLS
330
331/*
332** Functions internal to the implementation.
333*/
334
335__BEGIN_DECLS
336int sm_rget __P((SM_FILE_T *, int));
337int sm_vfscanf __P((SM_FILE_T *, int SM_NONVOLATILE, const char *,
338 va_list SM_NONVOLATILE));
339int sm_wbuf __P((SM_FILE_T *, int, int));
340__END_DECLS
341
342/*
343** The macros are here so that we can
344** define function versions in the library.
345*/
346
347#define sm_getc(f, t) \
348 (--(f)->f_r < 0 ? \
349 sm_rget(f, t) : \
350 (int)(*(f)->f_p++))
351
352/*
353** This has been tuned to generate reasonable code on the vax using pcc.
354** (It also generates reasonable x86 code using gcc.)
355*/
356
357#define sm_putc(f, t, c) \
358 (--(f)->f_w < 0 ? \
359 (f)->f_w >= (f)->f_lbfsize ? \
360 (*(f)->f_p = (c)), *(f)->f_p != '\n' ? \
361 (int)*(f)->f_p++ : \
362 sm_wbuf(f, t, '\n') : \
363 sm_wbuf(f, t, (int)(c)) : \
364 (*(f)->f_p = (c), (int)*(f)->f_p++))
365
366#define sm_eof(p) (((p)->f_flags & SMFEOF) != 0)
367#define sm_error(p) (((p)->f_flags & SMERR) != 0)
368#define sm_clearerr(p) ((void)((p)->f_flags &= ~(SMERR|SMFEOF)))
369
370#define sm_io_eof(p) sm_eof(p)
371#define sm_io_error(p) sm_error(p)
372
373#define sm_io_clearerr(p) sm_clearerr(p)
374
375#ifndef lint
376# ifndef _POSIX_SOURCE
377# define sm_io_getc(fp, t) sm_getc(fp, t)
378# define sm_io_putc(fp, t, x) sm_putc(fp, t, x)
379# endif /* _POSIX_SOURCE */
380#endif /* lint */
381
382#endif /* SM_IO_H */
225
226/* defines for timeout constants */
227#define SM_TIME_IMMEDIATE (0)
228#define SM_TIME_FOREVER (-1)
229#define SM_TIME_DEFAULT (-2)
230
231/* timeout state for blocking */
232#define SM_TIME_BLOCK (0) /* XXX just bool? */
233#define SM_TIME_NONBLOCK (1)
234
235/* Exposed buffering type flags */
236#define SM_IO_FBF 0 /* setvbuf should set fully buffered */
237#define SM_IO_LBF 1 /* setvbuf should set line buffered */
238#define SM_IO_NBF 2 /* setvbuf should set unbuffered */
239
240/* setvbuf buffered, but through at lower file type layers */
241#define SM_IO_NOW 3
242
243/*
244** size of buffer used by setbuf.
245** If underlying filesystem blocksize is discoverable that is used instead
246*/
247
248#define SM_IO_BUFSIZ 4096
249
250#define SM_IO_EOF (-1)
251
252/* Functions defined in ANSI C standard. */
253__BEGIN_DECLS
254SM_FILE_T *sm_io_autoflush __P((SM_FILE_T *, SM_FILE_T *));
255void sm_io_automode __P((SM_FILE_T *, SM_FILE_T *));
256void sm_io_clearerr __P((SM_FILE_T *));
257int sm_io_close __P((SM_FILE_T *, int SM_NONVOLATILE));
258SM_FILE_T *sm_io_dup __P((SM_FILE_T *));
259int sm_io_eof __P((SM_FILE_T *));
260int sm_io_error __P((SM_FILE_T *));
261char *sm_io_fgets __P((SM_FILE_T *, int, char *, int));
262int sm_io_flush __P((SM_FILE_T *, int SM_NONVOLATILE));
263
264int PRINTFLIKE(3, 4)
265sm_io_fprintf __P((SM_FILE_T *, int, const char *, ...));
266
267int sm_io_fputs __P((SM_FILE_T *, int, const char *));
268
269int SCANFLIKE(3, 4)
270sm_io_fscanf __P((SM_FILE_T *, int, const char *, ...));
271
272int sm_io_getc __P((SM_FILE_T *, int));
273int sm_io_getinfo __P((SM_FILE_T *, int, void *));
274SM_FILE_T *sm_io_open __P((const SM_FILE_T *, int SM_NONVOLATILE, const void *,
275 int, const void *));
276int sm_io_purge __P((SM_FILE_T *));
277int sm_io_putc __P((SM_FILE_T *, int, int));
278size_t sm_io_read __P((SM_FILE_T *, int, void *, size_t));
279SM_FILE_T *sm_io_reopen __P((const SM_FILE_T *, int SM_NONVOLATILE,
280 const void *, int, const void *, SM_FILE_T *));
281void sm_io_rewind __P((SM_FILE_T *, int));
282int sm_io_seek __P((SM_FILE_T *, int SM_NONVOLATILE, long SM_NONVOLATILE,
283 int SM_NONVOLATILE));
284int sm_io_setinfo __P((SM_FILE_T *, int, void *));
285int sm_io_setvbuf __P((SM_FILE_T *, int, char *, int, size_t));
286
287int SCANFLIKE(2, 3)
288sm_io_sscanf __P((const char *, char const *, ...));
289
290long sm_io_tell __P((SM_FILE_T *, int SM_NONVOLATILE));
291int sm_io_ungetc __P((SM_FILE_T *, int, int));
292int sm_io_vfprintf __P((SM_FILE_T *, int, const char *, va_list));
293size_t sm_io_write __P((SM_FILE_T *, int, const void *, size_t));
294
295void sm_strio_init __P((SM_FILE_T *, char *, size_t));
296
297extern SM_FILE_T *
298sm_io_fopen __P((
299 char *_pathname,
300 int _flags,
301 ...));
302
303extern SM_FILE_T *
304sm_io_stdioopen __P((
305 FILE *_stream,
306 char *_mode));
307
308extern int
309sm_vasprintf __P((
310 char **_str,
311 const char *_fmt,
312 va_list _ap));
313
314extern int
315sm_vsnprintf __P((
316 char *,
317 size_t,
318 const char *,
319 va_list));
320
321extern void
322sm_perror __P((
323 const char *));
324
325__END_DECLS
326
327/*
328** Functions internal to the implementation.
329*/
330
331__BEGIN_DECLS
332int sm_rget __P((SM_FILE_T *, int));
333int sm_vfscanf __P((SM_FILE_T *, int SM_NONVOLATILE, const char *,
334 va_list SM_NONVOLATILE));
335int sm_wbuf __P((SM_FILE_T *, int, int));
336__END_DECLS
337
338/*
339** The macros are here so that we can
340** define function versions in the library.
341*/
342
343#define sm_getc(f, t) \
344 (--(f)->f_r < 0 ? \
345 sm_rget(f, t) : \
346 (int)(*(f)->f_p++))
347
348/*
349** This has been tuned to generate reasonable code on the vax using pcc.
350** (It also generates reasonable x86 code using gcc.)
351*/
352
353#define sm_putc(f, t, c) \
354 (--(f)->f_w < 0 ? \
355 (f)->f_w >= (f)->f_lbfsize ? \
356 (*(f)->f_p = (c)), *(f)->f_p != '\n' ? \
357 (int)*(f)->f_p++ : \
358 sm_wbuf(f, t, '\n') : \
359 sm_wbuf(f, t, (int)(c)) : \
360 (*(f)->f_p = (c), (int)*(f)->f_p++))
361
362#define sm_eof(p) (((p)->f_flags & SMFEOF) != 0)
363#define sm_error(p) (((p)->f_flags & SMERR) != 0)
364#define sm_clearerr(p) ((void)((p)->f_flags &= ~(SMERR|SMFEOF)))
365
366#define sm_io_eof(p) sm_eof(p)
367#define sm_io_error(p) sm_error(p)
368
369#define sm_io_clearerr(p) sm_clearerr(p)
370
371#ifndef lint
372# ifndef _POSIX_SOURCE
373# define sm_io_getc(fp, t) sm_getc(fp, t)
374# define sm_io_putc(fp, t, x) sm_putc(fp, t, x)
375# endif /* _POSIX_SOURCE */
376#endif /* lint */
377
378#endif /* SM_IO_H */