/* 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 . */
#include
#include
#include
#include
#include
#include
#include
#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;
}