1N/A * Copyright (c) 2000-2001, 2005-2006 Sendmail, Inc. and its suppliers. 1N/A * All rights reserved. 1N/A * Copyright (c) 1990, 1993 1N/A * The Regents of the University of California. All rights reserved. 1N/A * This code is derived from software contributed to Berkeley by 1N/A * By using this file, you agree to the terms and conditions set 1N/A * forth in the LICENSE file which can be found at the top level of 1N/A * the sendmail distribution. 1N/A#
pragma ident "%Z%%M% %I% %E% SMI" 1N/A** SM_IO_RD_TIMEOUT -- measured timeout for reads 1N/A** This #define uses a select() to wait for the 'fd' to become readable. 1N/A** The select() can be active for up to 'To' time. The select() may not 1N/A** use all of the the 'To' time. Hence, the amount of "wall-clock" time is 1N/A** measured to decide how much to subtract from 'To' to update it. On some 1N/A** amount of time used. On many/most systems this does not happen. Therefore 1N/A** the updating of 'To' must be done ourselves; a copy of 'To' is passed 1N/A** since a BSD-like system will have updated it and we don't want to 1N/A** double the time used! 1N/A** Note: if a valid 'fd' doesn't exist yet, don't use this (e.g. the 1N/A** fp -- the file pointer for the active file 1N/A** fd -- raw file descriptor (from 'fp') to use for select() 1N/A** to -- struct timeval of the timeout 1N/A** timeout -- the original timeout value 1N/A** sel_ret -- the return value from the select() 1N/A** nothing, flow through code 1N/A /* something went wrong, errno set */ \
1N/A /* calulate wall-clock time used */ \
1N/A** SM_LFLUSH -- flush a file if it is line buffered and writable 1N/A** fp -- file pointer to flush 1N/A** timeout -- original timeout value (in milliseconds) 1N/A** Failure: returns SM_IO_EOF and sets errno 1N/A** Success: returns 0 1N/A** SM_REFILL -- refill a buffer 1N/A** fp -- file pointer for buffer refill 1N/A** timeout -- time to complete filling the buffer in milliseconds 1N/A** Success: returns 0 1N/A** Failure: returns SM_IO_EOF 1N/A ** Filling the buffer will take time and we are wanted to 1N/A ** return immediately. And we're not EOF or ERR really. 1N/A ** So... the failure is we couldn't do it in time. 1N/A /* make sure stdio is set up */ 1N/A fp->
f_r = 0;
/* largely a convenience for callers */ 1N/A /* if not already reading, have to be reading and writing */ 1N/A /* switch to reading */ 1N/A ** We were reading. If there is an ungetc buffer, 1N/A ** we must have been reading from that. Drop it, 1N/A ** restoring the previous buffer (if any). If there 1N/A ** is anything in that buffer, return. 1N/A /* revert blocking state */ 1N/A ** Before reading from a line buffered or unbuffered file, 1N/A ** flush all line buffered output files, per the ANSI C standard. 1N/A ** If this file is linked to another, and we are going to hang 1N/A ** on the read, flush the linked file before continuing. 1N/A ** The do-while loop stops trying to read when something is read 1N/A ** or it appears that the timeout has expired before finding 1N/A ** something available to be read (via select()). 1N/A errno = 0;
/* needed to ensure EOF correctly found */ 1N/A break;
/* EOF found */ 1N/A /* read would block */ 1N/A** SM_RGET -- refills buffer and returns first character 1N/A** Handle sm_getc() when the buffer ran out: 1N/A** Refill, then return the first character in the newly-filled buffer. 1N/A** fp -- file pointer to work on 1N/A** timeout -- time to complete refill 1N/A** Success: first character in refilled buffer as an int 1N/A** Failure: SM_IO_EOF