summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/libsm/fseek.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2008-08-28 02:25:51 +0000
committerpeter <peter@FreeBSD.org>2008-08-28 02:25:51 +0000
commitea50d71feb02a78d4d5fa746a26ca7ddc6e8cb19 (patch)
treedaf40952cf309641cc6c7d987989fd2abce2d758 /contrib/sendmail/libsm/fseek.c
parenta2b986fa722f9860a6c56bb5cc724b7e2937d1b7 (diff)
downloadFreeBSD-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.c336
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;
-}
OpenPOWER on IntegriCloud