diff --git a/include/toksvc/toksvc.h b/include/toksvc/toksvc.h index 0725ed7..4d68081 100644 --- a/include/toksvc/toksvc.h +++ b/include/toksvc/toksvc.h @@ -46,6 +46,9 @@ extern "C" { #define TOKS_DRIVER_ANNOTATE_NEVER 0x2000 #define TOKS_DRIVER_ANNOTATE_FULL 0x4000 +#define TOKS_DRIVER_MODE_SERVER 0X10000 +#define TOKS_DRIVER_MODE_CLIENT 0X20000 + /* error flags */ #define TOKS_ERROR_TOP_LEVEL 0x0001 #define TOKS_ERROR_NESTED 0x0002 @@ -90,6 +93,7 @@ struct toks_common_ctx { uint64_t drvflags; uint64_t actflags; uint64_t fmtflags; + const nt_guid * uuid; void * hroot; const char * sysroot; char ** eargv; diff --git a/src/daemon/toks_daemon_init.c b/src/daemon/toks_daemon_init.c index d11d347..0914a6d 100644 --- a/src/daemon/toks_daemon_init.c +++ b/src/daemon/toks_daemon_init.c @@ -12,9 +12,10 @@ #include "toksvc_daemon_impl.h" #include "toksvc_driver_impl.h" -static const nt_guid toks_daemon_guid = TOKS_PORT_GUID_DAEMON; - -static int32_t toks_daemon_init_impl(struct toks_daemon_ctx * dctx, void * htty) +static int32_t toks_daemon_init_impl( + struct toks_daemon_ctx * dctx, + const nt_guid * svcguid, + void * htty) { int32_t status; nt_daemon_params dparams; @@ -28,7 +29,7 @@ static int32_t toks_daemon_init_impl(struct toks_daemon_ctx * dctx, void * htty) /* port guid */ ntapi->tt_guid_copy( &dctx->daemon_attr.guid, - &toks_daemon_guid); + svcguid); /* port keys */ if ((status = ntapi->tt_port_generate_keys(&dctx->daemon_attr.keys))) @@ -69,6 +70,7 @@ static int32_t toks_daemon_init_impl(struct toks_daemon_ctx * dctx, void * htty) if ((status = ntapi->dsr_init(&dparams))) return status; + /* todo: check driver flags or defer to driver */ return ntapi->tty_request_peer( htty, TOKS_DAEMON_TTYSIGNAL, @@ -78,7 +80,7 @@ static int32_t toks_daemon_init_impl(struct toks_daemon_ctx * dctx, void * htty) static int32_t toks_daemon_once = 0; -int32_t __stdcall toks_daemon_init(struct toks_daemon_ctx * dctx, uint64_t drvflags) +int32_t __stdcall toks_daemon_init(struct toks_daemon_ctx * dctx, const nt_guid * svcguid) { int32_t status; nt_timeout timeout; @@ -88,18 +90,10 @@ int32_t __stdcall toks_daemon_init(struct toks_daemon_ctx * dctx, uint64_t drvfl if ((status = ntapi->tt_get_runtime_data(&rtdata,0))) return status; - /* needed? */ - if (drvflags & TOKS_DRIVER_DAEMON_NEVER) - return 0; - - if (!(drvflags & TOKS_DRIVER_DAEMON_ALWAYS)) - if (ntapi->tt_guid_compare(&rtdata->srv_guid,&toks_daemon_guid)) - return 0; - /* once */ switch (at_locked_cas_32(&toks_daemon_once,0,1)) { case 0: - if ((status = toks_daemon_init_impl(dctx,rtdata->hsession))) { + if ((status = toks_daemon_init_impl(dctx,svcguid,rtdata->hsession))) { at_locked_add_32(&toks_daemon_once,2); return status; } diff --git a/src/driver/toks_amain.c b/src/driver/toks_amain.c index 5853c5a..b4b3764 100644 --- a/src/driver/toks_amain.c +++ b/src/driver/toks_amain.c @@ -74,5 +74,7 @@ int toks_main(char ** argv, char ** envp) if ((toks_version(dctx)) < 0) return toks_exit(dctx,2); - return toks_exit(dctx,ret); + return (dctx->cctx->drvflags & TOKS_DRIVER_MODE_SERVER) + ? NT_STATUS_SERVICE_NOTIFICATION + : toks_exit(dctx,ret); } diff --git a/src/driver/toks_driver_ctx.c b/src/driver/toks_driver_ctx.c index 713d8f9..3a0fbb7 100644 --- a/src/driver/toks_driver_ctx.c +++ b/src/driver/toks_driver_ctx.c @@ -34,6 +34,7 @@ const ntapi_vtbl * toks_ntapi; /* daemon */ static struct toks_daemon_ctx toks_daemon_ctx; +static const nt_guid toks_daemon_default_guid = TOKS_PORT_GUID_DAEMON; /* package info */ static const struct toks_source_version toks_src_version = { @@ -169,6 +170,8 @@ int toks_get_driver_ctx( const struct argv_option * optv[TOKS_OPTV_ELEMENTS]; struct argv_meta * meta; struct argv_entry * entry; + struct argv_entry * uuid; + nt_guid svcguid; const char * program; char * targv[TOKS_SARGV_ELEMENTS]; @@ -191,7 +194,12 @@ int toks_get_driver_ctx( STDERR_FILENO))) return -1; + if (!(flags & TOKS_DRIVER_MODE_CLIENT)) + flags |= TOKS_DRIVER_MODE_SERVER; + + uuid = 0; program = argv_program_name(argv[0]); + memset(&cctx,0,sizeof(cctx)); cctx.drvflags = flags; cctx.eargv = sargv.eargv; @@ -222,12 +230,25 @@ int toks_get_driver_ctx( case TAG_SYSROOT: cctx.sysroot = entry->arg; break; + + case TAG_UUID: + uuid = entry; + break; } } else /* strict */ return toks_driver_usage(program,0,optv,meta); } + if (uuid && ntapi->tt_string_to_guid_utf8(uuid->arg,&svcguid)) { + if (flags & TOKS_DRIVER_VERBOSITY_ERRORS) + toks_dprintf(STDERR_FILENO, + "%s: error: '%s' is not a valid service guid (did you forget the braces?)", + program,uuid->arg); + return toks_get_driver_ctx_fail(meta); + + } + if (cctx.sysroot && toks_open_dir(&cctx.hroot,0,cctx.sysroot,false)) { if (flags & TOKS_DRIVER_VERBOSITY_ERRORS) toks_dprintf(STDERR_FILENO, @@ -239,11 +260,17 @@ int toks_get_driver_ctx( if (!(ctx = toks_driver_ctx_alloc(meta,&cctx))) return toks_get_driver_ctx_fail(meta); - if (toks_daemon_init(&toks_daemon_ctx,cctx.drvflags)) - return toks_get_driver_ctx_fail(meta); + ntapi->tt_guid_copy( + &ctx->uuid, + uuid ? &svcguid : &ctx->rtdata->srv_guid); + + if (cctx.drvflags & TOKS_DRIVER_MODE_SERVER) + if (toks_daemon_init(&toks_daemon_ctx,&ctx->uuid)) + return toks_get_driver_ctx_fail(meta); ctx->ctx.program = program; ctx->ctx.cctx = &ctx->cctx; + ctx->cctx.uuid = &ctx->uuid; *pctx = &ctx->ctx; return TOKS_OK; diff --git a/src/internal/toksvc_daemon_impl.h b/src/internal/toksvc_daemon_impl.h index d5ed546..07c43a4 100644 --- a/src/internal/toksvc_daemon_impl.h +++ b/src/internal/toksvc_daemon_impl.h @@ -29,7 +29,7 @@ struct toks_daemon_ctx { void * hevent_internal_client_ready; }; -int32_t __stdcall toks_daemon_init(struct toks_daemon_ctx *, uint64_t); +int32_t __stdcall toks_daemon_init(struct toks_daemon_ctx *, const nt_guid *); int32_t __stdcall toks_daemon_loop(void *); int32_t __stdcall toks_daemon_connect(nt_tty_port_msg *); int32_t __stdcall toks_daemon_signal(nt_tty_port_msg *); diff --git a/src/internal/toksvc_driver_impl.h b/src/internal/toksvc_driver_impl.h index fd018a3..4222638 100644 --- a/src/internal/toksvc_driver_impl.h +++ b/src/internal/toksvc_driver_impl.h @@ -22,6 +22,7 @@ enum app_tags { TAG_VERSION, TAG_DAEMON, TAG_SYSROOT, + TAG_UUID, }; struct toks_client_ctx { @@ -36,6 +37,7 @@ struct toks_driver_ctx_impl { struct toks_client_ctx clctx; struct toks_common_ctx cctx; struct toks_driver_ctx ctx; + nt_guid uuid; }; static inline struct toks_driver_ctx_impl * toks_get_driver_ictx(const struct toks_driver_ctx * dctx) @@ -50,6 +52,20 @@ static inline struct toks_driver_ctx_impl * toks_get_driver_ictx(const struct to return 0; } +static inline nt_rtdata * toks_get_driver_rtdata(const struct toks_driver_ctx * dctx) +{ + struct toks_driver_ctx_impl * ictx; + ictx = toks_get_driver_ictx(dctx); + return ictx->rtdata; +} + +static inline const nt_guid * toks_get_driver_uuid(const struct toks_driver_ctx * dctx) +{ + struct toks_driver_ctx_impl * ictx; + ictx = toks_get_driver_ictx(dctx); + return &ictx->uuid; +} + int32_t toks_open_file(void ** hfile, void * hat, const char * arg, bool fprivate); int32_t toks_open_dir(void ** hfile, void * hat, const char * arg, bool fprivate); diff --git a/src/skin/toks_skin_default.c b/src/skin/toks_skin_default.c index 4356438..0fe9d3e 100644 --- a/src/skin/toks_skin_default.c +++ b/src/skin/toks_skin_default.c @@ -13,11 +13,14 @@ const struct argv_option toks_default_options[] = { "and set it to be the child's intial root directory."}, {"daemon", 0,TAG_DAEMON,ARGV_OPTARG_OPTIONAL,0,"default|always|never",0, - "create a daemon thread and handle signals sent by the " - "application's own controlling terminal. The default is " - "to create a daemon thread when toksvc runs as a stand-alone " - "program, and defer the task to the main utility in all other " - "cases."}, + "have the service's daemon thread handle signals sent by the " + "application's own controlling terminal. The default is for " + "the daemon thread to handle signals when the service runs as " + "a stand-alone program, and defer the task to the main utility " + "in all other cases."}, + + {"uuid", 'u',TAG_UUID,ARGV_OPTARG_REQUIRED,0,0,"", + "set the service identifier to %s."}, {0,0,0,0,0,0,0,0} }; diff --git a/src/toksvc.c b/src/toksvc.c index 3637e57..7af9d30 100644 --- a/src/toksvc.c +++ b/src/toksvc.c @@ -14,6 +14,12 @@ static const nt_guid toksvc_daemon_guid = TOKS_PORT_GUID_DAEMON; static void toksvc_exit(int code) { + /* server mode? */ + if (code == NT_STATUS_SERVICE_NOTIFICATION) + ntapi->zw_terminate_thread( + NT_CURRENT_THREAD_HANDLE, + code); + /* posix exit code? */ if ((code >= 0) && (code <= 0xff)) code <<= 8;