diff options
| author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 | 
| commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
| tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/um/os-Linux/process.c | |
| download | olio-linux-3.10-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.xz olio-linux-3.10-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.zip  | |
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/um/os-Linux/process.c')
| -rw-r--r-- | arch/um/os-Linux/process.c | 171 | 
1 files changed, 171 insertions, 0 deletions
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c new file mode 100644 index 00000000000..ba9ca1cc790 --- /dev/null +++ b/arch/um/os-Linux/process.c @@ -0,0 +1,171 @@ +/*  + * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com) + * Licensed under the GPL + */ + +#include <unistd.h> +#include <stdio.h> +#include <errno.h> +#include <signal.h> +#include <linux/unistd.h> +#include <sys/mman.h> +#include <sys/wait.h> +#include "ptrace_user.h" +#include "os.h" +#include "user.h" +#include "user_util.h" + +#define ARBITRARY_ADDR -1 +#define FAILURE_PID    -1 + +#define STAT_PATH_LEN sizeof("/proc/#######/stat\0") +#define COMM_SCANF "%*[^)])" + +unsigned long os_process_pc(int pid) +{ +	char proc_stat[STAT_PATH_LEN], buf[256]; +	unsigned long pc; +	int fd, err; + +	sprintf(proc_stat, "/proc/%d/stat", pid); +	fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0); +	if(fd < 0){ +		printk("os_process_pc - couldn't open '%s', err = %d\n", +		       proc_stat, -fd); +		return(ARBITRARY_ADDR); +	} +	err = os_read_file(fd, buf, sizeof(buf)); +	if(err < 0){ +		printk("os_process_pc - couldn't read '%s', err = %d\n", +		       proc_stat, -err); +		os_close_file(fd); +		return(ARBITRARY_ADDR); +	} +	os_close_file(fd); +	pc = ARBITRARY_ADDR; +	if(sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d " +		  "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d " +		  "%*d %*d %*d %*d %*d %lu", &pc) != 1){ +		printk("os_process_pc - couldn't find pc in '%s'\n", buf); +	} +	return(pc); +} + +int os_process_parent(int pid) +{ +	char stat[STAT_PATH_LEN]; +	char data[256]; +	int parent, n, fd; + +	if(pid == -1) return(-1); + +	snprintf(stat, sizeof(stat), "/proc/%d/stat", pid); +	fd = os_open_file(stat, of_read(OPENFLAGS()), 0); +	if(fd < 0){ +		printk("Couldn't open '%s', err = %d\n", stat, -fd); +		return(FAILURE_PID); +	} + +	n = os_read_file(fd, data, sizeof(data)); +	os_close_file(fd); + +	if(n < 0){ +		printk("Couldn't read '%s', err = %d\n", stat, -n); +		return(FAILURE_PID); +	} + +	parent = FAILURE_PID; +	n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent); +	if(n != 1) +		printk("Failed to scan '%s'\n", data); + +	return(parent); +} + +void os_stop_process(int pid) +{ +	kill(pid, SIGSTOP); +} + +void os_kill_process(int pid, int reap_child) +{ +	kill(pid, SIGKILL); +	if(reap_child) +		CATCH_EINTR(waitpid(pid, NULL, 0)); +		 +} + +/* Kill off a ptraced child by all means available.  kill it normally first, + * then PTRACE_KILL it, then PTRACE_CONT it in case it's in a run state from + * which it can't exit directly. + */ + +void os_kill_ptraced_process(int pid, int reap_child) +{ +	kill(pid, SIGKILL); +	ptrace(PTRACE_KILL, pid); +	ptrace(PTRACE_CONT, pid); +	if(reap_child) +		CATCH_EINTR(waitpid(pid, NULL, 0)); +} + +void os_usr1_process(int pid) +{ +	kill(pid, SIGUSR1); +} + +/*Don't use the glibc version, which caches the result in TLS. It misses some + * syscalls, and also breaks with clone(), which does not unshare the TLS.*/ +inline _syscall0(pid_t, getpid) + +int os_getpid(void) +{ +	return(getpid()); +} + +int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, +		  int r, int w, int x) +{ +	void *loc; +	int prot; + +	prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |  +		(x ? PROT_EXEC : 0); + +	loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, +		     fd, off); +	if(loc == MAP_FAILED) +		return(-errno); +	return(0); +} + +int os_protect_memory(void *addr, unsigned long len, int r, int w, int x) +{ +        int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |  +		    (x ? PROT_EXEC : 0)); + +        if(mprotect(addr, len, prot) < 0) +		return(-errno); +        return(0); +} + +int os_unmap_memory(void *addr, int len) +{ +        int err; + +        err = munmap(addr, len); +	if(err < 0) +		return(-errno); +        return(0); +} + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only.  This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */  |