8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sendmail / libsm / fclose.c
blob3b3b6ec67de4ca6071fcae7c10169f72b1e88d92
1 /*
2 * Copyright (c) 2000-2002, 2004 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.
7 * This code is derived from software contributed to Berkeley by
8 * Chris Torek.
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"
17 #include <sm/gen.h>
18 SM_RCSID("@(#)$Id: fclose.c,v 1.44 2005/06/14 23:07:20 ca Exp $")
19 #include <errno.h>
20 #include <stdlib.h>
21 #include <sm/time.h>
22 #include <setjmp.h>
23 #include <sm/io.h>
24 #include <sm/assert.h>
25 #include <sm/heap.h>
26 #include <sm/signal.h>
27 #include <sm/conf.h>
28 #include <sm/clock.h>
29 #include "local.h"
31 static void closealrm __P((int));
32 static jmp_buf CloseTimeOut;
35 ** CLOSEALRM -- handler when timeout activated for sm_io_close()
37 ** Returns flow of control to where setjmp(CloseTimeOut) was set.
39 ** Parameters:
40 ** sig -- unused
42 ** Returns:
43 ** does not return
45 ** Side Effects:
46 ** returns flow of control to setjmp(CloseTimeOut).
48 ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
49 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
50 ** DOING.
53 /* ARGSUSED0 */
54 static void
55 closealrm(sig)
56 int sig;
58 longjmp(CloseTimeOut, 1);
62 ** SM_IO_CLOSE -- close a file handle/pointer
64 ** Parameters:
65 ** fp -- file pointer to be closed
66 ** timeout -- maximum time allowed to perform the close (millisecs)
68 ** Returns:
69 ** 0 on success
70 ** -1 on failure and sets errno
72 ** Side Effects:
73 ** file pointer 'fp' will no longer be valid.
76 int
77 sm_io_close(fp, timeout)
78 register SM_FILE_T *fp;
79 int SM_NONVOLATILE timeout;
81 register int SM_NONVOLATILE r;
82 SM_EVENT *evt = NULL;
84 if (fp == NULL)
86 errno = EBADF;
87 return SM_IO_EOF;
90 SM_REQUIRE_ISA(fp, SmFileMagic);
92 /* XXX this won't be reached if above macro is active */
93 if (fp->sm_magic == NULL)
95 /* not open! */
96 errno = EBADF;
97 return SM_IO_EOF;
99 if (fp->f_close == NULL)
101 /* no close function! */
102 errno = ENODEV;
103 return SM_IO_EOF;
105 if (fp->f_dup_cnt > 0)
107 /* decrement file pointer open count */
108 fp->f_dup_cnt--;
109 return 0;
112 /* Okay, this is where we set the timeout. */
113 if (timeout == SM_TIME_DEFAULT)
114 timeout = fp->f_timeout;
115 if (timeout == SM_TIME_IMMEDIATE)
117 errno = EAGAIN;
118 return -1;
121 /* No more duplicates of file pointer. Flush buffer and close */
122 r = fp->f_flags & SMWR ? sm_flush(fp, (int *) &timeout) : 0;
124 /* sm_flush() has updated to.it_value for the time it's used */
125 if (timeout != SM_TIME_FOREVER)
127 if (setjmp(CloseTimeOut) != 0)
129 errno = EAGAIN;
130 return SM_IO_EOF;
132 evt = sm_seteventm(timeout, closealrm, 0);
134 if ((*fp->f_close)(fp) < 0)
135 r = SM_IO_EOF;
137 /* We're back. So undo our timeout and handler */
138 if (evt != NULL)
139 sm_clrevent(evt);
140 if (fp->f_flags & SMMBF)
142 sm_free((char *)fp->f_bf.smb_base);
143 fp->f_bf.smb_base = NULL;
145 if (HASUB(fp))
146 FREEUB(fp);
147 fp->f_flags = 0; /* clear flags */
148 fp->sm_magic = NULL; /* Release this SM_FILE_T for reuse. */
149 fp->f_r = fp->f_w = 0; /* Mess up if reaccessed. */
150 return r;