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.
10 #pragma ident "%Z%%M% %I% %E% SMI"
13 SM_IDSTR(id
, "@(#)$Id: smstdio.c,v 1.34 2004/08/03 20:46:34 ca Exp $")
19 #include <sm/assert.h>
21 #include <sm/string.h>
24 static void setup
__P((SM_FILE_T
*));
28 ** This is a file type which implements a layer on top of the system
29 ** stdio. fp->f_cookie is the FILE* of stdio. The cookie may be
30 ** "bound late" because of the manner which Linux implements stdio.
31 ** When binding late (when fp->f_cookie==NULL) then the value of
32 ** fp->f_ival is used (0, 1 or 2) to map to stdio's stdin, stdout or
37 ** SM_STDIOOPEN -- open a file to system stdio implementation
40 ** fp -- file pointer assign for this open
41 ** info -- info about file to open
42 ** flags -- indicating method of opening
52 sm_stdioopen(fp
, info
, flags
, rpool
)
85 case SM_IO_APPENDRW_B
:
91 #endif /* SM_IO_BINARY != 0 */
98 if ((s
= fopen((char *)info
, stdiomode
)) == NULL
)
105 ** SETUP -- assign file type cookie when not already assigned
108 ** fp - the file pointer to get the cookie assigned
118 if (fp
->f_cookie
== NULL
)
123 fp
->f_cookie
= stdin
;
126 fp
->f_cookie
= stdout
;
129 fp
->f_cookie
= stderr
;
132 sm_abort("fp->f_ival=%d: out of range (0...2)", fp
->f_ival
);
139 ** SM_STDIOREAD -- read from the file
142 ** fp -- the file pointer
143 ** buf -- location to place the read data
144 ** n - number of bytes to read
147 ** result from fread().
151 sm_stdioread(fp
, buf
, n
)
158 if (fp
->f_cookie
== NULL
)
161 return fread(buf
, 1, n
, s
);
165 ** SM_STDIOWRITE -- write to the file
168 ** fp -- the file pointer
169 ** buf -- location of data to write
170 ** n - number of bytes to write
173 ** result from fwrite().
177 sm_stdiowrite(fp
, buf
, n
)
184 if (fp
->f_cookie
== NULL
)
187 return fwrite(buf
, 1, n
, s
);
191 ** SM_STDIOSEEK -- set position within file
194 ** fp -- the file pointer
195 ** offset -- new location based on 'whence'
196 ** whence -- indicates "base" for 'offset'
199 ** result from fseek().
203 sm_stdioseek(fp
, offset
, whence
)
210 if (fp
->f_cookie
== NULL
)
213 return fseek(s
, offset
, whence
);
217 ** SM_STDIOCLOSE -- close the file
220 ** fp -- close file pointer
223 ** status from fclose()
232 if (fp
->f_cookie
== NULL
)
239 ** SM_STDIOSETINFO -- set info for this open file
242 ** fp -- the file pointer
243 ** what -- type of information setting
244 ** valp -- memory location of info to set
247 ** Failure: -1 and sets errno
248 ** Success: none (currently).
253 sm_stdiosetinfo(fp
, what
, valp
)
260 case SM_IO_WHAT_MODE
:
268 ** SM_STDIOGETINFO -- get info for this open file
271 ** fp -- the file pointer
272 ** what -- type of information request
273 ** valp -- memory location to place info
276 ** Failure: -1 and sets errno
277 ** Success: none (currently).
282 sm_stdiogetinfo(fp
, what
, valp
)
289 case SM_IO_WHAT_SIZE
:
294 if (fp
->f_cookie
== NULL
)
296 fd
= fileno((FILE *) fp
->f_cookie
);
299 if (fstat(fd
, &st
) == 0)
305 case SM_IO_WHAT_MODE
:
313 ** SM_IO_STDIOOPEN -- create an SM_FILE which interfaces to a stdio FILE
316 ** stream -- an open stdio stream, as returned by fopen()
317 ** mode -- the mode argument to fopen() which describes stream
320 ** On success, return a pointer to an SM_FILE object which
321 ** can be used for reading and writing 'stream'.
322 ** Abort if mode is gibberish or stream is bad.
323 ** Raise an exception if we can't allocate memory.
327 sm_io_stdioopen(stream
, mode
)
350 sm_abort("sm_io_stdioopen: mode '%s' is bad", mode
);
352 if (strchr(&mode
[1], '+') != NULL
)
361 fp
= sm_fp(SmFtRealStdio
, ioflags
, NULL
);
363 fp
->f_cookie
= stream
;