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 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 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 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 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