For Programmers: Free Programming Magazines  


Home > Archive > Tcl > June 2006 > exec failures in menus under starkits









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author exec failures in menus under starkits
Lan

2006-06-24, 8:23 am

Please know that I have read lots on the tcler's wiki, Welsh et al, and
Jean Claude Wipple's original Starkit web site, as well as these
archives, before asking. Probably my answer is there somewhere, but so
far I've missed it.

I want to have a starkit that is a menu that calls individual programs
using exec. The goal is a cross platform (Linux/Windows) distribution
package that can be added to as apps are developed by adding the apps
to the .vfs directory structure and rewrapping.

Inside the prototype, the menu.tcl lives in .../apps-menu and the first
app, foo.tcl, lives in .../apps-menu/foo.

..../apps-menu/menu.tcl has the code:

if {[info exists starkit::topdir]} {
set progDir [file join $starkit::topdir lib app-menu]
} else {
set progDir [file dirname [info script]]
}

.... and later ...

..applications.application_menu add command -label "FOO" \
-command {exec [file join $progDir foo foo.tcl]}

This works when run from the .vfs directory, but gives this error from
the tclkit:

couldn't execute
"/home/lbarnes/menu/menu.kit/lib/app-menu/foo/foo.tcl": not a directory

I'm sure if I understood why it says "not a directory" I'd be closer to
understanding the error. I _know_ it's not a directory. Why does the
starkit think it might be?

But more importantly, what am I not understanding?

TIA,

~Lan

Aric Bills

2006-06-24, 8:23 am


> .applications.application_menu add command -label "FOO" \
> -command {exec [file join $progDir foo foo.tcl]}
>
> This works when run from the .vfs directory, but gives this error from
> the tclkit:
>
> couldn't execute
> "/home/lbarnes/menu/menu.kit/lib/app-menu/foo/foo.tcl": not a directory
>
> I'm sure if I understood why it says "not a directory" I'd be closer to
> understanding the error. I _know_ it's not a directory. Why does the
> starkit think it might be?
>
> But more importantly, what am I not understanding?


If you know it's not a directory, then it follows that you shouldn't
tell the exec command that it IS a directory :) [exec] relies on a
system call to fire off programs, but the system (unlike Tcl) can't use
the virtual file system that the starkit is using. To make this sort
of thing work, you'll need to copy the program to a real directory and
fire it off from there. This isn't a limitation of Tcl or Tclkit, but
rather a limitation of the operating system.

Lan

2006-06-24, 8:23 am


Aric Bills wrote:
>
> If you know it's not a directory, then it follows that you shouldn't
> tell the exec command that it IS a directory :) [exec] relies on a
> system call to fire off programs, but the system (unlike Tcl) can't use
> the virtual file system that the starkit is using. To make this sort
> of thing work, you'll need to copy the program to a real directory and
> fire it off from there. This isn't a limitation of Tcl or Tclkit, but
> rather a limitation of the operating system.


Not to carp, since you've answered my question on why it doesn't work
quite nicely (thank you), this _is_ a limitation of tclkit, and _I_
didn't treat it as a directory, I wrote the command for execing an
executable, which tclkit apparently cannot execute properly.

So I will rethink my distribution strategy and perhaps fall back on
zip/tar. But thank you again for saving me more frustration on this ...
feature of starkits.

Don Porter

2006-06-24, 8:23 am

Lan wrote:
[color=darkred]

Aric Bills wrote:[color=darkred]
[color=darkred]
> ...this _is_ a limitation of tclkit, and _I_
> didn't treat it as a directory, I wrote the command for execing an
> executable, which tclkit apparently cannot execute properly.


Did either [file executable] or [auto_execok] tell you that path
was an executable? If so, that's a bug in Tcl, so please file it.

If not, yet you tried to [exec] it anyway, then the fault is in your
code.

--
| Don Porter Mathematical and Computational Sciences Division |
| donald.porter@nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|_______________________________________
_______________________________|
Alan Anderson

2006-06-24, 8:23 am

> > > couldn't execute

