Alexandre Julliard : server: Added process control support using / proc on Solaris.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Mar 9 07:28:28 CST 2007


Module: wine
Branch: master
Commit: f2792521896ff3b56fea3583044404c73bd09c18
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f2792521896ff3b56fea3583044404c73bd09c18

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Mar  9 13:40:41 2007 +0100

server: Added process control support using /proc on Solaris.

---

 server/Makefile.in |    1 +
 server/process.h   |    2 +
 server/procfs.c    |  181 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 184 insertions(+), 0 deletions(-)

diff --git a/server/Makefile.in b/server/Makefile.in
index 50d3530..bfd5c31 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -32,6 +32,7 @@ C_SRCS = \
 	named_pipe.c \
 	object.c \
 	process.c \
+	procfs.c \
 	ptrace.c \
 	queue.c \
 	region.c \
diff --git a/server/process.h b/server/process.h
index 11a7d93..6f39240 100644
--- a/server/process.h
+++ b/server/process.h
@@ -133,6 +133,8 @@ extern void enum_processes( int (*cb)(struct process*, void*), void *user);
 /* process tracing mechanism to use */
 #ifdef __APPLE__
 #define USE_MACH
+#elif defined(__sun)
+#define USE_PROCFS
 #else
 #define USE_PTRACE
 #endif
diff --git a/server/procfs.c b/server/procfs.c
new file mode 100644
index 0000000..b15bfcd
--- /dev/null
+++ b/server/procfs.c
@@ -0,0 +1,181 @@
+/*
+ * Server-side /proc support for Solaris
+ *
+ * Copyright (C) 2007 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "winternl.h"
+
+#include "file.h"
+#include "process.h"
+#include "thread.h"
+
+#ifdef USE_PROCFS
+
+#include <procfs.h>
+
+static int open_proc_as( struct process *process, int flags )
+{
+    char buffer[32];
+    int fd;
+
+    sprintf( buffer, "/proc/%u/as", process->unix_pid );
+    if ((fd = open( buffer, flags )) == -1) file_set_error();
+    return fd;
+}
+
+static int open_proc_lwpctl( struct thread *thread )
+{
+    char buffer[48];
+    int fd;
+
+    sprintf( buffer, "/proc/%u/lwp/%u/lwpctl", thread->unix_pid, thread->unix_tid );
+    if ((fd = open( buffer, O_WRONLY )) == -1) file_set_error();
+    return fd;
+}
+
+
+/* handle a SIGCHLD signal */
+void sigchld_callback(void)
+{
+    assert( 0 );  /* should only be called when using ptrace */
+}
+
+/* initialize the process tracing mechanism */
+void init_tracing_mechanism(void)
+{
+    /* no initialization needed */
+}
+
+/* initialize the per-process tracing mechanism */
+void init_process_tracing( struct process *process )
+{
+    /* setup is done on-demand */
+}
+
+/* terminate the per-process tracing mechanism */
+void finish_process_tracing( struct process *process )
+{
+}
+
+/* send a Unix signal to a specific thread */
+int send_thread_signal( struct thread *thread, int sig )
+{
+    int fd = open_proc_lwpctl( thread );
+    long kill[2];
+    ssize_t ret;
+
+    if (fd == -1) return 0;
+
+    kill[0] = PCKILL;
+    kill[1] = sig;
+    ret = write( fd, kill, sizeof(kill) );
+    close( fd );
+    return (ret == sizeof(kill));
+}
+
+/* read data from a process memory space */
+int read_process_memory( struct process *process, const void *ptr, size_t size, char *dest )
+{
+    ssize_t ret;
+    int fd = open_proc_as( process, O_RDONLY );
+
+    if (fd == -1) return 0;
+
+    ret = pread( fd, dest, size, (off_t)ptr );
+    close( fd );
+    if (ret == size) return 1;
+
+    if (ret == -1) file_set_error();
+    else set_error( STATUS_ACCESS_VIOLATION );
+    return 0;
+}
+
+/* write data to a process memory space */
+int write_process_memory( struct process *process, void *ptr, size_t size, const char *src )
+{
+    ssize_t ret;
+    int fd = open_proc_as( process, O_WRONLY );
+
+    if (fd == -1) return 0;
+
+    ret = pwrite( fd, src, size, (off_t)ptr );
+    close( fd );
+    if (ret == size) return 1;
+
+    if (ret == -1) file_set_error();
+    else set_error( STATUS_ACCESS_VIOLATION );
+    return 0;
+}
+
+/* retrieve an LDT selector entry */
+void get_selector_entry( struct thread *thread, int entry, unsigned int *base,
+                         unsigned int *limit, unsigned char *flags )
+{
+    ssize_t ret;
+    off_t pos = (off_t)thread->process->ldt_copy;
+    int fd = open_proc_as( thread->process, O_RDONLY );
+
+    if (fd == -1) return;
+
+    ret = pread( fd, base, sizeof(*base), pos + entry*sizeof(int) );
+    if (ret != sizeof(*base)) goto error;
+    ret = pread( fd, limit, sizeof(*limit), pos + (8192 + entry)*sizeof(int) );
+    if (ret != sizeof(*limit)) goto error;
+    ret = pread( fd, flags, sizeof(*flags), pos + 2*8192*sizeof(int) + entry );
+    if (ret != sizeof(*flags)) goto error;
+    close( fd );
+    return;
+
+error:
+    if (ret == -1) file_set_error();
+    else set_error( STATUS_ACCESS_VIOLATION );
+    close( fd );
+}
+
+/* retrieve the thread registers */
+void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int flags )
+{
+    /* all other regs are handled on the client side */
+    assert( (flags | CONTEXT_i386) == CONTEXT_DEBUG_REGISTERS );
+
+    /* FIXME: get debug registers */
+}
+
+/* set the thread registers */
+void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned int flags )
+{
+    /* all other regs are handled on the client side */
+    assert( (flags | CONTEXT_i386) == CONTEXT_DEBUG_REGISTERS );
+
+    /* FIXME: set debug registers */
+}
+
+#endif /* USE_PROCFS */




More information about the wine-cvs mailing list