8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sgs / libld / common / exit.c
blob97596457a2959cf1f1765bea193650410de82ccf
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 1988 AT&T
24 * All Rights Reserved
26 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
30 * Utility functions
32 #include <unistd.h>
33 #include <signal.h>
34 #include <locale.h>
35 #include <string.h>
36 #include "msg.h"
37 #include "_libld.h"
40 * Exit after cleaning up.
42 int
43 ld_exit(Ofl_desc *ofl)
46 * If we have created an output file remove it.
48 if ((ofl->ofl_fd > 0) && ((ofl->ofl_flags1 & FLG_OF1_NONREG) == 0))
49 (void) unlink(ofl->ofl_name);
52 * Inform any support library that the link-edit has failed.
54 ld_sup_atexit(ofl, 1);
57 * Wrap up debug output file if one is open
59 dbg_cleanup();
61 /* If any ERR_GUIDANCE messages were issued, add a summary */
62 if (ofl->ofl_guideflags & FLG_OFG_ISSUED)
63 ld_eprintf(ofl, ERR_GUIDANCE, MSG_INTL(MSG_GUIDE_SUMMARY));
65 return (1);
69 * Establish the signals we're interested in, and the handlers that need to be
70 * reinstalled should any of these signals occur.
72 typedef struct {
73 int signo;
74 void (* defhdl)();
75 } Signals;
77 static Signals signals[] = {
78 { SIGHUP, SIG_DFL },
79 { SIGINT, SIG_IGN },
80 { SIGQUIT, SIG_DFL },
81 { SIGBUS, SIG_DFL },
82 { SIGTERM, SIG_IGN },
83 { 0, 0 } };
85 static Ofl_desc *Ofl = NULL;
88 * Define our signal handler.
90 static void
91 /* ARGSUSED2 */
92 handler(int sig, siginfo_t *sip, void *utp)
94 struct sigaction nact;
95 Signals * sigs;
98 * Reset all ignore handlers regardless of how we got here.
100 nact.sa_handler = SIG_IGN;
101 nact.sa_flags = 0;
102 (void) sigemptyset(&nact.sa_mask);
104 for (sigs = signals; sigs->signo; sigs++) {
105 if (sigs->defhdl == SIG_IGN)
106 (void) sigaction(sigs->signo, &nact, NULL);
110 * The model for creating an output file is to ftruncate() it to the
111 * required size and mmap() a mapping into which the new contents are
112 * written. Neither of these operations guarantee that the required
113 * disk blocks exist, and should we run out of disk space a bus error
114 * is generated.
115 * Other situations have been reported to result in ld catching a bus
116 * error (one instance was a stale NFS handle from an unstable server).
117 * Thus we catch all bus errors and hope we can decode a better error.
119 if ((sig == SIGBUS) && sip && Ofl->ofl_name) {
120 ld_eprintf(Ofl, ERR_FATAL, MSG_INTL(MSG_FIL_INTERRUPT),
121 Ofl->ofl_name, strerror(sip->si_errno));
124 * This assert(0) causes DEBUG enabled linkers to produce a core file.
126 if ((sig != SIGHUP) && (sig != SIGINT))
127 assert(0);
129 exit(ld_exit(Ofl));
133 * Establish a signal handler for all signals we're interested in.
135 void
136 ld_init_sighandler(Ofl_desc *ofl)
138 struct sigaction nact, oact;
139 Signals * sigs;
141 Ofl = ofl;
144 * Our heavy use of mmap() means that we are susceptible to
145 * receiving a SIGBUS in low diskspace situations. The main
146 * purpose of the signal handler is to handle that situation
147 * gracefully, so that out of disk errors don't drop a core file.
149 * In rare cases, this will prevent us from getting a core from a
150 * SIGBUS triggered by an internal alignment error in libld.
151 * If -znosighandler is set, return without registering the
152 * handler. This is primarily of use for debugging problems in
153 * the field, and is not of general interest.
155 if (ofl->ofl_flags1 & FLG_OF1_NOSGHND)
156 return;
159 * For each signal we're interested in set up a signal handler that
160 * insures we clean up any output file we're in the middle of creating.
162 nact.sa_sigaction = handler;
163 (void) sigemptyset(&nact.sa_mask);
165 for (sigs = signals; sigs->signo; sigs++) {
166 if ((sigaction(sigs->signo, NULL, &oact) == 0) &&
167 (oact.sa_handler != SIG_IGN)) {
168 nact.sa_flags = SA_SIGINFO;
169 if (sigs->defhdl == SIG_DFL)
170 nact.sa_flags |= (SA_RESETHAND | SA_NODEFER);
171 (void) sigaction(sigs->signo, &nact, NULL);