Init
This commit is contained in:
117
bin/ldd.c
Normal file
117
bin/ldd.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/* @(#)ldd.c 1.1 94/10/31 SMI */
|
||||
|
||||
/*
|
||||
* List Dynamic Dependencies
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <a.out.h>
|
||||
#include <link.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/file.h>
|
||||
|
||||
char *nargv[] = {0, 0}; /* dummy argument vector */
|
||||
|
||||
char *malloc(); /* malloc return value */
|
||||
|
||||
main(argc, argv, envp)
|
||||
int argc; /* count of arguments */
|
||||
char *argv[]; /* argument values */
|
||||
char *envp[]; /* array of environment strings */
|
||||
{
|
||||
unsigned int i, j; /* general temporaries */
|
||||
int fd; /* file descriptor on targets */
|
||||
int pid; /* child process id */
|
||||
char **nenvp; /* new environment */
|
||||
struct exec exec; /* template for inspecting target */
|
||||
union wait status; /* dummy for wait() */
|
||||
struct exec a;
|
||||
|
||||
/*
|
||||
* Initial sanity check.
|
||||
*/
|
||||
if (argc <= 1) {
|
||||
(void) fprintf(stderr, "Usage: ldd file ... \n");
|
||||
exit(1);
|
||||
}
|
||||
(void) setlinebuf(stdout);
|
||||
(void) setlinebuf(stderr);
|
||||
|
||||
/*
|
||||
* Add an environment variable. Count the number of existing
|
||||
* ones, and then allocate up a new vector of environment strings
|
||||
* and add ours to it.
|
||||
*/
|
||||
for (i = 0; envp[i]; i++)
|
||||
;
|
||||
if ((nenvp = (char **)malloc((i + 2) * sizeof (char *))) == NULL) {
|
||||
perror("ldd: out of memory for environment");
|
||||
exit(1);
|
||||
}
|
||||
nenvp[0] = "LD_TRACE_LOADED_OBJECTS=placeholder";
|
||||
for (j = 0; j < (i + 1); j++)
|
||||
nenvp[j + 1] = envp[j];
|
||||
|
||||
/*
|
||||
* For each argument, examine it and determine if it is an
|
||||
* executable with a __DYNAMIC structure and an entry point.
|
||||
* If it is, simply execute it and let the dynamic linker
|
||||
* report its status.
|
||||
*/
|
||||
for (i = 1; i < argc; i++) {
|
||||
if ((fd = open(argv[i], O_RDONLY)) == -1) {
|
||||
fprintf(stderr, "ldd: %s unreadable: ", argv[1]);
|
||||
perror("");
|
||||
continue;
|
||||
}
|
||||
j = read(fd, (char *)&exec, sizeof (struct exec));
|
||||
(void) close(fd);
|
||||
if (j != sizeof (struct exec)) {
|
||||
(void) fprintf(stderr, "ldd: %s: not an executable\n",
|
||||
argv[i]);
|
||||
continue;
|
||||
}
|
||||
if (N_BADMAG(exec)) {
|
||||
(void) fprintf(stderr, "ldd: %s: not an executable\n",
|
||||
argv[i]);
|
||||
continue;
|
||||
}
|
||||
if (!exec.a_dynamic) {
|
||||
(void) printf("%s: statically linked\n", argv[i]);
|
||||
continue;
|
||||
}
|
||||
if (exec.a_entry == 0) {
|
||||
(void) fprintf("%s: not an executable\n", argv[i]);
|
||||
continue;
|
||||
}
|
||||
if ((pid = fork()) == 0) {
|
||||
if (argc > 2)
|
||||
(void) printf("%s:\n", argv[i]);
|
||||
execve(argv[i], nargv, nenvp);
|
||||
(void) fprintf(stderr,
|
||||
"ldd: %s execution failed: ", argv[i]);
|
||||
perror("");
|
||||
continue;
|
||||
} else
|
||||
if (pid != -1) {
|
||||
while (wait(&status) != pid)
|
||||
;
|
||||
if (status.w_T.w_Termsig)
|
||||
(void) fprintf(stderr,
|
||||
"ldd: %s execution failed due to signal %d %s\n",
|
||||
argv[i],
|
||||
status.w_T.w_Termsig,
|
||||
status.w_T.w_Coredump ?
|
||||
"(core dumped)" : "");
|
||||
else if (status.w_T.w_Retcode)
|
||||
(void) printf(stderr,
|
||||
"ldd: %s execution failed: exit status %d\n",
|
||||
argv[i],
|
||||
status.w_T.w_Retcode);
|
||||
} else
|
||||
perror("ldd: fork() failed");
|
||||
}
|
||||
exit(0);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
Reference in New Issue
Block a user