"Lan" <lan@falleagle.net> wrote:
[color=darkred]
> Not to carp, since you've answered my question on why it doesn't work
> quite nicely (thank you), this _is_ a limitation of tclkit, and _I_
> didn't treat it as a directory, I wrote the command for execing an
> executable, which tclkit apparently cannot execute properly.


I'm pretty sure /home/lbarnes/menu/menu.kit is not a directory. Your
call to [exec] treats it as one. Once more -- it's not tclkit which has
a problem executing it, it's the operating system.

> So I will rethink my distribution strategy and perhaps fall back on
> zip/tar. But thank you again for saving me more frustration on this ...
> feature of starkits.


That's actually a good way of describing it. The ability to read the
contents of a virtual filesystem is indeed a feature of starkits. It is
unfortunately *not* a feature of the underlying OS, so if you need the
OS to be able to see a file in a VFS, the code has to copy it out to
somewhere that the OS can deal with.
Cameron Laird

2006-06-24, 8:23 am

In article <1150833492.723510.276880@r2g2000cwb.googlegroups.com>,
Aric Bills <aric.bills@gmail.com> wrote:
>
>
>If you know it's not a directory, then it follows that you shouldn't
>tell the exec command that it IS a directory :) [exec] relies on a
>system call to fire off programs, but the system (unlike Tcl) can't use
>the virtual file system that the starkit is using. To make this sort
>of thing work, you'll need to copy the program to a real directory and
>fire it off from there. This isn't a limitation of Tcl or Tclkit, but
>rather a limitation of the operating system.
>


.... but one quite a few of us hope we can circumvent at some point. For
now, though, yes, the point is that the $COMMAND in

exec $COMMAND ...

must appear in the real filesystem, not any of Tcl's VFSs.

If, like the original poster, you *need* to execute out of the VFS, your
only current recourse is to copy the executable image from the VFS to a
$TEMP directory in the real filesystem, then execute *that* image. That's
what Mr. Bills mentions above.
Bruce Hartweg

2006-06-24, 8:23 am

Lan wrote:
> Aric Bills wrote:
>
> Not to carp, since you've answered my question on why it doesn't work
> quite nicely (thank you), this _is_ a limitation of tclkit, and _I_
> didn't treat it as a directory, I wrote the command for execing an
> executable, which tclkit apparently cannot execute properly.


