aboutsummaryrefslogtreecommitdiff
path: root/libtrivfs/startup.c
diff options
context:
space:
mode:
Diffstat (limited to 'libtrivfs/startup.c')
-rw-r--r--libtrivfs/startup.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/libtrivfs/startup.c b/libtrivfs/startup.c
index 56ef02c4..d5767df2 100644
--- a/libtrivfs/startup.c
+++ b/libtrivfs/startup.c
@@ -86,3 +86,72 @@ trivfs_startup(mach_port_t bootstrap, int flags,
return err;
}
+
+/* Start in debug mode, no need to be called by settrans. Common options are
+ the same as in trivfs_startup. FILE_NAME is the path of the node where the
+ translator is set*/
+error_t
+trivfs_startup_debug(const char *file_name,
+ struct port_class *control_class,
+ struct port_bucket *control_bucket,
+ struct port_class *protid_class,
+ struct port_bucket *protid_bucket,
+ struct trivfs_control **control)
+{
+ mach_port_t underlying, right, goaway;
+ struct trivfs_control *fsys;
+ error_t err =
+ trivfs_create_control (MACH_PORT_NULL,
+ control_class, control_bucket,
+ protid_class, protid_bucket,
+ &fsys);
+
+ if (err)
+ return err;
+
+ right = ports_get_send_right (fsys);
+ goaway = ports_get_send_right (fsys);
+
+ /* Start ourselves as transpator instead of replying to settrans */
+ underlying = file_name_lookup(file_name, 0, 0);
+ if (underlying == MACH_PORT_NULL)
+ err = errno;
+ else
+ err = file_set_translator(underlying, 0, FS_TRANS_SET, 0, "", 0,
+ right, MACH_MSG_TYPE_COPY_SEND);
+ mach_port_deallocate (mach_task_self (), right);
+
+ if (! err)
+ fsys->underlying = underlying;
+
+ ports_port_deref (fsys);
+
+ /* Pass back what we got, unless the caller doesn't want it. */
+ if (!err && control)
+ *control = fsys;
+
+ /* don't mark us as important and install a SIGTERM handler, so we can be
+ * easily killed by Ctrl-C */
+ void handler_sigterm(int signum)
+ {
+ error_t ee;
+ ee = fsys_goaway(goaway, 0);
+ if (ee == ESUCCESS)
+ {
+ mach_port_deallocate (mach_task_self (), goaway);
+ }
+ else if (ee != EBUSY)
+ {
+ /* Not nice */
+ error(99, err, "fsys_goaway");
+ }
+ /* else the translator is busy, please retry */
+ }
+
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = handler_sigterm;
+ if (sigaction(SIGTERM, &sa, NULL) < 0)
+ err = errno;
+ return err;
+}