diff options
author | peter <peter@FreeBSD.org> | 2008-08-28 02:25:51 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2008-08-28 02:25:51 +0000 |
commit | ea50d71feb02a78d4d5fa746a26ca7ddc6e8cb19 (patch) | |
tree | daf40952cf309641cc6c7d987989fd2abce2d758 /contrib/sendmail/libsm/fseek.c | |
parent | a2b986fa722f9860a6c56bb5cc724b7e2937d1b7 (diff) | |
download | FreeBSD-src-ea50d71feb02a78d4d5fa746a26ca7ddc6e8cb19.zip FreeBSD-src-ea50d71feb02a78d4d5fa746a26ca7ddc6e8cb19.tar.gz |
Stage 1 of sendmail dist tree flattening. contrib/sendmail/contrib
prevents doing this in one pass.
Diffstat (limited to 'contrib/sendmail/libsm/fseek.c')
-rw-r--r-- | contrib/sendmail/libsm/fseek.c | 336 |
1 files changed, 0 insertions, 336 deletions
diff --git a/contrib/sendmail/libsm/fseek.c b/contrib/sendmail/libsm/fseek.c deleted file mode 100644 index 4b3fe10..0000000 --- a/contrib/sendmail/libsm/fseek.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (c) 2000-2001, 2004 Sendmail, Inc. and its suppliers. - * All rights reserved. - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Chris Torek. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - */ - -#include <sm/gen.h> -SM_RCSID("@(#)$Id: fseek.c,v 1.47 2005/06/14 23:07:20 ca Exp $") -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdlib.h> -#include <errno.h> -#include <setjmp.h> -#include <sm/time.h> -#include <sm/signal.h> -#include <sm/io.h> -#include <sm/assert.h> -#include <sm/clock.h> -#include "local.h" - -#define POS_ERR (-(off_t)1) - -static void seekalrm __P((int)); -static jmp_buf SeekTimeOut; - -/* -** SEEKALRM -- handler when timeout activated for sm_io_seek() -** -** Returns flow of control to where setjmp(SeekTimeOut) was set. -** -** Parameters: -** sig -- unused -** -** Returns: -** does not return -** -** Side Effects: -** returns flow of control to setjmp(SeekTimeOut). -** -** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD -** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE -** DOING. -*/ - -/* ARGSUSED0 */ -static void -seekalrm(sig) - int sig; -{ - longjmp(SeekTimeOut, 1); -} - -/* -** SM_IO_SEEK -- position the file pointer -** -** Parameters: -** fp -- the file pointer to be seek'd -** timeout -- time to complete seek (milliseconds) -** offset -- seek offset based on 'whence' -** whence -- indicates where seek is relative from. -** One of SM_IO_SEEK_{CUR,SET,END}. -** Returns: -** Failure: returns -1 (minus 1) and sets errno -** Success: returns 0 (zero) -*/ - -int -sm_io_seek(fp, timeout, offset, whence) - register SM_FILE_T *fp; - int SM_NONVOLATILE timeout; - long SM_NONVOLATILE offset; - int SM_NONVOLATILE whence; -{ - bool havepos; - off_t target, curoff; - size_t n; - struct stat st; - int ret; - SM_EVENT *evt = NULL; - register off_t (*seekfn) __P((SM_FILE_T *, off_t, int)); - - SM_REQUIRE_ISA(fp, SmFileMagic); - - /* make sure stdio is set up */ - if (!Sm_IO_DidInit) - sm_init(); - - /* Have to be able to seek. */ - if ((seekfn = fp->f_seek) == NULL) - { - errno = ESPIPE; /* historic practice */ - return -1; - } - - if (timeout == SM_TIME_DEFAULT) - timeout = fp->f_timeout; - if (timeout == SM_TIME_IMMEDIATE) - { - /* - ** Filling the buffer will take time and we are wanted to - ** return immediately. So... - */ - - errno = EAGAIN; - return -1; - } - -#define SM_SET_ALARM() \ - if (timeout != SM_TIME_FOREVER) \ - { \ - if (setjmp(SeekTimeOut) != 0) \ - { \ - errno = EAGAIN; \ - return -1; \ - } \ - evt = sm_seteventm(timeout, seekalrm, 0); \ - } - - /* - ** 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 - ** SM_IO_SEEK_END. - */ - - switch (whence) - { - case SM_IO_SEEK_CUR: - - /* - ** 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 */ - sm_flush(fp, (int *) &timeout); - SM_SET_ALARM(); - if (fp->f_flags & SMOFF) - curoff = fp->f_lseekoff; - else - { - curoff = (*seekfn)(fp, (off_t) 0, SM_IO_SEEK_CUR); - if (curoff == -1L) - { - ret = -1; - goto clean; - } - } - if (fp->f_flags & SMRD) - { - curoff -= fp->f_r; - if (HASUB(fp)) - curoff -= fp->f_ur; - } - else if (fp->f_flags & SMWR && fp->f_p != NULL) - curoff += fp->f_p - fp->f_bf.smb_base; - - offset += curoff; - whence = SM_IO_SEEK_SET; - havepos = true; - break; - - case SM_IO_SEEK_SET: - case SM_IO_SEEK_END: - SM_SET_ALARM(); - curoff = 0; /* XXX just to keep gcc quiet */ - havepos = false; - break; - - default: - errno = EINVAL; - return -1; - } - - /* - ** Can only optimise if: - ** reading (and not reading-and-writing); - ** not unbuffered; and - ** this is a `regular' Unix file (and hence seekfn==sm_stdseek). - ** We must check SMNBF first, because it is possible to have SMNBF - ** and SMSOPT both set. - */ - - if (fp->f_bf.smb_base == NULL) - sm_makebuf(fp); - if (fp->f_flags & (SMWR | SMRW | SMNBF | SMNPT)) - goto dumb; - if ((fp->f_flags & SMOPT) == 0) - { - if (seekfn != sm_stdseek || - fp->f_file < 0 || fstat(fp->f_file, &st) || - (st.st_mode & S_IFMT) != S_IFREG) - { - fp->f_flags |= SMNPT; - goto dumb; - } - fp->f_blksize = st.st_blksize; - fp->f_flags |= SMOPT; - } - - /* - ** We are reading; we can try to optimise. - ** Figure out where we are going and where we are now. - */ - - if (whence == SM_IO_SEEK_SET) - target = offset; - else - { - if (fstat(fp->f_file, &st)) - goto dumb; - target = st.st_size + offset; - } - - if (!havepos) - { - if (fp->f_flags & SMOFF) - curoff = fp->f_lseekoff; - else - { - curoff = (*seekfn)(fp, (off_t) 0, SM_IO_SEEK_CUR); - if (curoff == POS_ERR) - goto dumb; - } - curoff -= fp->f_r; - if (HASUB(fp)) - curoff -= fp->f_ur; - } - - /* - ** 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 (HASUB(fp)) - { - curoff += fp->f_r; /* kill off ungetc */ - n = fp->f_up - fp->f_bf.smb_base; - curoff -= n; - n += fp->f_ur; - } - else - { - n = fp->f_p - fp->f_bf.smb_base; - curoff -= n; - n += fp->f_r; - } - - /* - ** 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.) - */ - - if (target >= curoff && target < curoff + (off_t) n) - { - register int o = target - curoff; - - fp->f_p = fp->f_bf.smb_base + o; - fp->f_r = n - o; - if (HASUB(fp)) - FREEUB(fp); - fp->f_flags &= ~SMFEOF; - ret = 0; - goto clean; - } - - /* - ** 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. - */ - - curoff = target & ~(fp->f_blksize - 1); - if ((*seekfn)(fp, curoff, SM_IO_SEEK_SET) == POS_ERR) - goto dumb; - fp->f_r = 0; - fp->f_p = fp->f_bf.smb_base; - if (HASUB(fp)) - FREEUB(fp); - fp->f_flags &= ~SMFEOF; - n = target - curoff; - if (n) - { - /* Note: SM_TIME_FOREVER since fn timeout already set */ - if (sm_refill(fp, SM_TIME_FOREVER) || fp->f_r < (int) n) - goto dumb; - fp->f_p += n; - fp->f_r -= n; - } - - ret = 0; -clean: - /* We're back. So undo our timeout and handler */ - if (evt != NULL) - sm_clrevent(evt); - return ret; -dumb: - /* - ** 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 */ - ret = SM_TIME_FOREVER; - if (sm_flush(fp, &ret) != 0 || - (*seekfn)(fp, (off_t) offset, whence) == POS_ERR) - { - ret = -1; - goto clean; - } - - /* success: clear SMFEOF indicator and discard ungetc() data */ - if (HASUB(fp)) - FREEUB(fp); - fp->f_p = fp->f_bf.smb_base; - fp->f_r = 0; - fp->f_flags &= ~SMFEOF; - ret = 0; - goto clean; -} |