no, tclkit doesn't execute anything, the OS executes things, and
it can only execute things it knows about (i.e. it's own filesystems)
you code create progdir which is /home/lbarnes/menu/menu.kit/lib/app-menu/
to you, and your code (and tclkit itself) that is a directory, but to
the OS it is NOT. you can still distribute your code this way, but your
app needs to take an extra step of copying the executables from inside
this VFS system to the external file system and then exec that. It can
be done invisible to the user.

Bruce
Lan

2006-06-24, 8:23 am


Bruce Hartweg wrote:
> Lan wrote:
>
> no, tclkit doesn't execute anything, the OS executes things, and
> it can only execute things it knows about (i.e. it's own filesystems)
> you code create progdir which is /home/lbarnes/menu/menu.kit/lib/app-menu/
> to you, and your code (and tclkit itself) that is a directory, but to
> the OS it is NOT. you can still distribute your code this way, but your
> app needs to take an extra step of copying the executables from inside
> this VFS system to the external file system and then exec that. It can
> be done invisible to the user.
>
> Bruce


I cannot "blame" the OS for being unable to navigate a virtual file
system it knows nothing about. No OS has been more accomodating in
supporting a vast variety of OSs than Linux, but even if it did, my
main distribution target is Microsoft, and filing a request for support
of the VFS might not be the best use of my time.

Were starkits essential to my distribution requirements for some
reason, I could obviously modify my code to copy the executables out to
the real OS area. But part of how I sold Tcl/Tk to my bosses was by
pointing out how truly cross-platform it is -- I can code on Linux
(where I get the grown-up tool sets) and deploy to Microsoft without
changing a line of code[0]. However, I can now see that if I persist in
pursuing starkits, this is no longer close to true, and added
development time is a deal killer -- these programs are not my first
responsibility.

It occurred to me at lunch that perhaps the menu program could be a
starkit and all my called apps could be separate starkits, so the menu
call would be something akin to

exec $starkit::topdir/../foo.kit

.... but I'm not sure this buys me much more than a zip file within my
distribution environment. So that's the way I'm gonna go -- zip/tar.

BTW, when I said that I "knew" that .../foo/foo.tcl was not a
directory, I meant that (until it was clarified) I thought it was an
unambiguous path through a directory chain to an executable file. But
now I understand that it is a mere mirage, understood by tclkit but not
by either target OS.

I wouldn't want anything I've said in this thread to be interpreted as
disrespect for starkits. They're transcendently . It's just that
different people have different requirements.

[0] OK, I have one if-else structure where I test for OS in order to
select a fixed width font for a columnar pick list. A table pick list
would probably do the same thing better, but I haven't branched out
from the basic widgets yet. I'm really a rank beginner.

Aric Bills

2006-06-24, 8:23 am

> Not to carp, since you've answered my question on why it doesn't work
> quite nicely (thank you), this _is_ a limitation of tclkit, and _I_
> didn't treat it as a directory, I wrote the command for execing an
> executable, which tclkit apparently cannot execute properly.


Okay, I see what you're saying. I think it's a question of the
semantics of the [exec] command, but I can imagine some interesting
possibilities where Tcl would understand what you're trying to
accomplish and take care of the details like making a temporary copy of
your virtual file in the real filesystem and then calling that file,
and then cleaning up when [exec] returns. If there were some consensus
on how this process should work, it would make an interesting TIP.

As a shorter-term solution, you could code up a wrapper for exec that
will check whether the file being referred to is real or virtual; if
virtual, make a temporary copy in the real filesystem; fire off the
program; and clean up as necessary at the end.

Donald Arseneau

2006-06-24, 8:23 am

"Lan" <lan@falleagle.net> writes:

> this _is_ a limitation of tclkit, and _I_ didn't treat it as
> a directory, I wrote the command for execing an
> executable, which tclkit apparently cannot execute properly.


Such a "gotcha" should merit a mention in the tclkit documentation.

I still can't call it a bug of tclkit. Some systems are set up so
they won't execute programs on a CD (as protection against trojan
horse attacks). So what is buggy when you bundle your tcl app plus
executable onto a CD for distribution?


--
Donald Arseneau asnd@triumf.ca
Donald Arseneau

2006-06-24, 8:23 am

"Lan" <lan@falleagle.net> writes:

> the real OS area. But part of how I sold Tcl/Tk to my bosses was by
> pointing out how truly cross-platform it is -- I can code on Linux
> (where I get the grown-up tool sets) and deploy to Microsoft without
> changing a line of code[0].


I don't see how that claim could possibly stand up if you are using exec,
with or without kit! Executables absolutely have to be different for
different OSs. You might mighrate to pure Tcl/Tk and then both problems
with exec will disappear.


--
Donald Arseneau asnd@triumf.ca
Dan Smart

2006-06-24, 8:23 am

On 2006-06-20 18:14:57 -0400, "Lan" <lan@falleagle.net> said:[color=darkred]

If you really are only ever trying to exec scripts, then don't exec
them, restructure them slightly and [source] them ([source] is vfs
aware).

Without a bit more information as to what you are trying to achieve,
it's difficult to be more specific, but does the following help:

foo.tcl:
namespace eval foo {
proc main {args} {
puts "Hello [join $args]"
}
}

Your main application:
....
..applications.application_menu add command -label "FOO" \
-command {source [file join $progDir foo foo.tcl];
::foo::main Pod People}


Dan

Alan Anderson

2006-06-24, 8:23 am

"Lan" <lan@falleagle.net> wrote:

> ...part of how I sold Tcl/Tk to my bosses was by
> pointing out how truly cross-platform it is -- I can code on Linux
> (where I get the grown-up tool sets) and deploy to Microsoft without
> changing a line of code[0]...


If you're using [exec], you've thrown the cross-platform argument out
the window anyway.

> However, I can now see that if I persist in
> pursuing starkits, this is no longer close to true, and added
> development time is a deal killer -- these programs are not my first
> responsibility.


There's not a lot of development time needed. Make your own [exec] that
copies the file out into the OS-native filesystem first, then exec's it,
then deletes it when finished.

> It occurred to me at lunch that perhaps the menu program could be a
> starkit and all my called apps could be separate starkits, so the menu
> call would be something akin to
>
> exec $starkit::topdir/../foo.kit
>
> ... but I'm not sure this buys me much more than a zip file within my
> distribution environment. So that's the way I'm gonna go -- zip/tar.


Wait, what's this? Are your 'called apps' Tcl scripts as well? You
shouldn't be using [exec] on them in the first place! Make appropriate
use of namespaces and [source] them instead.
Michael A. Cleverly

2006-06-24, 8:23 am

On Tue, 20 Jun 2006, Lan wrote:

> Bruce Hartweg wrote:

Personally I view it more as an impedance mismatch, and not that either
Tcl/Tclkit or the OS is "at fault" per say.
[color=darkred]
>
> I cannot "blame" the OS for being unable to navigate a virtual file
> system it knows nothing about. No OS has been more accomodating in
> supporting a vast variety of OSs than Linux, but even if it did, my
> main distribution target is Microsoft, and filing a request for support
> of the VFS might not be the best use of my time.
>
> Were starkits essential to my distribution requirements for some
> reason, I could obviously modify my code to copy the executables out to
> the real OS area. But part of how I sold Tcl/Tk to my bosses was by
> pointing out how truly cross-platform it is -- I can code on Linux
> (where I get the grown-up tool sets) and deploy to Microsoft without
> changing a line of code[0].


Even running "unwrapped" on Windows (out of the .vfs directory), I doubt
your exec [file join $progDir foo foo.tcl] command would work. On *nix
(given that it works) you must have some variant of:

#!/bin/sh
#\
exec <interpreter> $0

style magic so that the shell knows what interpreter to run the script
under. (See http://wiki.tcl.tk/812).

Under Windows I expect you'd get a "no such file or directory" error back.

So even if tclkit copied the script to be executed out of the .vfs and to
some (real) temporary location on disk your code still would need to be
modified to remove the (*nix) platform specific behavior you're relying
on.

A more robust method of exec would be:

exec [info nameofexecutable] [file join $progDir foo foo.tcl]

I anticipate that should work on both *nix and Windows from within an
unwrapped .vfs directory (though I don't have a Windows machine at home to
test it on).

However that still won't help your situation running wrapped (as is)
because the new tclkit process won't have access to the .vfs either.

In this case what you'd want is something more along the lines of:

set ::self [file normalize [file join [pwd] $::argv0]]
exec [info nameofexecutable] $::self path/within/vfs/to/exec

Then add just as little as a line or two of code within your
main.tcl to [source] just the path/within/vfs/to/exec, if [lindex $argv 0]
exists inside the .vfs, and run your "main" app otherwise.

Again, something along the lines of:

if {[file exists [lindex $::argv 0]]} then {
source [lindex $::argv 0]
} else {
# do whatever you normally did
}

This will give you:

1) Correct behavior when running both wrapped and unwrapped
2) Reliable behavior on *nix and Windows
3) The ability to create a separate OS-level tclkit process to "run"
scripts within your .vfs

