/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1994, by Sun Microsytems, Inc.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* interfaces to exec a command and run it till all loadobjects have
* been loaded (rtld sync point).
*/
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include "prb_proc_int.h"
#include "dbg.h"
/*
* Defines
*/
/*
* Local declarations
*/
/*
* prb_child_create() - this routine instantiates and rendevous with the
* target child process. This routine returns an opaque handle for the
* childs /proc entry.
*/
const char *loption, const char *libtnfprobe_path,
{
extern char **environ;
char * const * env_to_use;
/* initialize shmem communication buffer to cause child to wait */
if (prbstat)
return (prbstat);
/* fork to create the child process */
return (prb_status_map(errno));
}
if (childpid == 0) {
char *oldenv;
char *newenv;
/* ---- CHILD PROCESS ---- */
"sunw%verbosity 1; sunw%debug 'child process created'",
if (envp) {
env_to_use = envp;
goto ContChild;
}
/* append libtnfprobe.so to the LD_PRELOAD environment */
/* probepathlen has a "/" added in ("+ 1") */
probepathlen = (libtnfprobe_path) ?
if (oldenv) {
1 + /* "=" */
1 + /* " " */
1 + /* " " */
loptlen +
1); /* NULL */
if (!newenv)
goto ContChild;
if (probepathlen) {
}
if (loptlen) {
}
} else {
1 + /* "=" */
1 + /* " " */
loptlen +
1); /* NULL */
if (!newenv)
goto ContChild;
if (probepathlen) {
}
if (loptlen) {
}
}
/*
* We don't check the return value of putenv because the
* desired libraries might already be in the target, even
* if our effort to change the environment fails. We
* should continue either way ...
*/
/* wait until the parent releases us */
(void) prb_shmem_wait(smp);
"sunw%verbosity 2; "
"sunw%debug 'child process about to exec'",
/*
* make the child it's own process group.
* This is so that signals delivered to parent are not
* also delivered to child.
*/
(void) setpgrp();
if (prbstat) {
/* parent waits for exit */
_exit(1);
}
_exit(1);
}
/* Never reached */
_exit(1);
}
/* ---- PARENT PROCESS ---- */
/* child is waiting for us */
if (prbstat) {
return (prbstat);
}
return (PRB_STATUS_OK);
}
/*
* interface that registers the address of the debug structure
* in the target process. This is where the linker maintains all
* the information about the loadobjects
*/
void
{
}
/*
* continue the child until the run time linker has loaded in all
* the loadobjects (rtld sync point)
*/
static prb_status_t
{
if (prbstat)
return (prbstat);
if (prbstat)
goto ret_failure;
/*
* default is to kill-on-last-close. In case we cannot sync with
* target, we don't want the target to continue.
*/
if (prbstat)
goto ret_failure;
if (prbstat)
goto ret_failure;
/* REMIND: do we have to wait on SYS_exec also ? */
if (prbstat)
goto ret_failure;
if (prbstat)
goto ret_failure;
if (prbstat)
goto ret_failure;
if (prbstat)
goto ret_failure;
switch (prbstat) {
case PRB_STATUS_OK:
break;
case EAGAIN:
/*
* will return EAGAIN. Reopen the 'fd' and try again.
* Read the last section of /proc man page - we reopen first
* and then close the old fd.
*/
if (tempstat) {
(void) prb_proc_close(oldproc_p);
return (tempstat);
}
(void) prb_proc_close(oldproc_p);
break;
default:
goto ret_failure;
}
if (prbstat)
goto ret_failure;
if (prbstat)
goto ret_failure;
/* expected condition */
} else {
goto ret_failure;
}
/* clear old interest mask */
if (prbstat)
goto ret_failure;
if (prbstat)
goto ret_failure;
/* Successful return */
return (PRB_STATUS_OK);
(void) prb_proc_close(proc_p);
return (prbstat);
}