Minor bug: library definition of "spawn" not const-correct.

BUG REPORT

DATE: 10 AUG 2003
PLATFORM: QNX 6.2.1 (All)
FROM: John Nagle / Team Overbot / nagle@overbot.com
SEVERITY: Mildly annoying.

DESCRIPTION

In include file <spawn.h> and associated library:

The last two arguments to "spawn are

char * const argv[ ]
char * const envp[ ]

They should be

const char * const argv[ ]
const char * const envp[ ]

You can’t pass a constant string to spawn given the
current definition. Spawn never stores into those strings
(if it does, that’s a bug) so they should be fully constant.

This comes up in practice when the underlying string
is inside a C++ “string”, accessed via “c_str()”, so
there’s an annoying C++ incompatibility.

John Nagle

John Nagle <nagle@downside.com> wrote:

BUG REPORT
PLATFORM: QNX 6.2.1 (All)
In include file <spawn.h> and associated library:
char * const argv[ ]
char * const envp[ ]

IMHO, you should address your issue to IEEE/ISO, not QNX.
Although spawn() is QNX, the similar posix_spawn() is
specified (in ISO/IEC 9945-1 2002) to use the qualifiers
“char * const [restrict]”. I believe that the reluctance
to use “const char * const []” is due to ambiguities in
the C language standard (search the web for more details)
pertaining to multi-level const qualification. Regardless,
our prototypes conform to the current specification.

This comes up in practice when the underlying string
is inside a C++ “string”, accessed via “c_str()”, so
there’s an annoying C++ incompatibility.

POSIX defines a set of C Language bindings, not C++.

LOL OK, technically your off the hook.

Maybe you could put in an #ifdef __cplusplus with a more C++
prototype.


John Garvey <jgarvey@qnx.com> wrote:
JG > John Nagle <nagle@downside.com> wrote:

BUG REPORT
PLATFORM: QNX 6.2.1 (All)
In include file <spawn.h> and associated library:
char * const argv[ ]
char * const envp[ ]

JG > IMHO, you should address your issue to IEEE/ISO, not QNX.
JG > Although spawn() is QNX, the similar posix_spawn() is
JG > specified (in ISO/IEC 9945-1 2002) to use the qualifiers
JG > “char * const [restrict]”. I believe that the reluctance
JG > to use “const char * const []” is due to ambiguities in
JG > the C language standard (search the web for more details)
JG > pertaining to multi-level const qualification. Regardless,
JG > our prototypes conform to the current specification.

This comes up in practice when the underlying string
is inside a C++ “string”, accessed via “c_str()”, so
there’s an annoying C++ incompatibility.

JG > POSIX defines a set of C Language bindings, not C++.

John Garvey <jgarvey@qnx.com> wrote:

John Nagle <> nagle@downside.com> > wrote:
BUG REPORT
PLATFORM: QNX 6.2.1 (All)
In include file <spawn.h> and associated library:
char * const argv[ ]
char * const envp[ ]

IMHO, you should address your issue to IEEE/ISO, not QNX.
Although spawn() is QNX, the similar posix_spawn() is
specified (in ISO/IEC 9945-1 2002) to use the qualifiers
“char * const [restrict]”. I believe that the reluctance
to use “const char * const []” is due to ambiguities in
the C language standard (search the web for more details)
pertaining to multi-level const qualification. Regardless,
our prototypes conform to the current specification.

I don’t think the C standard is ambiguous on this one; it’s pretty clear
from 6.5.2.2p2 (Function calls), 6.5.16.1p1 (Simple Assignment), and
6.2.5p25 (the definition of “qualified version” of a type), that you
can’t define a function that allows you to pass an array of char* and an
array of char const* to the same parameter. You have to choose one or
the other, and when the POSIX folks were making that choice for exec(),
code using “const” was much less common than it is today. And once that
decision was made for exec(), consistency was a good reason to define
new functions like posix_spawn() the same way.

In C++, this problem can be worked around by having two functions – the
“real” one and a simple inline function that does a typecast and calls
the other one. You still need a typecast, but at least C++ allows you
to have it in only one place.

Right. And here it is:

//
// spawn – spawn a new process
//
// Constness problem workaround.
//
inline pid_t spawn( const char* path, int fd_count, const int fd_map[ ],
const struct inheritance* inherit,
const char* const argv[ ], const char* const envp[ ])
{ return(spawn(path,fd_count,fd_map,inherit,
const_cast<charconst>(argv),const_cast<charconst>(envp)));
}


Wojtek Lerch wrote:

In C++, this problem can be worked around by having two functions – the
“real” one and a simple inline function that does a typecast and calls
the other one. You still need a typecast, but at least C++ allows you
to have it in only one place.

Oh, and while we’re on “spawn”, what is the format
of environment variables in the “envp” variable? Suppose
I need to set

DIR=“My Documents”

Do I use quotes in “envp” entries, or not? Are backslash escapes
supported/required? Thanks.

John Nagle

John Nagle <nagle@downside.com> wrote:

Oh, and while we’re on “spawn”, what is the format
of environment variables in the “envp” variable? Suppose
I need to set

DIR=“My Documents”

Do I use quotes in “envp” entries, or not? Are backslash escapes
supported/required? Thanks.

The issue of “quoting” or “escaping” is complex. There is no
single correct answer.

For example - spaces - are only an issue if that element will be
used to build a command line that will be parsed by a shell, since
the shell recognises spaces as token seperators.

And, once you get into multiple layers, you almost have to know
exactly how many layers of parsing/stripping will be done, before
you can know the correct number of quotes/escapes to wrap things
in.

If the child is going to do:

fname = strcat( fname, getenv(“DIR”));
fname = strcat( fname, FNAME );
open(fname,…);

Then “DIR=My Documents” would be fine.

But, if it is going to do something like:

fname = strcat( fname, getenv(“DIR”));
fname = strcat( fname, FNAME );
sprintf(cmd, “rm %s”, fname );
system(cmd);

Then it won’t be ok.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.