> However, I can now see that if I persist in pursuing starkits, this is
> no longer close to true, and added development time is a deal killer --
> these programs are not my first responsibility.
>
> It occurred to me at lunch that perhaps the menu program could be a
> starkit and all my called apps could be separate starkits, so the menu
> call would be something akin to
>
> exec $starkit::topdir/../foo.kit
>
> ... but I'm not sure this buys me much more than a zip file within my
> distribution environment. So that's the way I'm gonna go -- zip/tar.


Here is a contrived example along those lines (and what it buys you is
just a single .kit file on the client):

## foo.vfs/main.tcl
package require starkit
starkit::startup

set ::self [file normalize [file join [pwd] $::argv0]]

proc launch {vfsPath} {
exec [info nameofexecutable] $::self $vfsPath
}

if {[lindex $::argv 0] ne ""} then {
source [lindex $::argv 0]
} else {
puts "Welcome to this contrived example."
puts "The 'master' process is pid # [pid]"
puts ""
while 1 {
puts -nonewline "Please enter a number between 1 and 3 (or anything else to exit): "
flush stdout
set line [gets stdin]
switch -exact -- $line {
1 { puts [launch [file join $::self foo one.tcl]] }
2 { puts [launch [file join $::self foo two.tcl]] }
3 { puts [launch [file join $::self foo three.tcl]] }
default break
}
}
puts "Goodbye."
}

