source: trunk/third/sendmail/libsm/fpos.c @ 19204

Revision 19204, 3.1 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19203, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
3 *      All rights reserved.
4 * Copyright (c) 1990, 1993
5 *      The Regents of the University of California.  All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Chris Torek.
9 *
10 * By using this file, you agree to the terms and conditions set
11 * forth in the LICENSE file which can be found at the top level of
12 * the sendmail distribution.
13 */
14
15#include <sm/gen.h>
16SM_RCSID("@(#)$Id: fpos.c,v 1.1.1.1 2003-04-08 15:06:04 zacheiss Exp $")
17#include <errno.h>
18#include <setjmp.h>
19#include <sys/time.h>
20#include <sm/heap.h>
21#include <sm/signal.h>
22#include <sm/clock.h>
23#include <sm/io.h>
24#include <sm/assert.h>
25#include "local.h"
26
27static jmp_buf TellTimeOut;
28
29/*
30**  TELLALRM -- handler when timeout activated for sm_io_tell()
31**
32**  Returns flow of control to where setjmp(TellTimeOut) was set.
33**
34**      Parameters:
35**              sig -- unused
36**
37**      Returns:
38**              does not return
39**
40**      Side Effects:
41**              returns flow of control to setjmp(TellTimeOut).
42**
43**      NOTE:   THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
44**              ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
45**              DOING.
46*/
47
48/* ARGSUSED0 */
49static void
50tellalrm(sig)
51        int sig;
52{
53        longjmp(TellTimeOut, 1);
54}
55
56/*
57**  SM_IO_TELL -- position the file pointer
58**
59**      Paramters:
60**              fp -- the file pointer to get repositioned
61**              timeout -- time to complete the tell (milliseconds)
62**
63**      Returns:
64**              Success -- the repositioned location.
65**              Failure -- -1 (minus 1) and sets errno
66*/
67
68long
69sm_io_tell(fp, timeout)
70        register SM_FILE_T *fp;
71        int SM_NONVOLATILE timeout;
72{
73        register off_t pos;
74        SM_EVENT *evt = NULL;
75
76        SM_REQUIRE_ISA(fp, SmFileMagic);
77        if (fp->f_seek == NULL)
78        {
79                errno = ESPIPE;                 /* historic practice */
80                return -1L;
81        }
82
83        if (timeout == SM_TIME_DEFAULT)
84                timeout = fp->f_timeout;
85        if (timeout == SM_TIME_IMMEDIATE)
86        {
87                /*
88                **  Filling the buffer will take time and we are wanted to
89                **  return immediately. So...
90                */
91
92                errno = EAGAIN;
93                return -1L;
94        }
95
96        /*
97        **  Find offset of underlying I/O object, then adjust byte position
98        **  may adjust seek offset on append stream
99        */
100
101        (void) sm_flush(fp, (int *) &timeout);
102
103        /* This is where we start the timeout */
104        if (timeout != SM_TIME_FOREVER)
105        {
106                if (setjmp(TellTimeOut) != 0)
107                {
108                        errno = EAGAIN;
109                        return -1L;
110                }
111
112                evt = sm_seteventm(timeout, tellalrm, 0);
113        }
114
115        if (fp->f_flags & SMOFF)
116                pos = fp->f_lseekoff;
117        else
118        {
119                /* XXX only set the timeout here? */
120                pos = (*fp->f_seek)(fp, (off_t) 0, SM_IO_SEEK_CUR);
121                if (pos == -1L)
122                        goto clean;
123        }
124        if (fp->f_flags & SMRD)
125        {
126                /*
127                **  Reading.  Any unread characters (including
128                **  those from ungetc) cause the position to be
129                **  smaller than that in the underlying object.
130                */
131
132                pos -= fp->f_r;
133                if (HASUB(fp))
134                        pos -= fp->f_ur;
135        }
136        else if (fp->f_flags & SMWR && fp->f_p != NULL)
137        {
138                /*
139                **  Writing.  Any buffered characters cause the
140                **  position to be greater than that in the
141                **  underlying object.
142                */
143
144                pos += fp->f_p - fp->f_bf.smb_base;
145        }
146
147clean:
148        /*  We're back. So undo our timeout and handler */
149        if (evt != NULL)
150                sm_clrevent(evt);
151        return pos;
152}
Note: See TracBrowser for help on using the repository browser.