summaryrefslogtreecommitdiff
path: root/minix/lib/libpuffs/main.c
blob: 54e98f21d25d1f216e6b812dbfc0b7055ed6edfa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

#include "fs.h"

static message fs_msg;
static int fs_ipc_status;
static int fs_pending;

#define PUFFS_MAX_ARGS 20

/*===========================================================================*
 *		            sef_cb_init_fresh                                *
 *===========================================================================*/
static int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
/* Initialize the Minix file server. */
  return(OK);
}

/*===========================================================================*
 *		           sef_cb_signal_handler                             *
 *===========================================================================*/
static void sef_cb_signal_handler(int signo)
{
  /* Only check for termination signal, ignore anything else. */
  if (signo != SIGTERM) return;

  exitsignaled = 1;
  if (mounted)
	fs_sync();

  sef_cancel();
}

/*===========================================================================*
 *			       sef_local_startup			     *
 *===========================================================================*/
static void sef_local_startup(void)
{
  /* Register init callbacks. */
  sef_setcb_init_fresh(sef_cb_init_fresh);

  /* Register signal callbacks. */
  sef_setcb_signal_handler(sef_cb_signal_handler);

  /* Let SEF perform startup. */
  sef_startup();
}

/*===========================================================================*
 *				get_work				     *
 *===========================================================================*/
static int get_work(message *msg, int *ipc_status)
{
  int r;

  for (;;) {
	if ((r = sef_receive_status(ANY, msg, ipc_status)) != OK) {
		if (r == EINTR) /* sef_cancel from signal handler? */
			break; /* see if we can exit the main loop */
		panic("sef_receive failed: %d", r);
	}
	if (msg->m_source == VFS_PROC_NR)
		break;
	lpuffs_debug("libpuffs: unexpected source %d\n", msg->m_source);
  }

  return r;
}

int __wrap_main(int argc, char *argv[]);
int __real_main(int argc, char* argv[]);

int __wrap_main(int argc, char *argv[])
{
  int i;
  int new_argc = 0;
  static char* new_argv[PUFFS_MAX_ARGS];
  char *name;

  /* SEF local startup. */
  env_setargs(argc, argv);
  sef_local_startup();

  global_kcred.pkcr_type = PUFFCRED_TYPE_INTERNAL;

  if (argc < 3) {
	panic("Unexpected arguments, use:\
		mount -t fs /dev/ /dir [-o option1,option2]\n");
  }

  name = argv[0] + strlen(argv[0]);
  while (*name != '/' && name != argv[0])
	  name--;
  if (name != argv[0])
	  name++;
  strcpy(fs_name, name);

  new_argv[new_argc] = argv[0];
  new_argc++;

  for (i = 1; i < argc; i++) {
	if (new_argc >= PUFFS_MAX_ARGS) {
		panic("Too many arguments, change PUFFS_MAX_ARGS");
	}
	new_argv[new_argc] = argv[i];
	new_argc++;
  }

  assert(new_argc > 0);

  /* Get the mount request from VFS, so we can deal with it later. */
  (void)get_work(&fs_msg, &fs_ipc_status);
  fs_pending = TRUE;

  return __real_main(new_argc, new_argv);
}

/*
 * Receive a message unless one was already pending.  Process the message, and
 * send a reply if necessary.  Return whether puffs should keep running.
 */
int
lpuffs_pump(void)
{

	if (fs_pending == TRUE || get_work(&fs_msg, &fs_ipc_status) == OK) {
		fs_pending = FALSE;

		fsdriver_process(&puffs_table, &fs_msg, fs_ipc_status, FALSE);
	}

	return mounted || !exitsignaled;
}

/*
 * Initialize MINIX3-specific settings.
 */
void
lpuffs_init(struct puffs_usermount * pu)
{

	buildpath = pu->pu_flags & PUFFS_FLAG_BUILDPATH; /* XXX */

	LIST_INIT(&pu->pu_pnode_removed_lst);

	global_pu = pu;
}