## foo.vfs/foo/one.tcl
puts "You pressed 1. (I'm pid #[pid])"

# foo.vfs/foo/two.tcl
puts "You pressed 2. (I'm pid #[pid])"

# foo.vfs/foo/three.tcl
puts "You pressed 3. (I'm pid #[pid])"

Wrap that all up and you can run foo.kit and see that separate tclkit
processes are being exec'd to run the code in foo/<number>.tcl.
(GUI-ifying this is left as an exercise for the reader ;-).

> BTW, when I said that I "knew" that .../foo/foo.tcl was not a
> directory, I meant that (until it was clarified) I thought it was an
> unambiguous path through a directory chain to an executable file. But
> now I understand that it is a mere mirage, understood by tclkit but not
> by either target OS.
>
> I wouldn't want anything I've said in this thread to be interpreted as
> disrespect for starkits. They're transcendently . It's just that
> different people have different requirements.


Michael
Michael A. Cleverly

2006-06-24, 8:23 am

On Tue, 20 Jun 2006, Donald Arseneau wrote:

> I don't see how that claim could possibly stand up if you are using exec,
> with or without kit! Executables absolutely have to be different for
> different OSs. You might mighrate to pure Tcl/Tk and then both problems
> with exec will disappear.


Except in this case apparently the actual executable is tclkit which,
while different, must be present for the OP to have gotten as far as
encountering this problem. :-)

Michael
Michael A. Cleverly

2006-06-24, 8:23 am

On Tue, 20 Jun 2006, Alan Anderson wrote:

> Wait, what's this? Are your 'called apps' Tcl scripts as well? You
> shouldn't be using [exec] on them in the first place! Make appropriate
> use of namespaces and [source] them instead.


Or if refactoring to use [namespaces] is too burdensome then perhaps
[source]'ing them into individual slave interpreters would be an option...

Michael
Michael A. Cleverly

2006-06-24, 8:23 am

On Tue, 20 Jun 2006, Aric Bills wrote:

>
> Okay, I see what you're saying. I think it's a question of the
> semantics of the [exec] command, but I can imagine some interesting
> possibilities where Tcl would understand what you're trying to
> accomplish and take care of the details like making a temporary copy of
> your virtual file in the real filesystem and then calling that file,
> and then cleaning up when [exec] returns. If there were some consensus
> on how this process should work, it would make an interesting TIP.


As it would be specific to tclkit (and not the Tcl core), I don't think a
TIP would be needed(?).

Tclkit already does this for [load]ing shared libraries (copies to disk,
has the OS load the shared library from disk, and takes care of eventual
cleanup).

Doing something simillar with [exec] isn't impossible, but seems like it
would be awfully messy considering that we could be execing a series of
commands that pipe input to/from one another, etc.

Michael
Aric Bills

2006-06-24, 8:23 am


Michael A. Cleverly wrote:
> On Tue, 20 Jun 2006, Aric Bills wrote:
>
>
> As it would be specific to tclkit (and not the Tcl core), I don't think a
> TIP would be needed(?).


I could imagine a VFS-aware [exec] having applications beyond tclkit,
but as I've never needed the functionality, I don't think I'll be
writing the TIP or the patch :)

