The documentation for commandLineParams in std/cmdline suggests there are problem using the function in shared libraries in non-windows environments.
I was wondering if maybe you could extract the command arguaments from /proc/self/cmdline ?
An example would be like:
proc get_cmd_args*() : seq[string] =
## Get command line arguments
##
## When commandLineParams is available then this is merely an alias
## for commandLineParams, otherwise it will try and read the
## command line arguments from /proc/self/cmdline, and failing that
## it will raise an IOError.
when declared(commandLineParams):
return commandLineParams()
else:
let cline:string = readFile("/proc/self/cmdline")
let cargs = cline.split '\0'
return cargs[ 1 .. ^2]
The name "/proc/self" is not very portable. BSDs often use "/proc/curproc", for example..though some have /proc/self compatibility symlinks. In any event, that alone means this will be an #ifdef-soup or in Nim's case a when-soup.
This came up years ago and I suggested a less special-file-system-reliant (more low-level trickery-reliant) technique whereby you can infer the the local/stack-passed parameter argv from the "linkage" passed environ. The two memory areas are usually either argv, environ or environ, argv. This is because kernels prepare this portion of a new processes address space pre-jumping to the entry point in exec. This worked on a wide variety of Unixes around in the late 90s/early 00s - at least AIX, HP-UX, Solaris, all BSDs, Linux. In fact, I never found a Unix system on which it didn't work, but it does not seem to be very well known. It is probably more portable than the special filesystem idea. So, I mention it again. This time I will include some explicit C code:
#if defined __hpux
# define HAVE_STRINGS_FIRST
#endif
char **_argv (char **newval)
{
extern size_t strlen (const char *);
extern char **environ;
static char **val = (char **) 0;
char **p,
*bnd_hi,
*bnd_lo;
if (newval)
val = newval;
else if (!val) {
for (p = environ; *p; p++)
;
#ifdef HAVE_STRINGS_FIRST /* string data area just before pointer vectors */
bnd_hi = environ[-2];
bnd_lo = p[-1] + strlen (p[-1]) + 1; /* end of strings */
p = environ - 2;
while ((char *)p >= bnd_lo && *p <= bnd_hi)
p--;
#else /* string data area just after pointer vectors */
bnd_hi = environ[-2];
bnd_lo = (char *)(p + 1); /* after pointers, beg of argv-data*/
p = environ - 2;
while (bnd_lo <= *p && *p <= bnd_hi)
p--;
#endif
p++;
val = p;
}
return val;
}