diff options
Diffstat (limited to 'pong.c')
-rw-r--r-- | pong.c | 227 |
1 files changed, 227 insertions, 0 deletions
@@ -0,0 +1,227 @@ +/* A pong server. + + Copyright (C) 2013 Free Software Foundation, Inc. + + Written by Justus Winter <4winter@informatik.uni-hamburg.de> + + This file might one day be a part of the GNU Hurd. + + This program 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. + + This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <argp.h> +#include <error.h> +#include <hurd.h> +#include <hurd/fsys.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "reincarnation.h" +#include "reincarnation_U.h" + +static mach_port_t reincarnation; +static mach_port_t control; + +static int global_count; + +static int +demuxer (mach_msg_header_t *inp, + mach_msg_header_t *outp) +{ + extern int pong_server (mach_msg_header_t *, mach_msg_header_t *); + extern int fsys_server (mach_msg_header_t *, mach_msg_header_t *); + + return (pong_server (inp, outp) || + fsys_server (inp, outp)); +} + +int +main (int argc, char **argv) +{ + error_t err; + + /* Get reincarnation port. */ + err = reincarnation_get_port (mach_task_self (), + &reincarnation); + if (err) + error (2, err, "reincarnation_get_port"); + + if (reincarnation != MACH_PORT_NULL) + { + /* Get reincarnation image. */ + char *image = NULL; + size_t image_len = 0; + err = reincarnation_reincarnate (reincarnation, &image, &image_len); + if (err) + error (2, err, "reincarnation_reincarnate"); + + if (image_len) + { + global_count = *(int *) image; + } + } + + mach_port_t bootstrap; + task_get_bootstrap_port (mach_task_self (), &bootstrap); + if (bootstrap == MACH_PORT_NULL) + error (1, 0, "Must be started as a translator"); + + /* Reply to our parent */ + err = mach_port_allocate (mach_task_self (), + MACH_PORT_RIGHT_RECEIVE, + &control); + if (err) + error (1, err, "mach_port_allocate"); + + err = mach_port_insert_right (mach_task_self (), + control, + control, + MACH_MSG_TYPE_MAKE_SEND); + if (err) + error (1, err, "mach_port_insert_right"); + + mach_port_t realnode; + err = + fsys_startup (bootstrap, 0, control, MACH_MSG_TYPE_COPY_SEND, &realnode); + if (err) + error (1, err, "fsys_startup"); + + mach_port_deallocate (mach_task_self (), bootstrap); + + /* Launch */ + while (1) + { + err = mach_msg_server (demuxer, 0, control); + if (err) + error (2, err, "mach_msg_server"); + } +} + +error_t +S_ping (mach_port_t server, + int *local, + int *global) +{ + global_count += 1; + + if (reincarnation != MACH_PORT_NULL) + { + error_t err = reincarnation_checkpoint (reincarnation, + (data_t) &global_count, + sizeof global_count); + if (err) + error (0, err, "checkpoint"); + } + + *local = global_count; /* XXX */ + *global = global_count; + + return 0; +} + +error_t +S_fsys_getroot (mach_port_t fsys_t, + mach_port_t dotdotnode, + uid_t *uids, size_t nuids, + uid_t *gids, size_t ngids, + int flags, + retry_type *do_retry, + char *retry_name, + mach_port_t *ret, + mach_msg_type_name_t *rettype) +{ + *do_retry = FS_RETRY_NORMAL; + *retry_name = '\0'; + *ret = control; + *rettype = MACH_MSG_TYPE_COPY_SEND; + return 0; +} + +error_t +S_fsys_goaway (mach_port_t control, int flags) +{ + if (reincarnation != MACH_PORT_NULL) + reincarnation_goaway (reincarnation); + + exit (0); +} + +error_t +S_fsys_startup (mach_port_t bootstrap, int flags, mach_port_t control, + mach_port_t *real, mach_msg_type_name_t *realtype) +{ + return EOPNOTSUPP; +} + +error_t +S_fsys_syncfs (mach_port_t control, + int wait, + int recurse) +{ + return EOPNOTSUPP; +} + +error_t +S_fsys_set_options (mach_port_t control, + char *data, mach_msg_type_number_t len, + int do_children) +{ + return EOPNOTSUPP; +} + +error_t +S_fsys_get_options (mach_port_t control, + char **data, mach_msg_type_number_t *len) +{ + return EOPNOTSUPP; +} + +error_t +S_fsys_getfile (mach_port_t control, + uid_t *uids, size_t nuids, + uid_t *gids, size_t ngids, + char *handle, size_t handllen, + mach_port_t *pt, + mach_msg_type_name_t *pttype) +{ + return EOPNOTSUPP; +} + +error_t +S_fsys_getpriv (mach_port_t control, + mach_port_t *host_priv, mach_msg_type_name_t *host_priv_type, + mach_port_t *dev_master, mach_msg_type_name_t *dev_master_type, + task_t *fs_task, mach_msg_type_name_t *fs_task_type) +{ + return EOPNOTSUPP; +} + +error_t +S_fsys_init (mach_port_t control, + mach_port_t reply, + mach_msg_type_name_t replytype, + mach_port_t proc, + auth_t auth) +{ + return EOPNOTSUPP; +} + +error_t +S_fsys_forward (mach_port_t server, mach_port_t requestor, + char *argz, size_t argz_len) +{ + return EOPNOTSUPP; +} + + |