summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/ptycon/ptycon.h1
-rw-r--r--src/driver/ptyc_driver_ctx.c59
-rw-r--r--src/internal/ptycon_driver_impl.h1
-rw-r--r--src/skin/ptyc_skin_default.c9
4 files changed, 68 insertions, 2 deletions
diff --git a/include/ptycon/ptycon.h b/include/ptycon/ptycon.h
index ce0fbd7..78282cf 100644
--- a/include/ptycon/ptycon.h
+++ b/include/ptycon/ptycon.h
@@ -61,6 +61,7 @@ struct ptyc_common_ctx {
nt_pty * hpts;
nt_pty * hptm;
char ** catv;
+ char ** eargv;
};
struct ptyc_driver_ctx {
diff --git a/src/driver/ptyc_driver_ctx.c b/src/driver/ptyc_driver_ctx.c
index ab4cbdb..459abe2 100644
--- a/src/driver/ptyc_driver_ctx.c
+++ b/src/driver/ptyc_driver_ctx.c
@@ -51,6 +51,11 @@ struct ptyc_driver_ctx_alloc {
const char * units[];
};
+struct ptyc_split_vector {
+ char ** targv;
+ char ** eargv;
+};
+
static int32_t ptyc_once = 0;
static int32_t ptyc_vtbl_init(void)
@@ -161,6 +166,45 @@ static int ptyc_get_driver_ctx_fail(struct argv_meta * meta)
return -1;
}
+#define PTYC_SARGV_ELEMENTS 1024
+
+static int ptyc_split_argv(
+ char ** argv,
+ struct ptyc_split_vector * sargv)
+{
+ ptrdiff_t argc;
+ char ** parg;
+
+ /* argc */
+ for (parg=argv; *parg; )
+ parg++;
+
+ if ((argc = parg - argv) >= PTYC_SARGV_ELEMENTS)
+ return -1;
+
+ /* clone argv into targv */
+ ntapi->tt_aligned_block_memset(
+ (uintptr_t *)sargv->targv,
+ 0,PTYC_SARGV_ELEMENTS*sizeof(char *));
+
+ ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)sargv->targv,
+ (uintptr_t *)argv,
+ argc*sizeof(char *));
+
+ /* eargv */
+ for (parg=sargv->targv; *parg; parg++) {
+ if (!(strcmp(*parg,"-e")) || !(strcmp(*parg,"--exec"))) {
+ sargv->eargv = parg;
+ sargv->eargv++;
+ *parg = 0;
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
int ptyc_get_driver_ctx(
char ** argv,
char ** envp,
@@ -169,11 +213,13 @@ int ptyc_get_driver_ctx(
{
struct ptyc_driver_ctx_impl * ctx;
struct ptyc_common_ctx cctx;
+ struct ptyc_split_vector sargv;
const struct argv_option * options;
struct argv_meta * meta;
struct argv_entry * entry;
size_t nunits;
const char * program;
+ char * targv[PTYC_SARGV_ELEMENTS];
(void)envp;
@@ -185,13 +231,20 @@ int ptyc_get_driver_ctx(
options = ptyc_default_options;
- if (!(meta = argv_get(argv,options,ptyc_argv_flags(flags))))
+ sargv.targv = targv;
+ sargv.eargv = 0;
+
+ if (ptyc_split_argv(argv,&sargv))
+ return -1;
+
+ if (!(meta = argv_get(sargv.targv,options,ptyc_argv_flags(flags))))
return -1;
nunits = 0;
program = argv_program_name(argv[0]);
memset(&cctx,0,sizeof(cctx));
cctx.drvflags = flags;
+ cctx.eargv = sargv.eargv;
if (!argv[1] && (flags & PTYC_DRIVER_VERBOSITY_USAGE))
return ptyc_driver_usage(program,0,options,meta);
@@ -243,7 +296,9 @@ int ptyc_get_driver_ctx(
cctx.drvflags |= PTYC_DRIVER_DBG_WAIT;
break;
}
- }
+ } else
+ /* strict */
+ return ptyc_driver_usage(program,0,options,meta);
}
if (!(ctx = ptyc_driver_ctx_alloc(meta,&cctx,nunits)))
diff --git a/src/internal/ptycon_driver_impl.h b/src/internal/ptycon_driver_impl.h
index b1eefc7..03f0c9b 100644
--- a/src/internal/ptycon_driver_impl.h
+++ b/src/internal/ptycon_driver_impl.h
@@ -27,6 +27,7 @@ enum app_tags {
TAG_DAEMON,
TAG_DEBUG,
TAG_CAT,
+ TAG_EXEC,
TAG_WAIT,
};
diff --git a/src/skin/ptyc_skin_default.c b/src/skin/ptyc_skin_default.c
index 1239947..814f6c2 100644
--- a/src/skin/ptyc_skin_default.c
+++ b/src/skin/ptyc_skin_default.c
@@ -8,6 +8,15 @@ const struct argv_option ptyc_default_options[] = {
{"help", 'h',TAG_HELP,ARGV_OPTARG_OPTIONAL,0,"short|long",0,
"show usage information [listing %s options only]"},
+ {"-exec", 0,TAG_EXEC,ARGV_OPTARG_REQUIRED,
+ ARGV_OPTION_HYBRID_ONLY | ARGV_OPTION_HYBRID_SPACE,
+ 0,"<cmd> ... [argv] ...",
+ "execute %s; default is /bin/sh."},
+
+ {"e", 0,TAG_EXEC,ARGV_OPTARG_REQUIRED,
+ ARGV_OPTION_HYBRID_ONLY | ARGV_OPTION_HYBRID_SPACE,
+ 0,0,"synonym for --exec."},
+
{"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 "