From fe6ef8b5e2810495d9ef4620be30806857351202 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Mon, 28 Jan 2019 06:28:06 -0800 Subject: command line: support -f in Hash Bang Null Hack. * txr.c (txr_main): In processing the -f option, if there is already an input source, but its name exactly matches the argument of the -f option, then ignore the -f and its option intead of terminating with a diagnostic. This allows the user to use -f in the Null Hack to achieve the usual trick of allowing the script to take options passed through to the interpreter. * txr.1: Documented. --- txr.1 | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ txr.c | 8 +++++--- 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/txr.1 b/txr.1 index e7364436..6d0c7985 100644 --- a/txr.1 +++ b/txr.1 @@ -1412,6 +1412,64 @@ be taken to detect and handle that situation, either by means of the variable, or else by some logic which infers that the processing of the hash bang line hadn't been performed. +.coNP Passing Options to \*(TX via Hash Bang Null Hack + +It is possible to use the Hash Bang Null Hack, such that the resulting +executable program recognizes \*(TX options. This is made possible by +a special behavior in the processing of the +.code -f +option. + +For instance, suppose that the effect of the following familiar hash bang line +is required: + +.cblk + #!/path/to/txr -f +.cble + +However, suppose there is also a requirement to use the +.code env +utility to find \*(TX. Furthermore, the operation system allows only one hash +bang argument. Using the Null Hack, this is rewritten as: + +.cblk + #!/usr/bin/env txr-f +.cble + +then if the script is invoked with arguments +.codn "-a b c" , +the command line will ultimately be transformed into: + +.cblk + /path/to/txr -f /path/to/scriptfile -i a b c +.cble + +which allows \*(TX to process the +.code -i +option, leaving +.codn a , +.code b +and +.code c +as arguments for the script. + +However, note that there is a subtle issue with the +.code -f +option that has been inserted via the Null Hack: namely, this +insertion happens after +\*(TX has opened the script file and read the hash bang line from it. +This means that when the inserted +.code -f +option is being processed, the script file is already open. +A special behavior occurs. The +.code -f +option processing notices that the argument to +.code -f +is identical to the path name of name of the script file that \*(TX has +already opened for processing. The +.code -f +option and its argument are then skipped. + .NP* Hash Bang and Setuid \*(TX supports setuid hash bang scripting, even on platforms that do not support setuid and setgid attributes on hash bang scripts. On such diff --git a/txr.c b/txr.c index 584ec159..be77ca1c 100644 --- a/txr.c +++ b/txr.c @@ -839,13 +839,15 @@ int txr_main(int argc, char **argv) parse_stream = make_string_byte_input_stream(specstring); break; case 'f': + spec_file = arg; if (parse_stream) { + if (equal(spec_file, spec_file_str)) + break; format(std_error, - lit("~a: -f ~a: input file has already been established\n"), - prog_string, spec_file, nao); + lit("~a: -f ~a: input source ~a has already been established\n"), + prog_string, arg, spec_file_str, nao); return EXIT_FAILURE; } - spec_file = arg; if (wcscmp(c_str(spec_file), L"-") != 0) { open_txr_file(spec_file, &txr_lisp_p, &spec_file_str, &parse_stream); simulate_setuid_setgid(parse_stream); -- cgit v1.2.3