summaryrefslogtreecommitdiff
path: root/proc_proxy
diff options
context:
space:
mode:
Diffstat (limited to 'proc_proxy')
-rw-r--r--proc_proxy/ChangeLog40
-rw-r--r--proc_proxy/Makefile36
-rw-r--r--proc_proxy/README26
-rw-r--r--proc_proxy/ourdevice.defs383
-rw-r--r--proc_proxy/proc_proxy.c276
-rw-r--r--proc_proxy/proc_proxy.h67
-rw-r--r--proc_proxy/process_ops.c453
-rw-r--r--proc_proxy/test.c7
8 files changed, 1288 insertions, 0 deletions
diff --git a/proc_proxy/ChangeLog b/proc_proxy/ChangeLog
new file mode 100644
index 00000000..c647bd15
--- /dev/null
+++ b/proc_proxy/ChangeLog
@@ -0,0 +1,40 @@
+2008-08-29 Zheng Da <zhengda1936@gmail.com>
+
+ * README: Update.
+
+2008-08-29 Zheng Da <zhengda1936@gmail.com>
+
+ * Makefile: Add process_ops.c
+
+ * proc_proxy.c (master_port, args_doc, doc, options): New variables.
+ (reqport_find): Remove debugging print.
+ (comm_argv, comm_argc): New variables.
+ (add_comm_arg, add_comm_line, parse_opt): New functions.
+ (argp): New variable.
+ (main): Parse the options with argp.
+
+ * proc_proxy.h (DEBUG): Removed macro.
+
+ * process_ops.c (S_proc_getprivports): Return the master device port.
+
+2008-08-18 Zheng Da <zhengda1936@gmail.com>
+
+ * README: New file.
+
+2008-08-17 Zheng Da <zhengda1936@gmail.com>
+
+ * process.defs: Remove file.
+
+ * process_ops.c: Replace the server prefix with the default one "S_".
+
+2008-08-17 Zheng Da <zhengda1936@gmail.com>
+
+ * process.defs: New file.
+
+ * Makefile: New file.
+
+ * process_ops.c: New file.
+
+ * proc_proxy.c: New file.
+
+ * proc_proxy.h: New file.
diff --git a/proc_proxy/Makefile b/proc_proxy/Makefile
new file mode 100644
index 00000000..60ce1758
--- /dev/null
+++ b/proc_proxy/Makefile
@@ -0,0 +1,36 @@
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 2008 Free Software Foundation, Inc.
+# This file is part of the GNU Hurd.
+#
+# The GNU Hurd is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# The GNU Hurd 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with the GNU Hurd; see the file COPYING. If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+dir := proc_proxy
+makemode := server
+
+SRCS = proc_proxy.c process_ops.c
+LCLHDRS = proc_proxy.h
+DIST_FILES = process.defs
+HURDLIBS = threads ports
+target = proc_proxy
+MIGSTUBS = processServer.o
+OBJS = $(SRCS:.c=.o) $(MIGSTUBS)
+
+MIGSFLAGS="-DPROCESS_INTRAN=vpstruct_t reqport_find (process_t)" \
+ "-DPROCESS_DESTRUCTOR=process_drop (vpstruct_t)" \
+ "-DPROCESS_IMPORTS=import \"proc_proxy.h\";"
+
+include ../Makeconf
+
+my_processUser.c: processUser.c
+ cat $< | sed -e '/__mig_get_reply_port *( *)/s/__mig_get_reply_port/my_get_reply_port/' > $@;
diff --git a/proc_proxy/README b/proc_proxy/README
new file mode 100644
index 00000000..83e11691
--- /dev/null
+++ b/proc_proxy/README
@@ -0,0 +1,26 @@
+[Introduction]
+
+proc_proxy is a proxy for the proc server. It intercepts the PROCESS requests that should be sent from a user to his proc server, so it provides a possibility for us to tamper the reply or even create the reply at our will.
+
+The current implementation of proc_proxy is able to help the pfinet translator open the virtual interface created by eth-multiplexer.
+
+
+[Usage]
+
+Usage: proc_proxy [OPTION...] command line
+Hurd proc proxy
+
+ -M, --master-device=FILE Get the pseudo master device from a translator
+ -?, --help Give this help list
+ --usage Give a short usage message
+
+Mandatory or optional arguments to long options are also mandatory or optional for any corresponding short options.
+
+
+[Internal]
+
+proc_proxy implements the server-side functions in process.defs. In the beginning, proc_proxy forks a new process, set its child's process server to itself, and run the command in the child process. Therefore, proc_proxy can get all PROCESS reqeusts from its child.
+
+proc_proxy works in the same way as the proc server to distinguish different processes with their ports. proc_proxy creates a port for each process. When a request comes, reqport_find() is called on the port to find the corresponding process. The port created for a new task is in server-side proc_task2proc. When a proc_task2proc request for a new task comes, a new port is created for the task and the send right of the port is returned.
+
+In order to help pfinet open the virtual interface created by eth-multiplexer, proc_proxy returns the port to eth-multiplexer as a master device port to pfinet.
diff --git a/proc_proxy/ourdevice.defs b/proc_proxy/ourdevice.defs
new file mode 100644
index 00000000..ba9a2d80
--- /dev/null
+++ b/proc_proxy/ourdevice.defs
@@ -0,0 +1,383 @@
+# 1 "device.defs"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "device.defs"
+# 1 "/usr/include/device/device.defs" 1 3 4
+# 39 "/usr/include/device/device.defs" 3 4
+subsystem
+
+
+
+ device 2800;
+
+# 1 "/usr/include/mach/std_types.defs" 1 3 4
+# 33 "/usr/include/mach/std_types.defs" 3 4
+type char = MACH_MSG_TYPE_CHAR;
+type short = MACH_MSG_TYPE_INTEGER_16;
+type int = MACH_MSG_TYPE_INTEGER_32;
+type int32 = MACH_MSG_TYPE_INTEGER_32;
+type int64 = MACH_MSG_TYPE_INTEGER_64;
+type boolean_t = MACH_MSG_TYPE_BOOLEAN;
+type unsigned = MACH_MSG_TYPE_INTEGER_32;
+type unsigned32 = MACH_MSG_TYPE_INTEGER_32;
+type unsigned64 = MACH_MSG_TYPE_INTEGER_64;
+
+
+# 1 "/usr/include/mach/machine/machine_types.defs" 1 3 4
+# 50 "/usr/include/mach/machine/machine_types.defs" 3 4
+type natural_t = unsigned32;
+# 59 "/usr/include/mach/machine/machine_types.defs" 3 4
+type integer_t = int32;
+# 45 "/usr/include/mach/std_types.defs" 2 3 4
+
+type kern_return_t = int;
+
+type pointer_t = ^array[] of MACH_MSG_TYPE_BYTE
+ ctype: vm_offset_t;
+
+
+type mach_port_t = MACH_MSG_TYPE_COPY_SEND;
+type mach_port_array_t = array[] of mach_port_t;
+
+type mach_port_name_t = MACH_MSG_TYPE_PORT_NAME
+ ctype: mach_port_t;
+type mach_port_name_array_t = array[] of mach_port_name_t
+ ctype: mach_port_array_t;
+
+type mach_port_right_t = natural_t;
+
+type mach_port_type_t = natural_t;
+type mach_port_type_array_t = array[] of mach_port_type_t;
+
+type mach_port_urefs_t = natural_t;
+type mach_port_delta_t = integer_t;
+type mach_port_seqno_t = natural_t;
+type mach_port_mscount_t = unsigned;
+type mach_port_msgcount_t = unsigned;
+type mach_port_rights_t = unsigned;
+type mach_msg_id_t = integer_t;
+type mach_msg_type_name_t = unsigned;
+type mach_msg_type_number_t = natural_t;
+
+type mach_port_move_receive_t = MACH_MSG_TYPE_MOVE_RECEIVE
+ ctype: mach_port_t;
+type mach_port_copy_send_t = MACH_MSG_TYPE_COPY_SEND
+ ctype: mach_port_t;
+type mach_port_make_send_t = MACH_MSG_TYPE_MAKE_SEND
+ ctype: mach_port_t;
+type mach_port_move_send_t = MACH_MSG_TYPE_MOVE_SEND
+ ctype: mach_port_t;
+type mach_port_make_send_once_t = MACH_MSG_TYPE_MAKE_SEND_ONCE
+ ctype: mach_port_t;
+type mach_port_move_send_once_t = MACH_MSG_TYPE_MOVE_SEND_ONCE
+ ctype: mach_port_t;
+
+type mach_port_receive_t = MACH_MSG_TYPE_PORT_RECEIVE
+ ctype: mach_port_t;
+type mach_port_send_t = MACH_MSG_TYPE_PORT_SEND
+ ctype: mach_port_t;
+type mach_port_send_once_t = MACH_MSG_TYPE_PORT_SEND_ONCE
+ ctype: mach_port_t;
+
+type mach_port_poly_t = polymorphic
+ ctype: mach_port_t;
+
+import <mach/std_types.h>;
+# 46 "/usr/include/device/device.defs" 2 3 4
+# 1 "/usr/include/mach/mach_types.defs" 1 3 4
+# 61 "/usr/include/mach/mach_types.defs" 3 4
+type mach_port_status_t = struct[9] of integer_t;
+
+type old_mach_port_status_t = struct[8] of integer_t;
+
+type task_t = mach_port_t
+ ctype: mach_port_t
+
+
+
+
+
+ ;
+# 85 "/usr/include/mach/mach_types.defs" 3 4
+type thread_t = mach_port_t
+ ctype: mach_port_t
+
+
+
+
+
+ ;
+
+type thread_state_t = array[*:1024] of natural_t;
+
+type task_array_t = ^array[] of task_t;
+type thread_array_t = ^array[] of thread_t;
+
+type vm_task_t = mach_port_t
+ ctype: mach_port_t
+
+
+
+
+ ;
+
+type ipc_space_t = mach_port_t
+ ctype: mach_port_t
+
+
+
+
+ ;
+
+type vm_address_t = natural_t;
+type vm_offset_t = natural_t;
+type vm_size_t = natural_t;
+type vm_prot_t = int;
+type vm_inherit_t = int;
+type vm_statistics_data_t = struct[13] of integer_t;
+type vm_machine_attribute_t = int;
+type vm_machine_attribute_val_t = int;
+
+type thread_info_t = array[*:1024] of natural_t;
+type thread_basic_info_data_t = struct[11] of integer_t;
+type thread_sched_info_data_t = struct[7] of integer_t;
+
+type task_info_t = array[*:1024] of natural_t;
+type task_basic_info_data_t = struct[8] of integer_t;
+type task_events_info = struct[7] of natural_t;
+type task_thread_times_info_data_t = struct[4] of integer_t;
+
+
+type memory_object_t = mach_port_t
+ ctype: mach_port_t
+
+
+
+ ;
+
+type memory_object_control_t = mach_port_t
+ ctype: mach_port_t
+
+
+
+ ;
+
+type memory_object_name_t = mach_port_t
+ ctype: mach_port_t
+
+
+
+
+ ;
+
+type memory_object_copy_strategy_t = int;
+type memory_object_return_t = int;
+
+type machine_info_data_t = struct[5] of integer_t;
+type machine_slot_data_t = struct[8] of integer_t;
+
+type host_t = mach_port_t
+ ctype: mach_port_t
+
+
+
+
+ ;
+
+type host_priv_t = mach_port_t
+ ctype: mach_port_t
+
+
+
+ ;
+
+type host_info_t = array[*:1024] of natural_t;
+type host_basic_info_data_t = struct[5] of integer_t;
+type host_sched_info_data_t = struct[2] of integer_t;
+type host_load_info_data_t = struct[6] of integer_t;
+
+
+type processor_t = mach_port_t
+ ctype: mach_port_t
+
+
+
+
+ ;
+
+type processor_array_t = ^array[] of processor_t;
+type processor_info_t = array[*:1024] of natural_t;
+type processor_basic_info_data_t = struct[5] of integer_t;
+
+
+type processor_set_t = mach_port_t
+ ctype: mach_port_t
+
+
+
+
+
+ ;
+
+type processor_set_array_t = ^array[] of processor_set_t;
+
+type processor_set_name_t = mach_port_t
+ ctype: mach_port_t
+
+
+
+
+
+ ;
+
+type processor_set_name_array_t = ^array[] of processor_set_name_t;
+
+type processor_set_info_t = array[*:1024] of natural_t;
+type processor_set_basic_info_data_t = struct[5] of integer_t;
+type processor_set_sched_info_data_t = struct[2] of integer_t;
+
+
+type kernel_version_t = (MACH_MSG_TYPE_STRING, 512*8);
+
+type kernel_boot_info_t = (MACH_MSG_TYPE_STRING, 4096*8);
+
+type time_value_t = struct[2] of integer_t;
+
+type emulation_vector_t = ^array[] of vm_offset_t;
+
+type xxx_emulation_vector_t = array[*:1024] of vm_offset_t
+ ctype: emulation_vector_t;
+
+
+type rpc_signature_info_t = array[*:1024] of int;
+# 250 "/usr/include/mach/mach_types.defs" 3 4
+import <mach/mach_types.h>;
+# 47 "/usr/include/device/device.defs" 2 3 4
+# 1 "/usr/include/device/device_types.defs" 1 3 4
+# 42 "/usr/include/device/device_types.defs" 3 4
+type recnum_t = unsigned32;
+type dev_mode_t = unsigned32;
+type dev_flavor_t = unsigned32;
+type dev_name_t = (MACH_MSG_TYPE_STRING_C, 8*128);
+type dev_status_t = array[*:1024] of int;
+type io_buf_ptr_t = ^array[] of MACH_MSG_TYPE_INTEGER_8;
+type io_buf_ptr_inband_t= array[*:128] of char;
+type filter_t = short;
+type filter_array_t = array[*:128] of filter_t;
+
+type device_t = mach_port_t
+ ctype: mach_port_t
+
+
+
+
+
+ ;
+
+import <device/device_types.h>;
+import <device/net_status.h>;
+# 48 "/usr/include/device/device.defs" 2 3 4
+
+serverprefix ds_;
+
+type reply_port_t = MACH_MSG_TYPE_MAKE_SEND_ONCE | polymorphic
+ ctype: mach_port_t;
+
+routine device_open(
+ master_port : mach_port_t;
+ sreplyport reply_port : reply_port_t;
+ mode : dev_mode_t;
+ name : dev_name_t;
+ out device : mach_port_send_t
+ );
+
+routine device_close(
+ device : device_t
+ );
+
+routine device_write(
+ device : device_t;
+ sreplyport reply_port : reply_port_t;
+ in mode : dev_mode_t;
+ in recnum : recnum_t;
+ in data : io_buf_ptr_t;
+ out bytes_written : int
+ );
+
+routine device_write_inband(
+ device : device_t;
+ sreplyport reply_port : reply_port_t;
+ in mode : dev_mode_t;
+ in recnum : recnum_t;
+ in data : io_buf_ptr_inband_t;
+ out bytes_written : int
+ );
+
+routine device_read(
+ device : device_t;
+ sreplyport reply_port : reply_port_t;
+ in mode : dev_mode_t;
+ in recnum : recnum_t;
+ in bytes_wanted : int;
+ out data : io_buf_ptr_t
+ );
+
+routine device_read_inband(
+ device : device_t;
+ sreplyport reply_port : reply_port_t;
+ in mode : dev_mode_t;
+ in recnum : recnum_t;
+ in bytes_wanted : int;
+ out data : io_buf_ptr_inband_t
+ );
+
+
+routine xxx_device_set_status(
+ device : device_t;
+ in flavor : dev_flavor_t;
+ in status : dev_status_t, IsLong
+ );
+
+
+routine xxx_device_get_status(
+ device : device_t;
+ in flavor : dev_flavor_t;
+ out status : dev_status_t, IsLong
+ );
+
+
+routine xxx_device_set_filter(
+ device : device_t;
+ in receive_port : mach_port_send_t;
+ in priority : int;
+ in filter : filter_array_t, IsLong
+ );
+
+routine device_map(
+ device : device_t;
+ in prot : vm_prot_t;
+ in offset : vm_offset_t;
+ in size : vm_size_t;
+ out pager : memory_object_t;
+ in unmap : int
+ );
+
+routine device_set_status(
+ device : device_t;
+ in flavor : dev_flavor_t;
+ in status : dev_status_t
+ );
+
+routine device_get_status(
+ device : device_t;
+ in flavor : dev_flavor_t;
+ out status : dev_status_t, CountInOut
+ );
+
+routine device_set_filter(
+ device : device_t;
+ in receive_port : mach_port_send_t;
+ in priority : int;
+ in filter : filter_array_t
+ );
+# 1 "device.defs" 2
diff --git a/proc_proxy/proc_proxy.c b/proc_proxy/proc_proxy.c
new file mode 100644
index 00000000..c7878328
--- /dev/null
+++ b/proc_proxy/proc_proxy.c
@@ -0,0 +1,276 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+ Written by Zheng Da.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ The GNU Hurd 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the GNU Hurd; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <argp.h>
+#include <error.h>
+#include <syslog.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stddef.h>
+
+#include <hurd.h>
+#include <mach.h>
+
+#include "proc_proxy.h"
+
+struct port_bucket *proc_bucket;
+struct port_class *proc_class;
+
+mach_port_t master_port;
+
+static struct hurd_ihash proc_ht
+= HURD_IHASH_INITIALIZER (offsetof (struct vproc, p_task_hashloc));
+
+static char *args_doc = "command line";
+static char *doc = "Hurd proc proxy";
+static struct argp_option options[] =
+{
+ {"master-device", 'M', "FILE", 0, "Get the pseudo master device from a translator"},
+ { 0 }
+};
+
+vpstruct_t
+reqport_find (mach_port_t reqport)
+{
+ vpstruct_t p;
+ p = ports_lookup_port (proc_bucket, reqport, proc_class);
+ return p;
+}
+
+void
+task_clean_routine (void *port)
+{
+ vpstruct_t proc = port;
+ hurd_ihash_locp_remove (&proc_ht, proc->p_task_hashloc);
+ mach_port_deallocate (mach_task_self (), proc->proc);
+ mach_port_deallocate (mach_task_self (), proc->task_id);
+}
+
+vpstruct_t
+create_task (task_t task)
+{
+ vpstruct_t proc;
+ error_t err = ports_create_port (proc_class, proc_bucket,
+ sizeof (*proc), &proc);
+ if (err)
+ error (3, err, "ports_create_port");
+
+ proc->task_id = task;
+
+ hurd_ihash_add (&proc_ht, proc->task_id, proc);
+ return proc;
+}
+
+vpstruct_t
+find_task (task_t task)
+{
+ return hurd_ihash_find (&proc_ht, task) ? : create_task (task);
+}
+
+int
+request_server (mach_msg_header_t *inp, mach_msg_header_t *outp)
+{
+ extern boolean_t process_server (mach_msg_header_t *, mach_msg_header_t *);
+ return process_server (inp, outp);
+}
+
+void
+print_cmd (int argc, char *argv[])
+{
+ int i;
+ for (i = 0; i < argc; i++)
+ {
+ debug ("%s ", argv[i]);
+ }
+ debug ("\n");
+}
+
+static char **comm_argv;
+static int comm_argc;
+
+static int add_comm_arg (char *arg)
+{
+ static int comm_capacity = 0;
+ if (comm_capacity <= comm_argc)
+ {
+ comm_capacity += 8;
+ comm_argv = (char **) realloc (comm_argv,
+ comm_capacity * sizeof (char *));
+ if (comm_argv == NULL)
+ error (1, errno, "realloc");
+ }
+
+ comm_argv[comm_argc] = arg;
+ comm_argc++;
+
+ return 0;
+}
+
+static void add_comm_line (char *line)
+{
+ char *p = line;
+ char *start;
+
+ /* Skip the space */
+ for (; *p != 0 && isspace (*p); p++);
+ start = p;
+
+ while (1)
+ {
+ /* Find the end of an option */
+ for (; *p != 0 && !isspace (*p); p++);
+ if (*p)
+ {
+ *p = 0;
+ p++;
+ }
+ add_comm_arg (start);
+
+ /* Find the beginning of an option */
+ for (; *p != 0 && isspace (*p); p++);
+ if (*p == 0)
+ break;
+ start = p;
+ }
+}
+
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ switch (key)
+ {
+ case 'M':
+ master_port = file_name_lookup (arg, 0, 0);
+ if (master_port == MACH_PORT_NULL)
+ error (1, errno, "file_name_lookup");
+ break;
+ case ARGP_KEY_ARG:
+ add_comm_line (arg);
+ break;
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ error_t err;
+ vpstruct_t child_proc;
+ mach_port_t receive_port;
+ mach_port_t proc_port;
+ int pipe_fd1s[2];
+ int pipe_fd2s[2];
+ pid_t child_pid;
+ task_t child_task;
+ struct argp argp =
+ { options, parse_opt, args_doc, doc};
+
+ argp_parse (&argp, argc, argv, 0, 0, 0);
+ add_comm_arg (NULL);
+
+ if (pipe (pipe_fd1s) < 0)
+ error (2, errno, "pipe");
+ if (pipe (pipe_fd2s) < 0)
+ error (2, errno, "pipe");
+
+ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_DEAD_NAME,
+ &proc_port);
+ if (err != KERN_SUCCESS)
+ error (2, err, "mach_port_allocate");
+
+ child_pid = fork ();
+ if (child_pid < 0)
+ error (2, errno, "fork");
+ else if (child_pid == 0)
+ {
+ /* generate a new process group for child process,
+ * it's needed to set the child process group to foreground */
+ setpgid (getpid (), getpid ());
+
+ close (pipe_fd1s[1]);
+ close (pipe_fd2s[0]);
+
+ debug ("child process starts\n");
+ read (pipe_fd1s[0], &proc_port, sizeof (proc_port));
+ print_cmd (comm_argc, comm_argv);
+ write (pipe_fd2s[1], &proc_port, sizeof (proc_port));
+
+ setproc (proc_port);
+ debug ("child: current proc is %d\n", getproc ());
+ if (execvp (comm_argv[0], comm_argv) < 0)
+ error (2, errno, "execvp");
+ }
+
+ debug ("create a child process %d\n", child_pid);
+
+ /* Set the child process group as the foreground group. */
+ tcsetpgrp (fileno (stdout), child_pid);
+
+ close (pipe_fd1s[0]);
+ close (pipe_fd2s[1]);
+
+ proc_bucket = ports_create_bucket ();
+ proc_class = ports_create_class (task_clean_routine, 0);
+
+ /* Make the send right to the proc porxy in the child process. */
+ child_task = pid2task (child_pid);
+ err = mach_port_destroy (child_task, proc_port);
+ if (err != KERN_SUCCESS)
+ error (2, err, "mach_port_destroy");
+ child_proc = create_task (child_task);
+ receive_port = ports_get_right (child_proc);
+ err = mach_port_insert_right (child_task, proc_port, receive_port,
+ MACH_MSG_TYPE_MAKE_SEND);
+ if (err != KERN_SUCCESS)
+ error (2, err, "mach_port_insert_right");
+
+ /* Tell the child the send right. */
+ write (pipe_fd1s[1], &proc_port, sizeof(proc_port));
+ /* Synchronize. The child process should run first. */
+ read (pipe_fd2s[0], &proc_port, sizeof(proc_port));
+
+ debug ("the proxy starts\n");
+ proc_task2proc (getproc(), child_task, &child_proc->proc);
+
+ while (1)
+ {
+ int status;
+ int ret;
+
+ ports_manage_port_operations_one_thread (proc_bucket,
+ request_server, 500);
+ ret = waitpid (child_pid, &status, WNOHANG);
+ if (ret < 0)
+ error (1, errno, "waitpid");
+
+ /* if the child process exits */
+ if (ret == 1 && WIFEXITED (status))
+ break;
+
+ }
+ debug ("proc proxy exits\n");
+
+ return 0;
+}
+
diff --git a/proc_proxy/proc_proxy.h b/proc_proxy/proc_proxy.h
new file mode 100644
index 00000000..17494415
--- /dev/null
+++ b/proc_proxy/proc_proxy.h
@@ -0,0 +1,67 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+ Written by Zheng Da.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ The GNU Hurd 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the GNU Hurd; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef PROC_PROXY_H
+#define PROC_PROXY_H
+
+#include <stdio.h>
+
+#include <hurd.h>
+#include <hurd/ports.h>
+
+#ifdef DEBUG
+
+#define debug(format, ...) \
+ do \
+ { \
+ char buf [1024]; \
+ snprintf (buf, sizeof (buf), "%s: %s", __func__, format); \
+ fprintf (stderr, buf, ## __VA_ARGS__); \
+ } \
+ while (0)
+
+#else
+
+#define debug(format, ...) do {} while (0)
+
+#endif
+
+struct vproc
+{
+ struct port_info p_pi;
+ task_t task_id;
+ /* The actual port to the proc server for the process. */
+ process_t proc;
+ hurd_ihash_locp_t p_task_hashloc;
+};
+
+typedef struct vproc *vpstruct_t;
+
+static inline void
+process_drop (vpstruct_t p)
+{
+ if (p)
+ ports_port_deref (p);
+}
+
+vpstruct_t reqport_find (mach_port_t port);
+vpstruct_t find_task (task_t task);
+mach_port_t my_get_reply_port (void);
+
+#endif
diff --git a/proc_proxy/process_ops.c b/proc_proxy/process_ops.c
new file mode 100644
index 00000000..ed6b2f76
--- /dev/null
+++ b/proc_proxy/process_ops.c
@@ -0,0 +1,453 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+ Written by Zheng Da.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ The GNU Hurd 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the GNU Hurd; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <error.h>
+
+#include "process_S.h"
+
+kern_return_t
+S_proc_getprivports (vpstruct_t process, mach_port_t *host_priv,
+ mach_port_t *device_master)
+{
+ extern mach_port_t master_port;
+ kern_return_t ret = 0;
+ debug ("task id: %d\n", process->task_id);
+ if (host_priv)
+ {
+ mach_port_t orig_device_master;
+ ret = proc_getprivports (process->proc, host_priv,
+ &orig_device_master);
+ if (ret)
+ {
+ error (0, ret, "proc_getprivports");
+ return ret;
+ }
+ mach_port_deallocate (mach_task_self (), orig_device_master);
+ }
+
+ if (device_master)
+ *device_master = master_port;
+ return ret;
+}
+
+kern_return_t
+S_proc_getallpids (vpstruct_t process, pidarray_t *pidarray,
+ mach_msg_type_number_t *pidarrayCnt)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_getallpids (getproc (), pidarray, pidarrayCnt);
+}
+
+kern_return_t
+S_proc_setexecdata (vpstruct_t process, portarray_t ports,
+ mach_msg_type_number_t portsCnt, intarray_t ints,
+ mach_msg_type_number_t intsCnt)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_setexecdata (process->proc, ports, MACH_MSG_TYPE_COPY_SEND,
+ portsCnt, ints, intsCnt);
+}
+
+kern_return_t
+S_proc_getexecdata (vpstruct_t process, portarray_t *ports,
+ mach_msg_type_name_t *portsPoly,
+ mach_msg_type_number_t *portsCnt,
+ intarray_t *ints, mach_msg_type_number_t *intsCnt)
+{
+ kern_return_t ret;
+ debug ("task id: %d\n", process->task_id);
+ ret = proc_getexecdata (process->proc, ports, portsCnt, ints, intsCnt);
+ if (ret == 0)
+ *portsPoly = MACH_MSG_TYPE_MOVE_SEND;
+ return ret;
+}
+
+kern_return_t
+S_proc_execdata_notify (vpstruct_t process, mach_port_t notify)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_execdata_notify (process->proc, notify, MACH_MSG_TYPE_MOVE_SEND);
+}
+
+kern_return_t
+S_proc_uname (vpstruct_t process, utsname_t *uname)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_uname (process->proc, uname);
+}
+
+kern_return_t
+S_proc_register_version (vpstruct_t process, mach_port_t credential,
+ string_t name, string_t release, string_t version)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_register_version (process->proc, credential,
+ name, release, version);
+}
+
+kern_return_t
+S_proc_reauthenticate (vpstruct_t process, mach_port_t rendezvous2)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_reauthenticate (process->proc, rendezvous2,
+ MACH_MSG_TYPE_MOVE_SEND);
+}
+
+kern_return_t
+S_proc_child (vpstruct_t process, mach_port_t child)
+{
+ debug ("task id: %d, child task: %d\n", process->task_id, child);
+ return proc_child (process->proc, child);
+}
+
+kern_return_t
+S_proc_setmsgport (vpstruct_t process, mach_port_t reply_port,
+ mach_msg_type_name_t reply_portPoly, mach_port_t newmsgport,
+ mach_port_t *oldmsgport, mach_msg_type_name_t *oldmsgportPoly)
+{
+ kern_return_t ret=0;
+ debug ("task id: %d\n", process->task_id);
+ ret = proc_setmsgport (process->proc, newmsgport, oldmsgport);
+ if (ret == 0){
+ *oldmsgportPoly = MACH_MSG_TYPE_MOVE_SEND;
+ }
+ return ret;
+}
+
+kern_return_t
+S_proc_getmsgport (vpstruct_t process, mach_port_t reply_port,
+ mach_msg_type_name_t reply_portPoly, pid_t pid,
+ mach_port_t *msgport)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_getmsgport (getproc(), pid, msgport);
+}
+
+kern_return_t
+S_proc_reassign (vpstruct_t process, mach_port_t newtask)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_reassign (process->proc, newtask);
+}
+
+kern_return_t
+S_proc_setowner (vpstruct_t process, uid_t owner, int clear)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_setowner (process->proc, owner, clear);
+}
+
+kern_return_t
+S_proc_getpids (vpstruct_t process, pid_t *pid,
+ pid_t *ppid, int *orphaned)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_getpids (process->proc, pid, ppid, orphaned);
+}
+
+kern_return_t
+S_proc_set_arg_locations (vpstruct_t process, vm_address_t argv,
+ vm_address_t envp)
+{
+ kern_return_t ret;
+ debug ("task id: %d\n", process->task_id);
+ ret = proc_set_arg_locations(process->proc , argv , envp);
+ if (ret)
+ error (4, ret, "proc_set_arg_locations");
+ return ret;
+}
+
+kern_return_t
+S_proc_get_arg_locations (vpstruct_t process, vm_address_t *argv,
+ vm_address_t *envp)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_get_arg_locations (process->proc, argv, envp);
+}
+
+kern_return_t
+S_proc_wait (vpstruct_t process, mach_port_t reply_port,
+ mach_msg_type_name_t reply_portPoly, pid_t pid, int options,
+ int *status, int *sigcode, rusage_t *rusage, pid_t *pid_status)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_wait (process->proc, pid, options, status, sigcode,
+ rusage, pid_status);
+}
+
+kern_return_t
+S_proc_dostop (vpstruct_t process, mach_port_t contthread)
+{
+ kern_return_t ret;
+
+ debug ("task id: %d\n", process->task_id);
+ ret = proc_dostop(process->proc, contthread);
+ if (ret)
+ error (4, ret, "proc_dostop");
+ return ret;
+}
+
+kern_return_t
+S_proc_handle_exceptions (vpstruct_t process, mach_port_t msgport,
+ mach_port_t forwardport, int flavor,
+ thread_state_t new_state,
+ mach_msg_type_number_t new_stateCnt)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_handle_exceptions (process->proc, msgport, forwardport,
+ MACH_MSG_TYPE_MOVE_SEND, flavor,
+ new_state, new_stateCnt);
+}
+
+kern_return_t
+S_proc_mark_stop (vpstruct_t process, int signo, int sigcode)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_mark_stop (process->proc, signo, sigcode);
+}
+
+kern_return_t
+S_proc_mark_cont (vpstruct_t process)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_mark_cont (process->proc);
+}
+
+kern_return_t
+S_proc_mark_exit (vpstruct_t process, int status, int sigcode)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_mark_exit (process->proc, status, sigcode);
+}
+
+kern_return_t
+S_proc_mark_traced (vpstruct_t process)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_mark_traced (process->proc);
+}
+
+kern_return_t
+S_proc_mark_exec (vpstruct_t process)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_mark_exec (process->proc);
+}
+
+kern_return_t
+S_proc_mod_stopchild (vpstruct_t process, int doit)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_mod_stopchild (process->proc , doit);
+}
+
+kern_return_t
+S_proc_pid2task (vpstruct_t process, pid_t pid, mach_port_t *task)
+{
+ kern_return_t ret;
+ ret = proc_pid2task (getproc (), pid, task);
+ debug ("pid: %d, task: %d\n", pid, *task);
+ return ret;
+}
+
+kern_return_t
+S_proc_task2pid (vpstruct_t process, mach_port_t task, pid_t *pid)
+{
+ debug ("task id: %d\n", task);
+ return proc_task2pid (getproc (), task, pid);
+}
+
+kern_return_t
+S_proc_task2proc (vpstruct_t callerp, mach_port_t task,
+ mach_port_t *proc)
+{
+ kern_return_t err;
+ process_t actual_proc;
+
+ debug ("task id: %d\n", task);
+ vpstruct_t process = find_task (task);
+ *proc = ports_get_right (process);
+
+ /* Get the actuall port to the proc server. */
+ err = proc_task2proc (getproc (), task, &actual_proc);
+ if (err)
+ error (3, err, "proc_task2proc");
+ process->proc = actual_proc;
+
+ /* TODO Do I always need to deallocate task? */
+ mach_port_deallocate (mach_task_self (), task);
+ return 0;
+}
+
+kern_return_t
+S_proc_proc2task (vpstruct_t process, mach_port_t *task)
+{
+ debug ("task id: %d\n", process->task_id);
+ *task = process->task_id;
+ return 0;
+}
+
+kern_return_t
+S_proc_pid2proc (vpstruct_t process, pid_t pid, mach_port_t *proc)
+{
+ debug ("pid id: %d\n", pid);
+ return proc_pid2proc (getproc (), pid, proc);
+}
+
+kern_return_t
+S_proc_getprocinfo (vpstruct_t process, pid_t which, int *flags,
+ procinfo_t *procinfo, mach_msg_type_number_t *procinfoCnt,
+ data_t *threadwaits, mach_msg_type_number_t *threadwaitsCnt)
+{
+ debug ("pid id: %d\n", which);
+ return proc_getprocinfo (getproc (), which, flags, procinfo,
+ procinfoCnt, threadwaits, threadwaitsCnt);
+}
+
+kern_return_t
+S_proc_getprocargs (vpstruct_t process, pid_t which,
+ data_t *procargs, mach_msg_type_number_t *procargsCnt)
+{
+ debug ("pid id: %d\n", which);
+ return proc_getprocargs (getproc (), which, procargs, procargsCnt);
+}
+
+kern_return_t
+S_proc_getprocenv (vpstruct_t process, pid_t which,
+ data_t *procenv, mach_msg_type_number_t *procenvCnt)
+{
+ debug ("pid id: %d\n", which);
+ return proc_getprocenv (getproc (), which, procenv, procenvCnt);
+}
+
+kern_return_t
+S_proc_make_login_coll (vpstruct_t process)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_make_login_coll (process->proc);
+}
+
+kern_return_t
+S_proc_getloginid (vpstruct_t process, pid_t pid, pid_t *login_id)
+{
+ debug ("pid id: %d\n", pid);
+ return proc_getloginid (getproc (), pid, login_id);
+}
+
+kern_return_t
+S_proc_getloginpids (vpstruct_t process, pid_t id,
+ pidarray_t *pids, mach_msg_type_number_t *pidsCnt)
+{
+ debug ("pid id: %d\n", id);
+ return proc_getloginpids (getproc (), id, pids, pidsCnt);
+}
+
+kern_return_t
+S_proc_setlogin (vpstruct_t process, string_t logname)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_setlogin (process->proc, logname);
+}
+
+kern_return_t
+S_proc_getlogin (vpstruct_t process, string_t logname)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_getlogin (process->proc, logname);
+}
+
+kern_return_t
+S_proc_setsid (vpstruct_t process)
+{
+ debug ("task id: %d\n", process->task_id);
+ return proc_setsid (process->proc);
+}
+
+kern_return_t
+S_proc_getsid (vpstruct_t process, pid_t pid, pid_t *sid)
+{
+ debug ("pid id: %d\n", pid);
+ return proc_getsid (getproc (), pid, sid);
+}
+
+kern_return_t
+S_proc_getsessionpgids (vpstruct_t process, pid_t sid,
+ pidarray_t *pgidset, mach_msg_type_number_t *pgidsetCnt)
+{
+ debug ("pid id: %d\n", sid);
+ return proc_getsessionpgids (getproc (), sid, pgidset, pgidsetCnt);
+}
+
+kern_return_t
+S_proc_getsessionpids (vpstruct_t process, pid_t sid,
+ pidarray_t *pidset, mach_msg_type_number_t *pidsetCnt)
+{
+ debug ("pid id: %d\n", sid);
+ return proc_getsessionpids (getproc (), sid, pidset, pidsetCnt);
+}
+
+kern_return_t
+S_proc_getsidport (vpstruct_t process, mach_port_t *sessport,
+ mach_msg_type_name_t *sessportPoly)
+{
+ kern_return_t ret;
+ debug ("task id: %d\n", process->task_id);
+ ret = proc_getsidport (process->proc, sessport);
+ if (ret == 0)
+ *sessportPoly = MACH_MSG_TYPE_MOVE_SEND;
+ return ret;
+}
+
+kern_return_t
+S_proc_setpgrp (vpstruct_t process, pid_t pid, pid_t pgrp)
+{
+ debug ("pid id: %d\n", pid);
+ return proc_setpgrp (getproc (), pid, pgrp);
+}
+
+kern_return_t
+S_proc_getpgrp (vpstruct_t process, pid_t pid, pid_t *pgrp)
+{
+ kern_return_t ret;
+ debug ("pid id: %d\n", pid);
+ ret = proc_getpgrp(getproc(), pid, pgrp);
+ if (ret)
+ error (0, ret, "proc_proxy: proc_getpgrp");
+ return ret;
+}
+
+kern_return_t
+S_proc_getpgrppids (vpstruct_t process, pid_t pgrp,
+ pidarray_t *pidset, mach_msg_type_number_t *pidsetCnt)
+{
+ debug ("pgrp id: %d\n", pgrp);
+ return proc_getpgrppids (getproc (), pgrp, pidset, pidsetCnt);
+}
+
+kern_return_t
+S_proc_get_tty (vpstruct_t calling_process, pid_t target_process,
+ mach_port_t *tty, mach_msg_type_name_t *ttyPoly)
+{
+ kern_return_t ret;
+ debug ("");
+ ret = proc_get_tty (getproc (), target_process, tty);
+ if (ret == 0)
+ *ttyPoly = MACH_MSG_TYPE_MOVE_SEND;
+ return ret;
+}
diff --git a/proc_proxy/test.c b/proc_proxy/test.c
new file mode 100644
index 00000000..fa3591c0
--- /dev/null
+++ b/proc_proxy/test.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main (int argc, char *argv[])
+{
+ printf ("hello world: %s\n", argv[1]);
+ return 0;
+}