1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright (c) 1997-1999 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include "parser.h"
35 #include "trace.h"
36 #include "db.h"
37 #include "util.h"
38 #include "errlog.h"
39
40 /* Types and Globals */
41 FILE *Bodyfp = NULL;
42 FILE *Headfp = NULL;
43 FILE *Mapfp = NULL;
44
45 static char headfile_name[MAXLINE]; /* Saved for later. */
46 static char mapfile_name[MAXLINE]; /* Saved for later. */
47
48 /* File globals. */
49 static int alt_code_file(void);
50 static void abort_code_file(void);
51
52 /*
53 * open_code_file - open the code file and the invisible temp file.
54 */
55 int
open_code_file(void)56 open_code_file(void)
57 {
58 char *dir = db_get_target_directory();
59 char *body_file_name;
60 int rc = YES;
61
62 errlog(BEGIN, "open_code_file() {");
63
64 /* Open the Head file, which gets the headers, includes and */
65 /* definitions, and eventually gets the body concatenated to it. */
66 (void) snprintf(headfile_name, sizeof (headfile_name), "%s.c",
67 db_get_output_file());
68 if ((Headfp = fopen(headfile_name, "w")) == NULL) {
69 errlog(FATAL, "%s: %s", headfile_name, strerror(errno));
70 }
71
72 (void) snprintf(mapfile_name, sizeof (mapfile_name), "%s-vers",
73 db_get_output_file());
74
75 if ((Mapfp = fopen(mapfile_name, "w")) == NULL) {
76 errlog(FATAL, "%s: %s", mapfile_name, strerror(errno));
77 }
78 (void) fputs("SUNWabi_1.1 {\n global:\n", Mapfp);
79
80 /* Now the Body file, which is an ephemeral temp-file. */
81 if ((body_file_name = tempnam(dir, NULL)) == NULL) {
82 errlog(FATAL, "out of memory creating a temp-file name");
83 }
84
85 if ((Bodyfp = fopen(body_file_name, "w+")) == NULL) {
86 errlog(FATAL, "%s: %s", body_file_name, strerror(errno));
87 }
88
89 if (unlink(body_file_name) != 0) {
90 errlog(FATAL, "unlink %s: %s", body_file_name, strerror(errno));
91 }
92
93 (void) free(body_file_name);
94 errlog(END, "}");
95 return (rc);
96 }
97
98 /*
99 * abort_code_file -- close and discard files.
100 * this function is also called from alt_code_file, so
101 * it is not cool to unlink the code file or the mapfile
102 */
103 static void
abort_code_file(void)104 abort_code_file(void)
105 {
106 errlog(BEGIN, "abort_code_file() {");
107 (void) fclose(Bodyfp);
108 (void) fclose(Headfp);
109 if (unlink(headfile_name) != 0) {
110 errlog(FATAL, "unlink %s: %s", headfile_name, strerror(errno));
111 }
112 errlog(END, "}");
113 }
114
115 int
alt_code_file(void)116 alt_code_file(void)
117 {
118 char hfn[MAXLINE];
119 FILE *hfp;
120
121 abort_code_file();
122 (void) snprintf(hfn, sizeof (hfn), "%s.c", db_get_output_file());
123 if ((hfp = fopen(hfn, "w")) == NULL) {
124 errlog(FATAL, "%s: %s", headfile_name, strerror(errno));
125 }
126
127 (void) fputs("static int __abi_place_holder;\n", hfp);
128 (void) fclose(hfp);
129
130 return (YES);
131 }
132
133 /*
134 * commit_code_file -- close and commit files that have advanced
135 * beyond byte position 0.
136 */
137 int
commit_code_file(void)138 commit_code_file(void)
139 {
140 char copy_buffer[BUFSIZ*8];
141 size_t n;
142
143 errlog(BEGIN, "commit_code_file() {");
144 /*
145 * We unconditionally want a .pf and a -vers file
146 */
147 (void) fputs(" local:\n\t*;\n};\n", Mapfp);
148 if (fclose(Mapfp) != 0) {
149 errlog(FATAL, "fclose %s: %s", mapfile_name, strerror(errno));
150 }
151 if (ftell(Bodyfp) == 0) {
152 /*
153 * special case, redo C file with place holder
154 * so that makefiles won't break...
155 */
156 errlog(END, "}");
157 return (alt_code_file());
158 } else {
159 /* Concatenate body file to head file, close both. */
160 rewind(Bodyfp);
161 while ((n = fread(copy_buffer, 1,
162 sizeof (copy_buffer), Bodyfp)) != 0) {
163 (void) fwrite(copy_buffer, 1, n, Headfp);
164 }
165 (void) fclose(Bodyfp);
166 if (fclose(Headfp) != 0) {
167 errlog(FATAL, "fclose <temp file>: %s",
168 strerror(errno));
169 }
170 }
171
172 errlog(END, "}");
173 return (YES);
174 }
175