summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/libsm/fpos.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/libsm/fpos.c')
-rw-r--r--contrib/sendmail/libsm/fpos.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/contrib/sendmail/libsm/fpos.c b/contrib/sendmail/libsm/fpos.c
new file mode 100644
index 0000000..a8083fd
--- /dev/null
+++ b/contrib/sendmail/libsm/fpos.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2000-2001 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: fpos.c,v 1.37 2001/09/11 04:04:48 gshapiro Exp $")
+#include <errno.h>
+#include <setjmp.h>
+#include <sys/time.h>
+#include <sm/heap.h>
+#include <sm/signal.h>
+#include <sm/clock.h>
+#include <sm/io.h>
+#include <sm/assert.h>
+#include "local.h"
+
+static jmp_buf TellTimeOut;
+
+/*
+** TELLALRM -- handler when timeout activated for sm_io_tell()
+**
+** Returns flow of control to where setjmp(TellTimeOut) was set.
+**
+** Parameters:
+** sig -- unused
+**
+** Returns:
+** does not return
+**
+** Side Effects:
+** returns flow of control to setjmp(TellTimeOut).
+**
+** 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
+tellalrm(sig)
+ int sig;
+{
+ longjmp(TellTimeOut, 1);
+}
+
+/*
+** SM_IO_TELL -- position the file pointer
+**
+** Paramters:
+** fp -- the file pointer to get repositioned
+** timeout -- time to complete the tell (milliseconds)
+**
+** Returns:
+** Success -- the repositioned location.
+** Failure -- -1 (minus 1) and sets errno
+*/
+
+long
+sm_io_tell(fp, timeout)
+ register SM_FILE_T *fp;
+ int SM_NONVOLATILE timeout;
+{
+ register off_t pos;
+ SM_EVENT *evt = NULL;
+
+ SM_REQUIRE_ISA(fp, SmFileMagic);
+ if (fp->f_seek == NULL)
+ {
+ errno = ESPIPE; /* historic practice */
+ return -1L;
+ }
+
+ 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 -1L;
+ }
+
+ /*
+ ** Find offset of underlying I/O object, then adjust byte position
+ ** may adjust seek offset on append stream
+ */
+
+ (void) sm_flush(fp, (int *) &timeout);
+
+ /* This is where we start the timeout */
+ if (timeout != SM_TIME_FOREVER)
+ {
+ if (setjmp(TellTimeOut) != 0)
+ {
+ errno = EAGAIN;
+ return -1L;
+ }
+
+ evt = sm_seteventm(timeout, tellalrm, 0);
+ }
+
+ if (fp->f_flags & SMOFF)
+ pos = fp->f_lseekoff;
+ else
+ {
+ /* XXX only set the timeout here? */
+ pos = (*fp->f_seek)(fp, (off_t) 0, SM_IO_SEEK_CUR);
+ if (pos == -1L)
+ goto clean;
+ }
+ if (fp->f_flags & SMRD)
+ {
+ /*
+ ** Reading. Any unread characters (including
+ ** those from ungetc) cause the position to be
+ ** smaller than that in the underlying object.
+ */
+
+ pos -= fp->f_r;
+ if (HASUB(fp))
+ pos -= fp->f_ur;
+ }
+ else if (fp->f_flags & SMWR && fp->f_p != NULL)
+ {
+ /*
+ ** Writing. Any buffered characters cause the
+ ** position to be greater than that in the
+ ** underlying object.
+ */
+
+ pos += fp->f_p - fp->f_bf.smb_base;
+ }
+
+clean:
+ /* We're back. So undo our timeout and handler */
+ if (evt != NULL)
+ sm_clrevent(evt);
+ return pos;
+}
OpenPOWER on IntegriCloud