diff options
author | root <root@(null).(none)> | 2009-05-03 17:20:00 +0200 |
---|---|---|
committer | root <root@(null).(none)> | 2009-05-03 17:20:00 +0200 |
commit | e0faf22f31c48fb27b43c1825897d26e58feafc4 (patch) | |
tree | 65a09372b31e08a3a865bd0a88cd2718bafcd643 /boot.backup1/mach_port_impl.c~ |
This is my initial working version.
There is a bug in boot in this version: subhurd sometimes cannot boot.
Diffstat (limited to 'boot.backup1/mach_port_impl.c~')
-rw-r--r-- | boot.backup1/mach_port_impl.c~ | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/boot.backup1/mach_port_impl.c~ b/boot.backup1/mach_port_impl.c~ new file mode 100644 index 00000000..2933950e --- /dev/null +++ b/boot.backup1/mach_port_impl.c~ @@ -0,0 +1,378 @@ +/* + Copyright (C) 2009 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. */ + +/* This file implements the server-side RPC functions of mach_host. */ + +#include <mach.h> +#include <hurd.h> +#include <string.h> +#include <assert.h> + +#include "util.h" +#include "mach_proxy.h" + +kern_return_t +S_mach_port_names (mach_port_t task, mach_port_array_t *names, + mach_msg_type_number_t *namesCnt, + mach_port_type_array_t *types, + mach_msg_type_number_t *typesCnt) +{ + struct task_info *task_pi; + error_t err; + + debug (""); + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + err = mach_port_names (task_pi->task_port, + names, namesCnt, types, typesCnt); + /* The deallocation bit is set, + * so 'names' and 'types' will be deallocated after the reply is sent. */ + ports_port_deref (task_pi); + return err; +} + +/* Routine mach_port_type */ +kern_return_t +S_mach_port_type (mach_port_t task, mach_port_t name, mach_port_type_t *ptype) +{ + struct task_info *task_pi; + error_t err; + + debug (""); + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + err = mach_port_type (task_pi->task_port, name, ptype); + ports_port_deref (task_pi); + return err; +} + +/* Routine mach_port_rename */ +kern_return_t +S_mach_port_rename (mach_port_t task, + mach_port_t old_name, mach_port_t new_name) +{ + struct task_info *task_pi; + error_t err; + + debug (""); + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + /* old_name and new_name are just names, + * so I don't need to deallocate them. + * It should be the same for other RPCs that only deal with port names */ + err = mach_port_rename (task_pi->task_port, old_name, new_name); + ports_port_deref (task_pi); + return err; +} + +/* Routine mach_port_allocate_name */ +kern_return_t +S_mach_port_allocate_name (mach_port_t task, + mach_port_right_t right, mach_port_t name) +{ + struct task_info *task_pi; + error_t err; + + debug (""); + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + err = mach_port_allocate_name (task_pi->task_port, right, name); + ports_port_deref (task_pi); + return err; +} + +/* Routine mach_port_allocate */ +kern_return_t +S_mach_port_allocate (mach_port_t task, + mach_port_right_t right, mach_port_t *name) +{ + struct task_info *task_pi; + error_t err; + + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + debug ("get a request from task %d", task_pi->task_port); + print_port_type (task_pi->task_port); + err = mach_port_allocate (task_pi->task_port, right, name); + debug ("mach_port_allocate: %s", strerror (err)); + ports_port_deref (task_pi); + return err; +} + +/* Routine mach_port_destroy */ +kern_return_t +S_mach_port_destroy (mach_port_t task, mach_port_t name) +{ + struct task_info *task_pi; + error_t err; + + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + debug ("get a request from port %d", task_pi->task_port); + err = mach_port_destroy (task_pi->task_port, name); + ports_port_deref (task_pi); + return err; +} + +/* Routine mach_port_deallocate */ +kern_return_t +S_mach_port_deallocate (mach_port_t task, mach_port_t name) +{ + struct task_info *task_pi; + error_t err; + + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + debug ("get a request from task %d", task_pi->task_port); + err = mach_port_deallocate (task_pi->task_port, name); + debug ("mach_port_deallocate port: %d: %s", name, strerror (err)); + ports_port_deref (task_pi); + return err; +} + +/* Routine mach_port_get_refs */ +kern_return_t +S_mach_port_get_refs (mach_port_t task, mach_port_t name, + mach_port_right_t right, mach_port_urefs_t *refs) +{ + struct task_info *task_pi; + error_t err; + + debug (""); + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + err = mach_port_get_refs (task_pi->task_port, name, right, refs); + ports_port_deref (task_pi); + return err; +} + +/* Routine mach_port_mod_refs */ +kern_return_t +S_mach_port_mod_refs (mach_port_t task, mach_port_t name, + mach_port_right_t right, mach_port_delta_t delta) +{ + struct task_info *task_pi; + error_t err; + + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + debug ("get a request from task %d", task_pi->task_port); + err = mach_port_mod_refs (task_pi->task_port, name, right, delta); + debug ("mach_port_mod_refs: %s, port: %d, delta: %d", + strerror (err), right, delta); + ports_port_deref (task_pi); + return err; +} + +/* Routine old_mach_port_get_receive_status */ +kern_return_t +S_old_mach_port_get_receive_status (mach_port_t task, mach_port_t name, + old_mach_port_status_t *status) +{ + debug (""); + assert (0); + /* Hurd currently doesn't use it. */ + return EOPNOTSUPP; +} + +/* Routine mach_port_set_qlimit */ +kern_return_t +S_mach_port_set_qlimit (mach_port_t task, mach_port_t name, + mach_port_msgcount_t qlimit) +{ + struct task_info *task_pi; + error_t err; + + debug (""); + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + err = mach_port_set_qlimit (task_pi->task_port, name, qlimit); + ports_port_deref (task_pi); + return err; +} + +/* Routine mach_port_set_mscount */ +kern_return_t +S_mach_port_set_mscount (mach_port_t task, mach_port_t name, + mach_port_mscount_t mscount) +{ + struct task_info *task_pi; + error_t err; + + debug (""); + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + err = mach_port_set_mscount (task_pi->task_port, name, mscount); + ports_port_deref (task_pi); + return err; +} + +/* Routine mach_port_get_set_status */ +kern_return_t +S_mach_port_get_set_status (mach_port_t task, mach_port_t name, + mach_port_array_t *members, + mach_msg_type_number_t *membersCnt) +{ + struct task_info *task_pi; + error_t err; + + debug (""); + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + err = mach_port_get_set_status (task_pi->task_port, + name, members, membersCnt); + ports_port_deref (task_pi); + /* The deallocation bit is set, + * so 'members' will be deallocated after the reply is sent. */ + return err; +} + +/* Routine mach_port_move_member */ +kern_return_t +S_mach_port_move_member (mach_port_t task, mach_port_t member, + mach_port_t after) +{ + struct task_info *task_pi; + error_t err; + + debug (""); + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + err = mach_port_move_member (task_pi->task_port, member, after); + ports_port_deref (task_pi); + return err; +} + +/* Routine mach_port_request_notification */ +kern_return_t +S_mach_port_request_notification (mach_port_t task, mach_port_t name, + mach_msg_id_t id, mach_port_mscount_t sync, + mach_port_t notify, mach_port_t *previous, + mach_msg_type_name_t *previousPoly) +{ + struct task_info *task_pi; + error_t err; + + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + debug ("get a request from task %d", task_pi->task_port); + /* notify is send-once right from the client. */ + err = mach_port_request_notification (task_pi->task_port, name, id, sync, + notify, MACH_MSG_TYPE_MOVE_SEND_ONCE, + previous); + debug ("mach_port_request_notification, id: %d, old port: %d, %s", + id, *previous, strerror (err)); + ports_port_deref (task_pi); + if (err) + return err; + *previousPoly = MACH_MSG_TYPE_MOVE_SEND_ONCE; + return 0; +} + +/* Routine mach_port_insert_right */ +kern_return_t +S_mach_port_insert_right (mach_port_t task, mach_port_t name, + mach_port_t poly, mach_msg_type_name_t polyPoly) +{ + struct task_info *task_pi; + error_t err; + + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + debug ("get a request from task %d", task_pi->task_port); + /* polyPoly can only be three possible values: MACH_MSG_TYPE_PORT_SEND, + * MACH_MSG_TYPE_PORT_SEND_ONCE and MACH_MSG_TYPE_PORT_RECEIVE, + * so port will be deallocated when mach_port_insert_right is called. */ + err = mach_port_insert_right (task_pi->task_port, name, poly, polyPoly); + debug ("mach_port_insert_right: %s", strerror (err)); + ports_port_deref (task_pi); + return err; +} + +/* Routine mach_port_extract_right */ +kern_return_t +S_mach_port_extract_right (mach_port_t task, mach_port_t name, + mach_msg_type_name_t msgt_name, mach_port_t *poly, + mach_msg_type_name_t *polyPoly) +{ + struct task_info *task_pi; + error_t err; + + debug (""); + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + err = mach_port_extract_right (task_pi->task_port, name, msgt_name, + poly, polyPoly); + ports_port_deref (task_pi); + /* *polyPoly can only be MACH_MSG_TYPE_PORT_SEND, MACH_MSG_TYPE_PORT_RECEIVE, + * or MACH_MSG_TYPE_PORT_SEND_ONCE, so the port extracted from 'task' + * will be moved to the client. */ + return err; +} + +/* Routine mach_port_get_receive_status */ +kern_return_t +S_mach_port_get_receive_status (mach_port_t task, mach_port_t name, + mach_port_status_t *status) +{ + struct task_info *task_pi; + error_t err; + + debug (""); + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + err = mach_port_get_receive_status (task_pi->task_port, name, status); + ports_port_deref (task_pi); + return err; +} + +/* Routine mach_port_set_seqno */ +kern_return_t +S_mach_port_set_seqno (mach_port_t task, mach_port_t name, + mach_port_seqno_t seqno) +{ + struct task_info *task_pi; + error_t err; + + debug (""); + task_pi = ports_lookup_port (port_bucket, task, task_portclass); + if (task_pi == NULL) + return EOPNOTSUPP; + err = mach_port_set_seqno (task_pi->task_port, name, seqno); + ports_port_deref (task_pi); + return err; +} |