minix/servers/hgfs/main.c
Ben Gras 35a108b911 panic() cleanup.
this change
   - makes panic() variadic, doing full printf() formatting -
     no more NO_NUM, and no more separate printf() statements
     needed to print extra info (or something in hex) before panicing
   - unifies panic() - same panic() name and usage for everyone -
     vm, kernel and rest have different names/syntax currently
     in order to implement their own luxuries, but no longer
   - throws out the 1st argument, to make source less noisy.
     the panic() in syslib retrieves the server name from the kernel
     so it should be clear enough who is panicing; e.g.
         panic("sigaction failed: %d", errno);
     looks like:
         at_wini(73130): panic: sigaction failed: 0
         syslib:panic.c: stacktrace: 0x74dc 0x2025 0x100a
   - throws out report() - printf() is more convenient and powerful
   - harmonizes/fixes the use of panic() - there were a few places
     that used printf-style formatting (didn't work) and newlines
     (messes up the formatting) in panic()
   - throws out a few per-server panic() functions
   - cleans up a tie-in of tty with panic()

merging printf() and panic() statements to be done incrementally.
2010-03-05 15:05:11 +00:00

233 lines
5.8 KiB
C

/* This file contains the main message loop of the HGFS file system server.
*
* The entry points into this file are:
* main main program function
*
* Created:
* April 2009 (D.C. van Moolenbroek)
*/
#include "inc.h"
#include "optset.h"
#include <signal.h>
#include <unistd.h>
FORWARD _PROTOTYPE( int init, (int type, sef_init_info_t *info) );
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( void cleanup, (void) );
FORWARD _PROTOTYPE( int get_work, (endpoint_t *who_e) );
FORWARD _PROTOTYPE( void send_reply, (int err) );
FORWARD _PROTOTYPE( int proc_event, (void) );
PRIVATE struct optset optset_table[] = {
{ "prefix", OPT_STRING, opt.prefix, sizeof(opt.prefix) },
{ "uid", OPT_INT, &opt.uid, 10 },
{ "gid", OPT_INT, &opt.gid, 10 },
{ "fmask", OPT_INT, &opt.file_mask, 8 },
{ "dmask", OPT_INT, &opt.dir_mask, 8 },
{ "icase", OPT_BOOL, &opt.case_insens, TRUE },
{ "noicase", OPT_BOOL, &opt.case_insens, FALSE },
{ NULL }
};
EXTERN int env_argc;
EXTERN char **env_argv;
/*===========================================================================*
* init *
*===========================================================================*/
PRIVATE int init(type, info)
int type;
sef_init_info_t *info;
{
/* Initialize this file server. Called at startup time.
*/
message m;
int i, r;
/* Defaults */
opt.prefix[0] = 0;
opt.uid = 0;
opt.gid = 0;
opt.file_mask = 0755;
opt.dir_mask = 0755;
opt.case_insens = FALSE;
/* If we have been given an options string, parse options from there. */
for (i = 1; i < env_argc - 1; i++)
if (!strcmp(env_argv[i], "-o"))
optset_parse(optset_table, env_argv[++i]);
/* Make sure that the given path prefix doesn't end with a slash. */
for (i = strlen(opt.prefix); i > 0 && opt.prefix[i - 1] == '/'; i--);
opt.prefix[i] = 0;
/* Initialize the HGFS library. If this fails, exit immediately. */
r = hgfs_init();
if (r != OK && r != EAGAIN) {
printf("HGFS: unable to initialize HGFS library (%d)\n", r);
return r;
}
state.mounted = FALSE;
/* Announce our presence to VFS. */
m.m_type = FS_READY;
if ((r = send(FS_PROC_NR, &m)) != OK) {
printf("HGFS: unable to login to VFS (%d)\n", r);
return r;
}
return OK;
}
/*===========================================================================*
* sef_local_startup *
*===========================================================================*/
PRIVATE void sef_local_startup()
{
/* Specify initialization routines and start the SEF framework.
*/
sef_setcb_init_fresh(init);
sef_setcb_init_restart(init);
/* No live update support yet. */
sef_startup();
}
/*===========================================================================*
* cleanup *
*===========================================================================*/
PRIVATE void cleanup()
{
/* Clean up any resources in use by this file server. Called at shutdown time.
*/
/* Pass on the cleanup request to the HGFS library. */
hgfs_cleanup();
}
/*===========================================================================*
* main *
*===========================================================================*/
PUBLIC int main(argc, argv)
int argc;
char *argv[];
{
/* The main function of this file server. After initializing, loop forever
* receiving one request from VFS at a time, processing it, and sending a
* reply back to VFS.
*/
endpoint_t who_e;
int call_nr, err;
env_setargs(argc, argv);
sef_local_startup();
for (;;) {
call_nr = get_work(&who_e);
if (who_e != FS_PROC_NR) {
/* Is this PM telling us to shut down? */
if (who_e == PM_PROC_NR && is_notify(call_nr))
if (proc_event()) break;
continue;
}
if (state.mounted || call_nr == REQ_READSUPER) {
call_nr -= VFS_BASE;
dprintf(("HGFS: call %d\n", call_nr));
if (call_nr >= 0 && call_nr < NREQS) {
err = (*call_vec[call_nr])();
} else {
err = ENOSYS;
}
dprintf(("HGFS: call %d result %d\n", call_nr, err));
}
else err = EINVAL;
send_reply(err);
}
cleanup();
return 0;
}
/*===========================================================================*
* get_work *
*===========================================================================*/
PRIVATE int get_work(who_e)
endpoint_t *who_e;
{
/* Receive a request message from VFS. Return the request call number.
*/
int r;
if ((r = sef_receive(ANY, &m_in)) != OK)
panic("receive failed: %d", r);
*who_e = m_in.m_source;
return m_in.m_type;
}
/*===========================================================================*
* send_reply *
*===========================================================================*/
PRIVATE void send_reply(err)
int err; /* resulting error code */
{
/* Send a reply message to the requesting party, with the given error code.
*/
int r;
m_out.m_type = err;
if ((r = send(m_in.m_source, &m_out)) != OK)
printf("HGFS: send failed (%d)\n", r);
}
/*===========================================================================*
* proc_event *
*===========================================================================*/
PRIVATE int proc_event()
{
/* We got a notification from PM; see what it's about. Return TRUE if this
* server has been told to shut down.
*/
sigset_t set;
int r;
if ((r = getsigset(&set)) != OK) {
printf("HGFS: unable to get pending signals from PM (%d)\n", r);
return FALSE;
}
if (sigismember(&set, SIGTERM)) {
if (state.mounted) {
dprintf(("HGFS: got SIGTERM, still mounted\n"));
return FALSE;
}
dprintf(("HGFS: got SIGTERM, shutting down\n"));
return TRUE;
}
return FALSE;
}