140266059SGregory Neil Shapiro /* 25dd76dd0SGregory Neil Shapiro * Copyright (c) 2000-2001, 2004 Proofpoint, Inc. and its suppliers. 340266059SGregory Neil Shapiro * All rights reserved. 440266059SGregory Neil Shapiro * Copyright (c) 1990, 1993 540266059SGregory Neil Shapiro * The Regents of the University of California. All rights reserved. 640266059SGregory Neil Shapiro * 740266059SGregory Neil Shapiro * This code is derived from software contributed to Berkeley by 840266059SGregory Neil Shapiro * Chris Torek. 940266059SGregory Neil Shapiro * 1040266059SGregory Neil Shapiro * By using this file, you agree to the terms and conditions set 1140266059SGregory Neil Shapiro * forth in the LICENSE file which can be found at the top level of 1240266059SGregory Neil Shapiro * the sendmail distribution. 1340266059SGregory Neil Shapiro */ 1440266059SGregory Neil Shapiro 1540266059SGregory Neil Shapiro #include <sm/gen.h> 164313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: fpos.c,v 1.40 2013-11-22 20:51:42 ca Exp $") 1740266059SGregory Neil Shapiro #include <errno.h> 1840266059SGregory Neil Shapiro #include <setjmp.h> 194e4196cbSGregory Neil Shapiro #include <sm/time.h> 2040266059SGregory Neil Shapiro #include <sm/heap.h> 2140266059SGregory Neil Shapiro #include <sm/signal.h> 2240266059SGregory Neil Shapiro #include <sm/clock.h> 2340266059SGregory Neil Shapiro #include <sm/io.h> 2440266059SGregory Neil Shapiro #include <sm/assert.h> 2540266059SGregory Neil Shapiro #include "local.h" 2640266059SGregory Neil Shapiro 27b6bacd31SGregory Neil Shapiro static void tellalrm __P((int)); 2840266059SGregory Neil Shapiro static jmp_buf TellTimeOut; 2940266059SGregory Neil Shapiro 3040266059SGregory Neil Shapiro /* 3140266059SGregory Neil Shapiro ** TELLALRM -- handler when timeout activated for sm_io_tell() 3240266059SGregory Neil Shapiro ** 3340266059SGregory Neil Shapiro ** Returns flow of control to where setjmp(TellTimeOut) was set. 3440266059SGregory Neil Shapiro ** 3540266059SGregory Neil Shapiro ** Parameters: 3640266059SGregory Neil Shapiro ** sig -- unused 3740266059SGregory Neil Shapiro ** 3840266059SGregory Neil Shapiro ** Returns: 3940266059SGregory Neil Shapiro ** does not return 4040266059SGregory Neil Shapiro ** 4140266059SGregory Neil Shapiro ** Side Effects: 4240266059SGregory Neil Shapiro ** returns flow of control to setjmp(TellTimeOut). 4340266059SGregory Neil Shapiro ** 4440266059SGregory Neil Shapiro ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD 4540266059SGregory Neil Shapiro ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE 4640266059SGregory Neil Shapiro ** DOING. 4740266059SGregory Neil Shapiro */ 4840266059SGregory Neil Shapiro 4940266059SGregory Neil Shapiro /* ARGSUSED0 */ 5040266059SGregory Neil Shapiro static void 5140266059SGregory Neil Shapiro tellalrm(sig) 5240266059SGregory Neil Shapiro int sig; 5340266059SGregory Neil Shapiro { 5440266059SGregory Neil Shapiro longjmp(TellTimeOut, 1); 5540266059SGregory Neil Shapiro } 5640266059SGregory Neil Shapiro 5740266059SGregory Neil Shapiro /* 5840266059SGregory Neil Shapiro ** SM_IO_TELL -- position the file pointer 5940266059SGregory Neil Shapiro ** 60*5b0945b5SGregory Neil Shapiro ** Parameters: 6140266059SGregory Neil Shapiro ** fp -- the file pointer to get repositioned 6240266059SGregory Neil Shapiro ** timeout -- time to complete the tell (milliseconds) 6340266059SGregory Neil Shapiro ** 6440266059SGregory Neil Shapiro ** Returns: 6540266059SGregory Neil Shapiro ** Success -- the repositioned location. 6640266059SGregory Neil Shapiro ** Failure -- -1 (minus 1) and sets errno 6740266059SGregory Neil Shapiro */ 6840266059SGregory Neil Shapiro 6940266059SGregory Neil Shapiro long 7040266059SGregory Neil Shapiro sm_io_tell(fp, timeout) 7140266059SGregory Neil Shapiro register SM_FILE_T *fp; 7240266059SGregory Neil Shapiro int SM_NONVOLATILE timeout; 7340266059SGregory Neil Shapiro { 7440266059SGregory Neil Shapiro register off_t pos; 7540266059SGregory Neil Shapiro SM_EVENT *evt = NULL; 7640266059SGregory Neil Shapiro 7740266059SGregory Neil Shapiro SM_REQUIRE_ISA(fp, SmFileMagic); 7840266059SGregory Neil Shapiro if (fp->f_seek == NULL) 7940266059SGregory Neil Shapiro { 8040266059SGregory Neil Shapiro errno = ESPIPE; /* historic practice */ 8140266059SGregory Neil Shapiro return -1L; 8240266059SGregory Neil Shapiro } 8340266059SGregory Neil Shapiro 8440266059SGregory Neil Shapiro if (timeout == SM_TIME_DEFAULT) 8540266059SGregory Neil Shapiro timeout = fp->f_timeout; 8640266059SGregory Neil Shapiro if (timeout == SM_TIME_IMMEDIATE) 8740266059SGregory Neil Shapiro { 8840266059SGregory Neil Shapiro /* 8940266059SGregory Neil Shapiro ** Filling the buffer will take time and we are wanted to 9040266059SGregory Neil Shapiro ** return immediately. So... 9140266059SGregory Neil Shapiro */ 9240266059SGregory Neil Shapiro 9340266059SGregory Neil Shapiro errno = EAGAIN; 9440266059SGregory Neil Shapiro return -1L; 9540266059SGregory Neil Shapiro } 9640266059SGregory Neil Shapiro 9740266059SGregory Neil Shapiro /* 9840266059SGregory Neil Shapiro ** Find offset of underlying I/O object, then adjust byte position 9940266059SGregory Neil Shapiro ** may adjust seek offset on append stream 10040266059SGregory Neil Shapiro */ 10140266059SGregory Neil Shapiro 10240266059SGregory Neil Shapiro (void) sm_flush(fp, (int *) &timeout); 10340266059SGregory Neil Shapiro 10440266059SGregory Neil Shapiro /* This is where we start the timeout */ 10540266059SGregory Neil Shapiro if (timeout != SM_TIME_FOREVER) 10640266059SGregory Neil Shapiro { 10740266059SGregory Neil Shapiro if (setjmp(TellTimeOut) != 0) 10840266059SGregory Neil Shapiro { 10940266059SGregory Neil Shapiro errno = EAGAIN; 11040266059SGregory Neil Shapiro return -1L; 11140266059SGregory Neil Shapiro } 11240266059SGregory Neil Shapiro 11340266059SGregory Neil Shapiro evt = sm_seteventm(timeout, tellalrm, 0); 11440266059SGregory Neil Shapiro } 11540266059SGregory Neil Shapiro 11640266059SGregory Neil Shapiro if (fp->f_flags & SMOFF) 11740266059SGregory Neil Shapiro pos = fp->f_lseekoff; 11840266059SGregory Neil Shapiro else 11940266059SGregory Neil Shapiro { 12040266059SGregory Neil Shapiro /* XXX only set the timeout here? */ 12140266059SGregory Neil Shapiro pos = (*fp->f_seek)(fp, (off_t) 0, SM_IO_SEEK_CUR); 12240266059SGregory Neil Shapiro if (pos == -1L) 12340266059SGregory Neil Shapiro goto clean; 12440266059SGregory Neil Shapiro } 12540266059SGregory Neil Shapiro if (fp->f_flags & SMRD) 12640266059SGregory Neil Shapiro { 12740266059SGregory Neil Shapiro /* 12840266059SGregory Neil Shapiro ** Reading. Any unread characters (including 12940266059SGregory Neil Shapiro ** those from ungetc) cause the position to be 13040266059SGregory Neil Shapiro ** smaller than that in the underlying object. 13140266059SGregory Neil Shapiro */ 13240266059SGregory Neil Shapiro 13340266059SGregory Neil Shapiro pos -= fp->f_r; 13440266059SGregory Neil Shapiro if (HASUB(fp)) 13540266059SGregory Neil Shapiro pos -= fp->f_ur; 13640266059SGregory Neil Shapiro } 13740266059SGregory Neil Shapiro else if (fp->f_flags & SMWR && fp->f_p != NULL) 13840266059SGregory Neil Shapiro { 13940266059SGregory Neil Shapiro /* 14040266059SGregory Neil Shapiro ** Writing. Any buffered characters cause the 14140266059SGregory Neil Shapiro ** position to be greater than that in the 14240266059SGregory Neil Shapiro ** underlying object. 14340266059SGregory Neil Shapiro */ 14440266059SGregory Neil Shapiro 14540266059SGregory Neil Shapiro pos += fp->f_p - fp->f_bf.smb_base; 14640266059SGregory Neil Shapiro } 14740266059SGregory Neil Shapiro 14840266059SGregory Neil Shapiro clean: 14940266059SGregory Neil Shapiro /* We're back. So undo our timeout and handler */ 15040266059SGregory Neil Shapiro if (evt != NULL) 15140266059SGregory Neil Shapiro sm_clrevent(evt); 15240266059SGregory Neil Shapiro return pos; 15340266059SGregory Neil Shapiro } 154