Lan

2006-06-24, 8:23 am


Aric Bills wrote:
> Michael A. Cleverly wrote:
>
> I could imagine a VFS-aware [exec] having applications beyond tclkit,
> but as I've never needed the functionality, I don't think I'll be
> writing the TIP or the patch :)


Wow! All of the responses in this thread have been eye openers. This
has been a graduate seminar for me.

As OP, I thank everyone for the insights, hints and code snippets. I
have a lot more to work with.

Because you might be curious, let me announce my revised plan of
approach. First, I owe it to myself to test a stub example on Microsoft
to make sure that exec will behave as I hope in the absence of the VFS
(the point is taken that it may not, however the MS tclsh/wish
interpreters have been doing fine with the .tcl extension associated
with them so far, so I have hope).

If that succeeds, I will address my present requirements with the zip
file approach so as to make my deadlines. For the future, I mught
return to the challenge by extending exec as suggested to do a copy out
to a well-known place before executing the program.

I would prefer to avoid resorting to name spaces and sourcing for this
family of applications, which are expected to be used internally at my
company and not go anywhere else. I understand the necessity of
namespaces, but find their syntax very un-Tclish (although I also
recognize that having a naming convention to avoid collisions is just
as much work and doesn't provide the same level of security).

My thanks again to all for the thoughtful and articulate responses.

Donald Arseneau

2006-06-24, 8:23 am

"Lan" <lan@falleagle.net> writes:

> I would prefer to avoid resorting to name spaces and sourcing for this
> family of applications,


I like the separate-interp mode of execution.

exec of another tcl script does have a benefit of
providing poor-man's threading.

I don't suppose [open "|..."] works directly from the vfs,
does it?


--
Donald Arseneau asnd@triumf.ca
Jeff Hobbs

2006-06-24, 8:23 am

Donald Arseneau wrote:
> "Lan" <lan@falleagle.net> writes:
>
>
> I like the separate-interp mode of execution.
>
> exec of another tcl script does have a benefit of
> providing poor-man's threading.
>
> I don't suppose [open "|..."] works directly from the vfs,
> does it?


No, that essentially popen and again has only visibility for native fs
executables.

Jeff
Dan Smart

2006-06-24, 8:23 am

On 2006-06-21 12:59:58 -0400, "Lan" <lan@falleagle.net> said:
> Because you might be curious, let me announce my revised plan of
> approach. First, I owe it to myself to test a stub example on Microsoft
> to make sure that exec will behave as I hope in the absence of the VFS
> (the point is taken that it may not, however the MS tclsh/wish
> interpreters have been doing fine with the .tcl extension associated
> with them so far, so I have hope).
>
> If that succeeds, I will address my present requirements with the zip
> file approach so as to make my deadlines. For the future, I mught
> return to the challenge by extending exec as suggested to do a copy out
> to a well-known place before executing the program.


This approach may work, but in my arrogant opinion, is in general the
least desireable of your options. It's probably no less work than the
other alternatives, in particular creating slave interps for the
scripts would be bordering on trivial, and would satisfy your desire to
avoid namespaces, while maintaining the time you have invested in
starkits. Starkits are also the nicest of your deployment options.
>
> I would prefer to avoid resorting to name spaces and sourcing for this
> family of applications, which are expected to be used internally at my
> company and not go anywhere else. I understand the necessity of
> namespaces, but find their syntax very un-Tclish (although I also
> recognize that having a naming convention to avoid collisions is just
> as much work and doesn't provide the same level of security).


Namespace syntax sucks goats... but getting in the habit of putting all
your code (except the actual call to main) in namespaces pays enormous
dividends, and can allow the trivial re-use of existing programs as
libraries for new programs. This is seriously , and makes all the
other programmers in the playground swoon with envy. It's just a shame
about all the goats really.
>
> My thanks again to all for the thoughtful and articulate responses.


Dan "There is a relatively new piece of syntax that sucks harder, but
we won't go there just now" Smart

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com