fseek.c revision 1
2N/A * Copyright (c) 2000-2001, 2004 Sendmail, Inc. and its suppliers. 2N/A * All rights reserved. 2N/A * Copyright (c) 1990, 1993 2N/A * The Regents of the University of California. All rights reserved. 2N/A * This code is derived from software contributed to Berkeley by 2N/A * By using this file, you agree to the terms and conditions set 2N/A * forth in the LICENSE file which can be found at the top level of 2N/A * the sendmail distribution. 2N/A#
pragma ident "%Z%%M% %I% %E% SMI" 2N/A** SEEKALRM -- handler when timeout activated for sm_io_seek() 2N/A** Returns flow of control to where setjmp(SeekTimeOut) was set. 2N/A** returns flow of control to setjmp(SeekTimeOut). 2N/A** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD 2N/A** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE 2N/A** SM_IO_SEEK -- position the file pointer 2N/A** fp -- the file pointer to be seek'd 2N/A** timeout -- time to complete seek (milliseconds) 2N/A** offset -- seek offset based on 'whence' 2N/A** whence -- indicates where seek is relative from. 2N/A** One of SM_IO_SEEK_{CUR,SET,END}. 2N/A** Failure: returns -1 (minus 1) and sets errno 2N/A** Success: returns 0 (zero) /* make sure stdio is set up */ /* Have to be able to seek. */ ** Filling the buffer will take time and we are wanted to ** return immediately. So... ** Change any SM_IO_SEEK_CUR to SM_IO_SEEK_SET, and check `whence' ** argument. After this, whence is either SM_IO_SEEK_SET or ** In order to seek relative to the current stream offset, ** we have to first find the current stream offset a la ** ftell (see ftell for details). /* may adjust seek offset on append stream */ curoff = 0;
/* XXX just to keep gcc quiet */ ** reading (and not reading-and-writing); ** this is a `regular' Unix file (and hence seekfn==sm_stdseek). ** We must check SMNBF first, because it is possible to have SMNBF ** We are reading; we can try to optimise. ** Figure out where we are going and where we are now. ** Compute the number of bytes in the input buffer (pretending ** that any ungetc() input has been discarded). Adjust current ** offset backwards by this count so that it represents the ** file offset for the first byte in the current input buffer. ** If the target offset is within the current buffer, ** simply adjust the pointers, clear SMFEOF, undo ungetc(), ** and return. (If the buffer was modified, we have to ** skip this; see getln in fget.c.) ** The place we want to get to is not within the current buffer, ** but we can still be kind to the kernel copyout mechanism. ** By aligning the file offset to a block boundary, we can let ** the kernel use the VM hardware to map pages instead of ** copying bytes laboriously. Using a block boundary also ** ensures that we only read one block, rather than two. /* Note: SM_TIME_FOREVER since fn timeout already set */ /* We're back. So undo our timeout and handler */ ** We get here if we cannot optimise the seek ... just ** do it. Allow the seek function to change fp->f_bf.smb_base. /* Note: SM_TIME_FOREVER since fn timeout already set */ /* success: clear SMFEOF indicator and discard ungetc() data */