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]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
25 #pragma ident "%Z%%M% %I% %E% SMI"
27 #include <sys/types.h>
42 * Having gathered together any dependencies, dldump(3x) any necessary images.
44 * All dldump(3x) processing is carried out from the audit library. The
45 * temporary configuration file is read and all alternative marked files are
46 * dumped. If a -E application requires RTLD_REL_EXEC then that application
47 * acts as the new process, otherwise lddstub is used.
49 * Besides dldump(3x)'ing any images the audit library returns the address
50 * range of the images which will used to update the configuration file.
53 dump(Crle_desc
* crle
)
55 const char *orgapp
= (const char *)crle
->c_app
;
59 orgapp
= conv_lddstub(M_CLASS
);
62 * Set up a pipe through which the audit library will write the image
65 if (pipe(fildes
) == -1) {
67 (void) fprintf(stderr
, MSG_INTL(MSG_SYS_PIPE
),
68 crle
->c_name
, strerror(err
));
73 * Fork ourselves to run the application and collect its dependencies.
75 if ((pid
= fork()) == -1) {
77 (void) fprintf(stderr
, MSG_INTL(MSG_SYS_FORK
),
78 crle
->c_name
, strerror(err
));
84 * Parent. Read memory range entries from the audit library.
85 * The read side of the pipe is attached to stdio to make
86 * obtaining the individual dependencies easier.
88 int error
= 0, status
;
90 char buffer
[PATH_MAX
];
92 (void) close(fildes
[1]);
93 if ((fd
= fdopen(fildes
[0], MSG_ORIG(MSG_STR_READ
))) != NULL
) {
95 Rtc_head
*rtc
= (Rtc_head
*)crle
->c_tempheadaddr
;
97 while (fgets(buffer
, PATH_MAX
, fd
) != NULL
) {
99 * Make sure we recognize the message, remove
100 * the newline (which allowed fgets() use) and
101 * register the memory range entry;
103 if (strncmp(MSG_ORIG(MSG_AUD_PRF
), buffer
,
107 str
= strrchr(buffer
, '\n');
109 str
= buffer
+ MSG_AUD_PRF_SIZE
;
111 if (strncmp(MSG_ORIG(MSG_AUD_RESBGN
),
112 str
, MSG_AUD_RESBGN_SIZE
) == 0) {
114 strtoull(str
+ MSG_AUD_RESBGN_SIZE
,
116 } else if (strncmp(MSG_ORIG(MSG_AUD_RESEND
),
117 str
, MSG_AUD_RESEND_SIZE
) == 0) {
119 strtoull(str
+ MSG_AUD_RESEND_SIZE
,
129 while (wait(&status
) != pid
)
132 if (WIFSIGNALED(status
)) {
133 (void) fprintf(stderr
,
134 MSG_INTL(MSG_SYS_EXEC
), crle
->c_name
,
135 orgapp
, (WSIGMASK
& status
),
136 ((status
& WCOREFLG
) ?
137 MSG_INTL(MSG_SYS_CORE
) :
138 MSG_ORIG(MSG_STR_EMPTY
)));
144 char efds
[MSG_ENV_AUD_FD_SIZE
+ 10];
145 char eflg
[MSG_ENV_AUD_FLAGS_SIZE
+ 10];
148 (void) close(fildes
[0]);
151 * Child. Set up environment variables to enable and identify
154 (void) snprintf(efds
, (MSG_ENV_AUD_FD_SIZE
+ 10),
155 MSG_ORIG(MSG_ENV_AUD_FD
), fildes
[1]);
156 (void) snprintf(eflg
, (MSG_ENV_AUD_FLAGS_SIZE
+ 10),
157 MSG_ORIG(MSG_ENV_AUD_FLAGS
), crle
->c_dlflags
);
158 (void) snprintf(ecnf
, PATH_MAX
, MSG_ORIG(MSG_ENV_LD_CONFIG
),
162 * Put strings in the environment for exec().
163 * NOTE, use of automatic variables for construction of the
164 * environment variables is legitimate here, as they are local
165 * to the child process and are established solely for exec().
167 if ((putenv(efds
) != 0) || (putenv(eflg
) != 0) ||
168 (putenv(ecnf
) != 0) || (putenv(crle
->c_audit
) != 0) ||
169 (putenv((char *)MSG_ORIG(MSG_ENV_LD_FLAGS
)) != 0)) {
171 (void) fprintf(stderr
, MSG_INTL(MSG_SYS_PUTENV
),
172 crle
->c_name
, strerror(err
));
176 if (execlp(orgapp
, orgapp
, 0) == -1) {
178 (void) fprintf(stderr
, MSG_INTL(MSG_SYS_EXECLP
),
179 crle
->c_name
, orgapp
, strerror(err
));