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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 1998 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25 /*
26 * @(#)ld_file.c 1.7 06/12/12
27 */
28 #pragma ident "@(#)ld_file.c 1.7 06/12/12"
29
30 #pragma init(ld_support_init)
31
32 #include <stdio.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <libelf.h>
37 #include <sys/param.h>
38 #include <link.h>
39
40 #define SUNPRO_DEPENDENCIES "SUNPRO_DEPENDENCIES"
41
42 /*
43 * Linked list of strings - used to keep lists of names
44 * of directories or files.
45 */
46
47 struct Stritem {
48 char * str;
49 void * next;
50 };
51
52 typedef struct Stritem Stritem;
53
54 static char * depend_file = NULL;
55 static Stritem * list = NULL;
56
57
58 void mk_state_init()
59 {
60 depend_file = getenv(SUNPRO_DEPENDENCIES);
61 } /* mk_state_init() */
62
63
64
65 static void
66 prepend_str(Stritem **list, const char * str)
67 {
68 Stritem * new;
69 char * newstr;
70
71 if (!(new = calloc(1, sizeof (Stritem)))) {
72 perror("libmakestate.so");
73 return;
74 } /* if */
75
76 if (!(newstr = malloc(strlen(str) + 1))) {
77 perror("libmakestate.so");
78 return;
79 } /* if */
80
81 new->str = strcpy(newstr, str);
82 new->next = *list;
83 *list = new;
84
85 } /* prepend_str() */
86
87
88 void
89 mk_state_collect_dep(const char * file)
90 {
91 /*
92 * SUNPRO_DEPENDENCIES wasn't set, we don't collect .make.state
93 * information.
94 */
95 if (!depend_file)
96 return;
97
98 prepend_str(&list, file);
99
100 } /* mk_state_collect_dep() */
101
102
103 void
104 mk_state_update_exit()
105 {
106 Stritem * cur;
107 char lockfile[MAXPATHLEN], * err, * space, * target;
108 FILE * ofp;
109 extern char * file_lock(char *, char *, int);
110
111 if (!depend_file)
112 return;
113
114 if ((space = strchr(depend_file, ' ')) == NULL)
115 return;
116 *space = '\0';
117 target = &space[1];
118
119 (void) sprintf(lockfile, "%s.lock", depend_file);
120 if ((err = file_lock(depend_file, lockfile, 0))) {
121 (void) fprintf(stderr, "%s\n", err);
122 return;
123 } /* if */
124
125 if (!(ofp = fopen(depend_file, "a")))
126 return;
127
128 if (list)
129 (void) fprintf(ofp, "%s: ", target);
130
131 for (cur = list; cur; cur = cur->next)
132 (void) fprintf(ofp, " %s", cur->str);
133
134 (void) fputc('\n', ofp);
135
136 (void) fclose(ofp);
137 (void) unlink(lockfile);
138 *space = ' ';
139
140 } /* mk_state_update_exit() */
141
142 static void
143 /* LINTED static unused */
144 ld_support_init()
145 {
146 mk_state_init();
147
148 } /* ld_support_init() */
149
150 /* ARGSUSED */
151 void
152 ld_file(const char * file, const Elf_Kind ekind, int flags, Elf *elf)
153 {
154 if(! ((flags & LD_SUP_DERIVED) && !(flags & LD_SUP_EXTRACTED)))
155 return;
156
157 mk_state_collect_dep(file);
158
159 } /* ld_file */
160
161 void
162 ld_atexit(int exit_code)
163 {
164 if (exit_code)
165 return;
166
167 mk_state_update_exit();
168
169 } /* ld_atexit() */
170
171 /*
172 * Supporting 64-bit objects
173 */
174 void
175 ld_file64(const char * file, const Elf_Kind ekind, int flags, Elf *elf)
176 {
177 if(! ((flags & LD_SUP_DERIVED) && !(flags & LD_SUP_EXTRACTED)))
178 return;
179
180 mk_state_collect_dep(file);
181
182 } /* ld_file64 */
183
184 void
185 ld_atexit64(int exit_code)
186 {
187 if (exit_code)
188 return;
189
190 mk_state_update_exit();
191
192 } /* ld_atexit64() */