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 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 30 #include <stdio.h> 31 #include <string.h> 32 #include <errno.h> 33 #include <unistd.h> 34 #include <stdlib.h> 35 #include <sys/types.h> 36 #include <sys/param.h> 37 #include "parser.h" 38 #include "trace.h" 39 #include "db.h" 40 #include "util.h" 41 #include "errlog.h" 42 43 /* Types and Globals */ 44 FILE *Bodyfp = NULL; 45 FILE *Headfp = NULL; 46 FILE *Mapfp = NULL; 47 48 static char headfile_name[MAXLINE]; /* Saved for later. */ 49 static char mapfile_name[MAXLINE]; /* Saved for later. */ 50 51 /* File globals. */ 52 static int alt_code_file(void); 53 static void abort_code_file(void); 54 55 /* 56 * open_code_file - open the code file and the invisible temp file. 57 */ 58 int 59 open_code_file(void) 60 { 61 char *dir = db_get_target_directory(); 62 char *body_file_name; 63 int rc = YES; 64 65 errlog(BEGIN, "open_code_file() {"); 66 67 /* Open the Head file, which gets the headers, includes and */ 68 /* definitions, and eventually gets the body concatenated to it. */ 69 (void) snprintf(headfile_name, sizeof (headfile_name), "%s.c", 70 db_get_output_file()); 71 if ((Headfp = fopen(headfile_name, "w")) == NULL) { 72 errlog(FATAL, "%s: %s", headfile_name, strerror(errno)); 73 } 74 75 (void) snprintf(mapfile_name, sizeof (mapfile_name), "%s-vers", 76 db_get_output_file()); 77 78 if ((Mapfp = fopen(mapfile_name, "w")) == NULL) { 79 errlog(FATAL, "%s: %s", mapfile_name, strerror(errno)); 80 } 81 (void) fputs("SUNWabi_1.1 {\n global:\n", Mapfp); 82 83 /* Now the Body file, which is an ephemeral temp-file. */ 84 if ((body_file_name = tempnam(dir, NULL)) == NULL) { 85 errlog(FATAL, "out of memory creating a temp-file name"); 86 } 87 88 if ((Bodyfp = fopen(body_file_name, "w+")) == NULL) { 89 errlog(FATAL, "%s: %s", body_file_name, strerror(errno)); 90 } 91 92 if (unlink(body_file_name) != 0) { 93 errlog(FATAL, "unlink %s: %s", body_file_name, strerror(errno)); 94 } 95 96 (void) free(body_file_name); 97 errlog(END, "}"); 98 return (rc); 99 } 100 101 /* 102 * abort_code_file -- close and discard files. 103 * this function is also called from alt_code_file, so 104 * it is not cool to unlink the code file or the mapfile 105 */ 106 static void 107 abort_code_file(void) 108 { 109 errlog(BEGIN, "abort_code_file() {"); 110 (void) fclose(Bodyfp); 111 (void) fclose(Headfp); 112 if (unlink(headfile_name) != 0) { 113 errlog(FATAL, "unlink %s: %s", headfile_name, strerror(errno)); 114 } 115 errlog(END, "}"); 116 } 117 118 int 119 alt_code_file(void) 120 { 121 char hfn[MAXLINE]; 122 FILE *hfp; 123 124 abort_code_file(); 125 (void) snprintf(hfn, sizeof (hfn), "%s.c", db_get_output_file()); 126 if ((hfp = fopen(hfn, "w")) == NULL) { 127 errlog(FATAL, "%s: %s", headfile_name, strerror(errno)); 128 } 129 130 (void) fputs("static int __abi_place_holder;\n", hfp); 131 (void) fclose(hfp); 132 133 return (YES); 134 } 135 136 /* 137 * commit_code_file -- close and commit files that have advanced 138 * beyond byte position 0. 139 */ 140 int 141 commit_code_file(void) 142 { 143 char copy_buffer[BUFSIZ*8]; 144 size_t n; 145 146 errlog(BEGIN, "commit_code_file() {"); 147 /* 148 * We unconditionally want a .pf and a -vers file 149 */ 150 (void) fputs(" local:\n\t*;\n};\n", Mapfp); 151 if (fclose(Mapfp) != 0) { 152 errlog(FATAL, "fclose %s: %s", mapfile_name, strerror(errno)); 153 } 154 if (ftell(Bodyfp) == 0) { 155 /* 156 * special case, redo C file with place holder 157 * so that makefiles won't break... 158 */ 159 errlog(END, "}"); 160 return (alt_code_file()); 161 } else { 162 /* Concatenate body file to head file, close both. */ 163 rewind(Bodyfp); 164 while ((n = fread(copy_buffer, 1, 165 sizeof (copy_buffer), Bodyfp)) != 0) { 166 (void) fwrite(copy_buffer, 1, n, Headfp); 167 } 168 (void) fclose(Bodyfp); 169 if (fclose(Headfp) != 0) { 170 errlog(FATAL, "fclose <temp file>: %s", 171 strerror(errno)); 172 } 173 } 174 175 errlog(END, "}"); 176 return (YES); 177 } 178