2 * Copyright (c) 2000-2002 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.
16 SM_RCSID("@(#)$Id: fclose.c,v 1.42 2002/02/01 02:28:00 ca Exp $")
22 #include <sm/assert.h>
24 #include <sm/signal.h>
29 static jmp_buf CloseTimeOut;
32 ** CLOSEALRM -- handler when timeout activated for sm_io_close()
34 ** Returns flow of control to where setjmp(CloseTimeOut) was set.
43 ** returns flow of control to setjmp(CloseTimeOut).
45 ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
46 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
55 longjmp(CloseTimeOut, 1);
59 ** SM_IO_CLOSE -- close a file handle/pointer
62 ** fp -- file pointer to be closed
63 ** timeout -- maximum time allowed to perform the close (millisecs)
67 ** -1 on failure and sets errno
70 ** file pointer 'fp' will no longer be valid.
74 sm_io_close(fp, timeout)
75 register SM_FILE_T *fp;
76 int SM_NONVOLATILE timeout;
78 register int SM_NONVOLATILE r;
87 SM_REQUIRE_ISA(fp, SmFileMagic);
89 /* XXX this won't be reached if above macro is active */
90 if (fp->sm_magic == NULL)
96 if (fp->f_close == NULL)
98 /* no close function! */
102 if (fp->f_dup_cnt > 0)
104 /* decrement file pointer open count */
109 /* Okay, this is where we set the timeout. */
110 if (timeout == SM_TIME_DEFAULT)
111 timeout = fp->f_timeout;
112 if (timeout == SM_TIME_IMMEDIATE)
118 /* No more duplicates of file pointer. Flush buffer and close */
119 r = fp->f_flags & SMWR ? sm_flush(fp, (int *) &timeout) : 0;
121 /* sm_flush() has updated to.it_value for the time it's used */
122 if (timeout != SM_TIME_FOREVER)
124 if (setjmp(CloseTimeOut) != 0)
129 evt = sm_seteventm(timeout, closealrm, 0);
131 if ((*fp->f_close)(fp) < 0)
134 /* We're back. So undo our timeout and handler */
137 if (fp->f_flags & SMMBF)
139 sm_free((char *)fp->f_bf.smb_base);
140 fp->f_bf.smb_base = NULL;
144 fp->f_flags = 0; /* clear flags */
145 fp->sm_magic = NULL; /* Release this SM_FILE_T for reuse. */
146 fp->f_r = fp->f_w = 0; /* Mess up if reaccessed. */