This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Adding putenv/setenv functionality to libiberty (for fixincl)


Discussing options for fixing fixincl, Jeff Law describes three
possibilities:
>> 1. Always use putenv from libiberty, using the semantics provided by
>> libiberty (not as easy as it might sound since putenv is only included
>> in libiberty if it's not in the system C library).

... and Bruce Korb <ddsinc09@ix.netcom.com> replies:
> Not as difficult as it might sound, since there are trivial methods for
> forcing setenv/putenv to go into the library.

Actually it *is* difficult. Generally it's bad form do declare a function
that has the same name as one in another library.  Maybe something in
the C library depends on `their' putenv. Maybe the linker doesn't like
two libraries competing over defining a symbol.

If we were going to do something like this, we'd call it xputenv.

>> 2. Avoid putenv entirely.  Possibly settling on setenv if it has better
>> defined semantics.
>
> This is was what I said a while ago.

Fine with me.  We then get to decide whether we need putenv in libiberty,
since we won't actually be using it.

>> 3. Support both variants of putenv (yuk).
>
> Bzzt.  :-)

It might not be necessary, but it isn't hard.  In reply to my earlier,
Bruce sent me the following:

>>> As to Bruce's concerns about a memory leak, I don't see it myself.
>>> Looking at the code for setenv, it seems like it only allocates
>>> space if there isn't space to overwrite.
%
% And there is not enough space every time the file name is larger than
% the previous one.  So, it only leaks a little under half the time.

If you allocate a large string (say filled with 1024 'X's) for the value
of the environment variable before entering the loop, you can safely
call putenv inside the loop without leaking on BSD/glibc or SYSV putenv
implementations.

This method still seems over-complicated though, compared to the
alternatives.

>> I'd lean towards #2.  It seems the safest assuming that the behavior of
>> setenv hasn't changed over time.
>
> I think I would insist on it, partly just because you would be guaranteed
> that it comes from libiberty (wouldn't you?  It is not listed in any
> of my handy man pages for SVR1, BSD4.2 and SVR5.)

Setenv seems to be in BSD4.4 and glibc systems.  I'm guessing the
semantics are the same, but it'd be worth checking.

> I wonder, do you suppose it would be better to just get the address of
> the environment pointer array and insert my own pointer into it?

Seems fairly clean to me, but there could be a subtle catch. Is the
initial environ array guaranteed to be writable?

An alternative is not to use execl but switch over to execle with
your own environment.

> Ah, there is one other possibility.  Currently, the shell script for
> fixing a header is static.  (This is the only context within which this
> putenv/setenv stuff is used anyway!)  I could, instead, do the following:
>
> static const char z_shell_fix[] = "file='%s'\n%s\n";
> sprintf( z_shell_buf, z_shell_fix, pz_file, p_fix->pz_script );
>
> and then use z_shell_buf to the execl("sh", "-c", z_shell_buf) call.
> Now, we can dump the setenv/putenv entirely  :-))
> I would have to distinguish shell invocations from sed
> invocations, however :(.  That, however, ought to be much easier
> than all this other horsing around!!

Fine in this case perhaps, but a dangerous trick in general. A file
with a name like:
	
	Ha!' 'rm -rf ~

is legal, and would to horrible things with the above code.

    Melissa.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]