summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sysif.c2
-rw-r--r--sysif.h3
-rw-r--r--txr.128
-rw-r--r--txr.c8
4 files changed, 40 insertions, 1 deletions
diff --git a/sysif.c b/sysif.c
index d7272dcf..e9c422ec 100644
--- a/sysif.c
+++ b/sysif.c
@@ -524,7 +524,7 @@ static val dup_wrap(val old, val neu)
return num(dup2(c_num(old), c_num(neu)));
}
-static val exec_wrap(val file, val args_opt)
+val exec_wrap(val file, val args_opt)
{
val args = default_bool_arg(args_opt);
int nargs = c_num(length(args)) + 1;
diff --git a/sysif.h b/sysif.h
index 093e4152..62712387 100644
--- a/sysif.h
+++ b/sysif.h
@@ -43,6 +43,9 @@ typedef long off_t;
#endif
val getenv_wrap(val name);
+#if HAVE_FORK_STUFF
+val exec_wrap(val file, val args_opt);
+#endif
#if HAVE_SYS_STAT
struct stat;
val stat_to_struct(struct stat st);
diff --git a/txr.1 b/txr.1
index 1a8801d7..0032d4c9 100644
--- a/txr.1
+++ b/txr.1
@@ -757,6 +757,26 @@ or
.code -P
options.
+.coIP --reexec
+On platforms which support the POSIX
+.code exec
+family of functions, this option causes \*(TX to re-execute itself.
+The re-executed image receives the remaining arguments which follow
+the
+.code --reexec
+argument. Note: this option is useful for supporting setuid operation in
+"hash hang" scripts. On some platforms, the interpreter designated by
+a "hash bang" script runs without altered privilege, even if that
+interpreter is installed setuid. If the interpreter is executed directly,
+then setuid applies to it, but not if it is executed via "hash bang".
+If the
+.code --reexec
+option is used in the interpreter command line of such a script, the
+interpreter will re-execute itself, thereby gaining the setuid privilege.
+The re-executed image will then obtain the script name from the arguments
+which are passed to it and determine whether that script will run setuid.
+See the section SETUID/SETGID OPERATION.
+
.coIP --gc-debug
This option enables a behavior which stresses the garbage collector with
frequent garbage collection requests. The purpose is to make it more likely
@@ -1101,6 +1121,14 @@ script name is inserted anywhere among them, possibly multiple times. Arguments
for the interpreter can be encoded, as well as arguments to be processed by the
script.
+\*(TX supports setuid hash bang scripting, even on platforms that do not
+support setuid and setgid attributes on hash bang scripts. On such
+platforms, \*(TX has to be installed setuid/setgid. See the section
+SETUID/SETGID OPERATION. On some platforms, it may also be necessary to
+to use the
+.code --reexec
+option.
+
.SS* Whitespace
Outside of directives, whitespace is significant in \*(TX queries, and represents
a pattern match for whitespace in the input. An extent of text consisting of
diff --git a/txr.c b/txr.c
index 5a79611e..b8e6267f 100644
--- a/txr.c
+++ b/txr.c
@@ -153,6 +153,9 @@ static void help(void)
"--compat=N Synonym for -C N\n"
"--gc-delta=N Invoke garbage collection when malloc activity\n"
" increments by N megabytes since last collection.\n"
+#if HAVE_FORK_STUFF
+"--reexec Re-execute TXR with remaining arguments.\n"
+#endif
"--debug-autoload Allow debugger to step through library auto-loading.\n"
"--debug-expansion Allow debugger to step through macro-expansion of query.\n"
"--yydebug Debug Yacc parser, if compiled with YYDEBUG support.\n"
@@ -603,6 +606,11 @@ int txr_main(int argc, char **argv)
} else if (equal(opt, lit("lisp"))) {
txr_lisp_p = t;
continue;
+#if HAVE_FORK_STUFF
+ } else if (equal(opt, lit("reexec"))) {
+ exec_wrap(prog_path, arg_list);
+ return EXIT_FAILURE;
+#endif
} else if (equal(opt, lit("debugger"))) {
drop_privilege();
#if CONFIG_DEBUG_SUPPORT