2 * Copyright (c) 2000-2002, 2004 Sendmail, Inc. and its suppliers.
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
11 SM_IDSTR(id, "@(#)$Id: smstdio.c,v 1.34 2004/08/03 20:46:34 ca Exp $")
17 #include <sm/assert.h>
19 #include <sm/string.h>
22 static void setup __P((SM_FILE_T *));
26 ** This is a file type which implements a layer on top of the system
27 ** stdio. fp->f_cookie is the FILE* of stdio. The cookie may be
28 ** "bound late" because of the manner which Linux implements stdio.
29 ** When binding late (when fp->f_cookie==NULL) then the value of
30 ** fp->f_ival is used (0, 1 or 2) to map to stdio's stdin, stdout or
35 ** SM_STDIOOPEN -- open a file to system stdio implementation
38 ** fp -- file pointer assign for this open
39 ** info -- info about file to open
40 ** flags -- indicating method of opening
50 sm_stdioopen(fp, info, flags, rpool)
83 case SM_IO_APPENDRW_B:
89 #endif /* SM_IO_BINARY != 0 */
96 if ((s = fopen((char *)info, stdiomode)) == NULL)
103 ** SETUP -- assign file type cookie when not already assigned
106 ** fp - the file pointer to get the cookie assigned
116 if (fp->f_cookie == NULL)
121 fp->f_cookie = stdin;
124 fp->f_cookie = stdout;
127 fp->f_cookie = stderr;
130 sm_abort("fp->f_ival=%d: out of range (0...2)", fp->f_ival);
137 ** SM_STDIOREAD -- read from the file
140 ** fp -- the file pointer
141 ** buf -- location to place the read data
142 ** n - number of bytes to read
145 ** result from fread().
149 sm_stdioread(fp, buf, n)
156 if (fp->f_cookie == NULL)
159 return fread(buf, 1, n, s);
163 ** SM_STDIOWRITE -- write to the file
166 ** fp -- the file pointer
167 ** buf -- location of data to write
168 ** n - number of bytes to write
171 ** result from fwrite().
175 sm_stdiowrite(fp, buf, n)
182 if (fp->f_cookie == NULL)
185 return fwrite(buf, 1, n, s);
189 ** SM_STDIOSEEK -- set position within file
192 ** fp -- the file pointer
193 ** offset -- new location based on 'whence'
194 ** whence -- indicates "base" for 'offset'
197 ** result from fseek().
201 sm_stdioseek(fp, offset, whence)
208 if (fp->f_cookie == NULL)
211 return fseek(s, offset, whence);
215 ** SM_STDIOCLOSE -- close the file
218 ** fp -- close file pointer
221 ** status from fclose()
230 if (fp->f_cookie == NULL)
237 ** SM_STDIOSETINFO -- set info for this open file
240 ** fp -- the file pointer
241 ** what -- type of information setting
242 ** valp -- memory location of info to set
245 ** Failure: -1 and sets errno
246 ** Success: none (currently).
251 sm_stdiosetinfo(fp, what, valp)
258 case SM_IO_WHAT_MODE:
266 ** SM_STDIOGETINFO -- get info for this open file
269 ** fp -- the file pointer
270 ** what -- type of information request
271 ** valp -- memory location to place info
274 ** Failure: -1 and sets errno
275 ** Success: none (currently).
280 sm_stdiogetinfo(fp, what, valp)
287 case SM_IO_WHAT_SIZE:
292 if (fp->f_cookie == NULL)
294 fd = fileno((FILE *) fp->f_cookie);
297 if (fstat(fd, &st) == 0)
303 case SM_IO_WHAT_MODE:
311 ** SM_IO_STDIOOPEN -- create an SM_FILE which interfaces to a stdio FILE
314 ** stream -- an open stdio stream, as returned by fopen()
315 ** mode -- the mode argument to fopen() which describes stream
318 ** On success, return a pointer to an SM_FILE object which
319 ** can be used for reading and writing 'stream'.
320 ** Abort if mode is gibberish or stream is bad.
321 ** Raise an exception if we can't allocate memory.
325 sm_io_stdioopen(stream, mode)
348 sm_abort("sm_io_stdioopen: mode '%s' is bad", mode);
350 if (strchr(&mode[1], '+') != NULL)
359 fp = sm_fp(SmFtRealStdio, ioflags, NULL);
361 fp->f_cookie = stream;