summaryrefslogtreecommitdiffstats
path: root/lib/libproc/proc_create.c
diff options
context:
space:
mode:
authorrpaulo <rpaulo@FreeBSD.org>2010-07-31 16:10:20 +0000
committerrpaulo <rpaulo@FreeBSD.org>2010-07-31 16:10:20 +0000
commita049970caad5cf461ceb13d4b2fcd914b2af24f1 (patch)
tree30c1af86897f11bb9ea43da0c92ec31dbecd1c50 /lib/libproc/proc_create.c
parentf5ec1d3118207f2f24806692cce1f78fff6d53d3 (diff)
downloadFreeBSD-src-a049970caad5cf461ceb13d4b2fcd914b2af24f1.zip
FreeBSD-src-a049970caad5cf461ceb13d4b2fcd914b2af24f1.tar.gz
New version of libproc. Changes are:
* breakpoint setup support * register query * symbol to address mapping and vice-versa * more misc utility functions based on their Solaris counterpart Also, I've written some test cases. Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'lib/libproc/proc_create.c')
-rw-r--r--lib/libproc/proc_create.c61
1 files changed, 28 insertions, 33 deletions
diff --git a/lib/libproc/proc_create.c b/lib/libproc/proc_create.c
index 1649b47..b30a77b 100644
--- a/lib/libproc/proc_create.c
+++ b/lib/libproc/proc_create.c
@@ -27,6 +27,7 @@
*/
#include "_libproc.h"
+#include <stdio.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
@@ -40,11 +41,10 @@ int
proc_attach(pid_t pid, int flags, struct proc_handle **pphdl)
{
struct proc_handle *phdl;
- struct kevent kev;
int error = 0;
int status;
- if (pid == 0 || pphdl == NULL)
+ if (pid == 0 || pid == getpid())
return (EINVAL);
/*
@@ -58,26 +58,24 @@ proc_attach(pid_t pid, int flags, struct proc_handle **pphdl)
phdl->pid = pid;
phdl->flags = flags;
phdl->status = PS_RUN;
+ elf_version(EV_CURRENT);
- EV_SET(&kev, pid, EVFILT_PROC, EV_ADD | EV_ONESHOT, NOTE_EXIT,
- 0, NULL);
-
- if ((phdl->kq = kqueue()) == -1)
- err(1, "ERROR: cannot create kernel evet queue");
-
- if (kevent(phdl->kq, &kev, 1, NULL, 0, NULL) < 0)
- err(2, "ERROR: cannot monitor child process %d", pid);
-
- if (ptrace(PT_ATTACH, phdl->pid, NULL, 0) != 0)
+ if (ptrace(PT_ATTACH, phdl->pid, 0, 0) != 0) {
error = errno;
+ DPRINTF("ERROR: cannot ptrace child process %d", pid);
+ goto out;
+ }
/* Wait for the child process to stop. */
- else if (waitpid(pid, &status, WUNTRACED) == -1)
- err(3, "ERROR: child process %d didn't stop as expected", pid);
+ if (waitpid(pid, &status, WUNTRACED) == -1) {
+ error = errno;
+ DPRINTF("ERROR: child process %d didn't stop as expected", pid);
+ goto out;
+ }
/* Check for an unexpected status. */
- else if (WIFSTOPPED(status) == 0)
- err(4, "ERROR: child process %d status 0x%x", pid, status);
+ if (WIFSTOPPED(status) == 0)
+ DPRINTF("ERROR: child process %d status 0x%x", pid, status);
else
phdl->status = PS_STOP;
@@ -85,6 +83,7 @@ proc_attach(pid_t pid, int flags, struct proc_handle **pphdl)
proc_free(phdl);
else
*pphdl = phdl;
+out:
return (error);
}
@@ -94,7 +93,6 @@ proc_create(const char *file, char * const *argv, proc_child_func *pcf,
void *child_arg, struct proc_handle **pphdl)
{
struct proc_handle *phdl;
- struct kevent kev;
int error = 0;
int status;
pid_t pid;
@@ -106,6 +104,8 @@ proc_create(const char *file, char * const *argv, proc_child_func *pcf,
if ((phdl = malloc(sizeof(struct proc_handle))) == NULL)
return (ENOMEM);
+ elf_version(EV_CURRENT);
+
/* Fork a new process. */
if ((pid = vfork()) == -1)
error = errno;
@@ -128,31 +128,26 @@ proc_create(const char *file, char * const *argv, proc_child_func *pcf,
phdl->pid = pid;
phdl->status = PS_IDLE;
- EV_SET(&kev, pid, EVFILT_PROC, EV_ADD | EV_ONESHOT, NOTE_EXIT,
- 0, NULL);
-
- if ((phdl->kq = kqueue()) == -1)
- err(1, "ERROR: cannot create kernel evet queue");
-
- if (kevent(phdl->kq, &kev, 1, NULL, 0, NULL) < 0)
- err(2, "ERROR: cannot monitor child process %d", pid);
-
/* Wait for the child process to stop. */
- if (waitpid(pid, &status, WUNTRACED) == -1)
- err(3, "ERROR: child process %d didn't stop as expected", pid);
+ if (waitpid(pid, &status, WUNTRACED) == -1) {
+ error = errno;
+ DPRINTF("ERROR: child process %d didn't stop as expected", pid);
+ goto bad;
+ }
/* Check for an unexpected status. */
- if (WIFSTOPPED(status) == 0)
- err(4, "ERROR: child process %d status 0x%x", pid, status);
- else
+ if (WIFSTOPPED(status) == 0) {
+ error = errno;
+ DPRINTF("ERROR: child process %d status 0x%x", pid, status);
+ goto bad;
+ } else
phdl->status = PS_STOP;
}
-
+bad:
if (error)
proc_free(phdl);
else
*pphdl = phdl;
-
return (error);
}
OpenPOWER on IntegriCloud