# [email protected] / 2010-02-12 15:25:48 +0100:
> Roman Neuhauser a écrit :
> > But I'm sure you have good reasons to embed the bytecode; could you
> > please rehash them so I know which way to push this further?
> 
> The main reason is simplicity : you can have one command that boot 
> itself. Please note that it works perfectly on all OS except BSD ;) 

If the pronoun in "it works" means the #else branch of executable_path(),
then I have to disagree.  Obviously it doesn't work on Debian GNU/FreeBSD
either, and if you check the standard, there's no support for thinking it
should:

http://www.opengroup.org/onlinepubs/000095399/functions/exec.html

Esp. the execve(2) example is illuminating:

    #include <unistd.h>

    int ret;
    char *cmd[] = { "ls", "-l", (char *)0 };
    char *env[] = { "HOME=/usr/home", "LOGNAME=home", (char *)0 };
    ...
    ret = execve ("/bin/ls", cmd, env);

In fact, the #else branch works only on systems with a specific procfs
(GNU/Linux) and failing that, in bash and other shells that set $_ (IOW,
it's silently dependent on non-standard and non-universal behavior of
another application, and fails when executed via other means.

> Maybe there's a BSD specific C API for getting current executable path ?

I'm investigating that.  The first thing that occurred to me is that this could
be made more universal if it matched the behavior prescribed by the SUS:

if argv[0] begins with "/", the full path == argv[0]; else
if argv[0] contains "/", the full path == $PWD/argv[0]; else
foreach dir in $PATH:
  if $dir/argv[0] exists, it's the full path, you're done
end
if you got here, the full path is unknown

found this on google: http://stackoverflow.com/questions/1023306/

%    * Mac OS X: _NSGetExecutablePath() (man 3 dyld)
%    * Linux: readlink /proc/self/exe
%    * Solaris: getexecname()
%    * FreeBSD: sysctl CTL_KERN KERN_PROC KERN_PROC_PATHNAME -1
%    * BSD with procfs: readlink /proc/curproc/file
%    * Windows: GetModuleFileName() with hModule = NULL
%
% The portable (but less reliable) method is to use argv[0]. Although it could
% be set to anything by the calling program, by convention it is set to either
% a path name of the executable or a name that was found using $PATH.
%
% Some shells, including bash and ksh, set the environment variable "_" to the
% full path of the executable before it is executed. In that case you can use
% getenv("_") to get it. However this is unreliable because not all shells do
% this, and it could be set to anything or be left over from a parent process
% which did not change it before executing your program.

I'll be back with a patch.

-- 
Roman Neuhauser

--
Neko : One VM to run them all
(http://nekovm.org)

Reply via email to