Browse Source

initial trun command for raw windows commandline execution (non-capturing alternative to exec craziness)

master
Julian Noble 1 year ago
parent
commit
facd6a6f23
  1. 6
      src/modules/punk-0.1.tm
  2. 3
      src/modules/punk/config-0.1.tm
  3. 96
      src/modules/shellrun-0.1.tm

6
src/modules/punk-0.1.tm

@ -6711,6 +6711,12 @@ namespace eval punk {
interp alias {} psls {} puts stderr $ps_missing interp alias {} psls {} puts stderr $ps_missing
interp alias {} psps {} puts stderr $ps_missing interp alias {} psps {} puts stderr $ps_missing
} }
proc psencode {cmdline} {
}
proc psdecode {encodedcmd} {
}
proc repl {startstop} { proc repl {startstop} {
if {$startstop eq "stop"} { if {$startstop eq "stop"} {

3
src/modules/punk/config-0.1.tm

@ -10,6 +10,9 @@ namespace eval punk::config {
variable running variable running
variable known_punk_env_vars variable known_punk_env_vars
#todo - XDG_DATA_HOME etc
#https://specifications.freedesktop.org/basedir-spec/latest/
# see also: http://hiphish.github.io/blog/2020/08/30/dotfiles-were-a-mistake/
variable vars variable vars
set vars [list \ set vars [list \

96
src/modules/shellrun-0.1.tm

@ -96,6 +96,69 @@ namespace eval shellrun {
return [list runopts $runopts cmdargs $cmdargs] return [list runopts $runopts cmdargs $cmdargs]
} }
#2023 - a more serious attempt at proper raw argument passing to windows
proc trun {args} {
#puts stdout --rawargs-list--$args
set_last_run_display [list]
set splitargs [get_run_opts $args]
set runopts [dict get $splitargs runopts]
set cmdargs [dict get $splitargs cmdargs]
if {"-nonewline" in $runopts} {
set nonewline 1
} else {
set nonewline 0
}
set cmdline ""
foreach a $args {
append cmdline "[punk::objclone $a] "
}
if {[llength $args] > 0} {
set cmdline [string range $cmdline 0 end-1] ;#trim 1 trailing space
}
#puts stdout "==args_as_string==$cmdline"
#don't run regexp on the list rep
set wordranges [regexp -inline -all -indices {\S+} $cmdline]
#set wordparts [list]
set cmdlineparts [list]
foreach range $wordranges {
set word [string range $cmdline {*}$range]
lappend cmdlineparts [punk::objclone $word]
#lappend wordparts [punk::objclone $word]
}
#puts stdout -->$wordparts
#set listinfo [shellfilter::list_element_info $wordparts]
#puts stdout --$listinfo
set cmdline ""
set i 0
#-----------
#the list_element_info analysys left in for debugging in case the quoting/internal rep mechanism in Tcl changes from version to version
#we hopefully don't need to check the "wouldescape" "wouldescape" member of listinfo if we've been careful enough
#----------
foreach w $cmdlineparts {
#set wordinfo [dict get $listinfo $i]
#if {[dict get $wordinfo wouldbrace] && [dict get $wordinfo head_tail_names] eq {lbrace rbrace}} {
# append cmdline [string range $w 1 end-1]
#} else {
append cmdline $w
#}
append cmdline " "
incr i
}
# -----------------
#puts stdout --1>$cmdline
#All this mucking about is because:
#cmdline could be something like: cmd /c echo x\"x^b
#when represented as a list - but we just want it as: cmd /c echo x"x^b
# -----------------
set cmdline [string range $cmdline 0 end-1]
shellrun::tw_run $cmdline
}
proc run {args} { proc run {args} {
set_last_run_display [list] set_last_run_display [list]
@ -546,7 +609,7 @@ namespace eval shellrun {
proc repl_runraw {args} { proc repl_runraw {args} {
error "runraw: only available in repl as direct call - not from script" error "runraw: only available in repl as direct call - not from script"
} }
#we can only call runraw with a single (presumably braced) string if we want to use it from both repl and tcl scripts #we can only call runraw with a single (presumably braced) string if we want to use it from both repl and tcl scripts (why? todo with unbalanced quotes/braces?)
proc runraw {commandline} { proc runraw {commandline} {
#runraw fails as intended - because we can't bypass exec/open interference quoting :/ #runraw fails as intended - because we can't bypass exec/open interference quoting :/
set_last_run_display [list] set_last_run_display [list]
@ -669,11 +732,27 @@ namespace eval shellrun {
} }
namespace eval shellrun { namespace eval shellrun {
proc twapi_exec {cmdline} { proc twapi_exec {cmdline args} {
package require twapi
set psinfo [twapi::create_process {} -cmdline $cmdline {*}$args]
}
proc tw_run {cmdline} {
#twapi::create_file to redirect?
package require twapi package require twapi
twapi::create_process {} -cmdline $cmdline set psinfo [twapi::create_process {} -cmdline $cmdline -returnhandles 1]
lassign $psinfo _pid _tid hpid htid
set waitresult [twapi::wait_on_handle $hpid -wait -1]
#e.g timeout, signalled
if {$waitresult eq "timeout"} {
puts stderr "tw_run: timeout waiting for process"
}
set code [twapi::get_process_exit_code $hpid]
twapi::close_handle $htid
twapi::close_handle $hpid
return [dict create exitcode $code]
} }
interp alias {} run {} shellrun::run interp alias {} run {} shellrun::run
interp alias {} trun {} shellrun::trun
interp alias {} sh_run {} shellrun::sh_run interp alias {} sh_run {} shellrun::sh_run
interp alias {} runout {} shellrun::runout interp alias {} runout {} shellrun::runout
interp alias {} sh_runout {} shellrun::sh_runout interp alias {} sh_runout {} shellrun::sh_runout
@ -695,6 +774,17 @@ namespace eval shellrun {
} }
namespace eval shellrun {
proc test_cffi {} {
package require test_cffi
cffi::Wrapper create ::shellrun::kernel32 [file join $env(windir) system32 Kernel32.dll]
::shellrun::kernel32 stdcall CreateProcessA
#todo - stuff.
return ::shellrun::kernel32
}
}
package provide shellrun [namespace eval shellrun { package provide shellrun [namespace eval shellrun {
variable version variable version
set version 0.1 set version 0.1

Loading…
Cancel
Save