2 * Copyright (c) 2000-2001, 2004 Sendmail, Inc. and its suppliers.
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
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.
15 #pragma ident "%Z%%M% %I% %E% SMI"
18 SM_RCSID("@(#)$Id: fpos.c,v 1.39 2005/06/14 23:07:20 ca Exp $")
23 #include <sm/signal.h>
26 #include <sm/assert.h>
29 static void tellalrm
__P((int));
30 static jmp_buf TellTimeOut
;
33 ** TELLALRM -- handler when timeout activated for sm_io_tell()
35 ** Returns flow of control to where setjmp(TellTimeOut) was set.
44 ** returns flow of control to setjmp(TellTimeOut).
46 ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
47 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
56 longjmp(TellTimeOut
, 1);
60 ** SM_IO_TELL -- position the file pointer
63 ** fp -- the file pointer to get repositioned
64 ** timeout -- time to complete the tell (milliseconds)
67 ** Success -- the repositioned location.
68 ** Failure -- -1 (minus 1) and sets errno
72 sm_io_tell(fp
, timeout
)
73 register SM_FILE_T
*fp
;
74 int SM_NONVOLATILE timeout
;
79 SM_REQUIRE_ISA(fp
, SmFileMagic
);
80 if (fp
->f_seek
== NULL
)
82 errno
= ESPIPE
; /* historic practice */
86 if (timeout
== SM_TIME_DEFAULT
)
87 timeout
= fp
->f_timeout
;
88 if (timeout
== SM_TIME_IMMEDIATE
)
91 ** Filling the buffer will take time and we are wanted to
92 ** return immediately. So...
100 ** Find offset of underlying I/O object, then adjust byte position
101 ** may adjust seek offset on append stream
104 (void) sm_flush(fp
, (int *) &timeout
);
106 /* This is where we start the timeout */
107 if (timeout
!= SM_TIME_FOREVER
)
109 if (setjmp(TellTimeOut
) != 0)
115 evt
= sm_seteventm(timeout
, tellalrm
, 0);
118 if (fp
->f_flags
& SMOFF
)
119 pos
= fp
->f_lseekoff
;
122 /* XXX only set the timeout here? */
123 pos
= (*fp
->f_seek
)(fp
, (off_t
) 0, SM_IO_SEEK_CUR
);
127 if (fp
->f_flags
& SMRD
)
130 ** Reading. Any unread characters (including
131 ** those from ungetc) cause the position to be
132 ** smaller than that in the underlying object.
139 else if (fp
->f_flags
& SMWR
&& fp
->f_p
!= NULL
)
142 ** Writing. Any buffered characters cause the
143 ** position to be greater than that in the
144 ** underlying object.
147 pos
+= fp
->f_p
- fp
->f_bf
.smb_base
;
151 /* We're back. So undo our timeout and handler */