View Issue Details

IDProjectCategoryView StatusLast Update
00001881003.1(2008)/Issue 7System Interfacespublic2024-06-11 08:53
Reportergeoffclare Assigned Toajosey  
PrioritynormalSeverityObjectionTypeEnhancement Request
Status ClosedResolutionAccepted As Marked 
NameGeoff Clare
OrganizationThe Open Group
User Reference
Sectiongetenv
Page Number1008
Line Number33858
Interp StatusApproved
Final Accepted Text0000188:0000325
Summary0000188: thread-safe getenv()
DescriptionThe standard says that getenv() need not be thread-safe. Since there
is no getenv_r() function, this makes obtaining environment variable
values somewhat inconvenient in multi-threaded conforming applications.
I imagine there are a large number of applications that don't bother
to be careful with getenv() and just assume it is thread-safe.
It probably is thread-safe on most, if not all, implementations that
support POSIX threads.

The reason getenv() is not required to be thread-safe is stated in
the rationale:

    "The getenv() function is inherently not thread-safe because it
    returns [sic] a value pointing to static data."

(I added "[sic]" because it should say "may return" not "returns".)

I think it likely that the only POSIX implementations where getenv()
copies the value to an internal buffer are UNIX implementations where
the UNIX APIs have been added to an O/S that was not originally UNIX.
It's possible none of these implement POSIX threads, or if they do
then they may have made getenv() thread-safe by using per-thread
internal buffers instead of a single buffer.

Therefore I think the standard should require getenv() to be
thread-safe. If there are any implementations which copy to an
internal buffer, and either have POSIX threads or want to add POSIX
threads in the future, they can conform simply by using per-thread
internal buffers.
Desired ActionAt line 33853 change:

    The string pointed to may be overwritten by a subsequent call to
    getenv(), [CX]setenv(), unsetenv(),[/CX] [XSI]or putenv()[/XSI]
    but shall not be overwritten by a call to any other function in
    this volume of POSIX.1-2008.

to:

    The string pointed to may be overwritten by a subsequent call to
    getenv(), [CX]setenv(), unsetenv(),[/CX] [XSI]or putenv()[/XSI]
    from the same thread but shall not be overwritten by a call to
    any of these functions from another thread or by a call to any
    other function in this volume of POSIX.1-2008 from any thread.

At line 33858 delete:

    The getenv() function need not be thread-safe.

At line 33878 change:

    The getenv() function is inherently not thread-safe because it
    returns a value pointing to static data.

to:

    Some earlier versions of this standard did not require getenv()
    to be thread-safe because it may return a value pointing to
    static data. However, implementations of getenv() that do
    this can be made thread-safe by using per-thread internal buffers
    instead of a single buffer. Therefore getenv() is now required
    to be thread-safe (except when another thread is modifying the
    environment).

At line 33908 delete:

    A future version may add one or more functions to access and
    modify the environment in a thread-safe manner.


At page 507 line 17494 section 2.9.1 delete getenv() from the list
of functions that need not be thread-safe.

At page 508 line 17518 change:

    any function dependent on any environment variable is not
    thread-safe if another thread is modifying the environment

to:

    the getenv() function and any function dependent on any
    environment variable are not thread-safe if another thread is
    modifying the environment
Tagsissue8

Relationships

related to 0001394 Closed Issue 8 drafts Another way the getenv() return string is modifiable 

Activities

drepper

2009-11-26 16:25

reporter   bugnote:0000309

Oh, no. I'll never agree to that.

The reason why getenv had to be marked not thread safe is that other threads might call setenv or modify strings passed in with putenv. Aside from that getenv is thread-safe and this is what we've said for a long time. I.e., any program that wants to use getenv simply must refrain from using setenv and putenv.

Using thread-local buffers is completely unacceptable. It adds even more sources of problems. First, environment entries can be arbitrarily long in size. You'd need a complete dynamic buffer management, not just some fixed-size buffer. Second, and more severe. Programs expect the values returned from getenv to be usable for a long time. In fact, until the environment is changed (most of the time this means for the lifetime of the process). With you copy implementation this would change. The lifetime would end at the next getenv call.

As I said many times, I don't think there is a problem at all. If you want to do something, outlaw setenv and putenv, especially in multi-threaded code. Environments should be constructed for a process before the start and then left alone.

The only alternative would be a new interface which, unlike getenv, does provide a buffer for the content of the envvar to be copied in. Then the lifetime of the string is in the hands of the application. That's a new interface of course. I don't think I would even agree to that. I really think the environment should be immutable after startup.

geoffclare

2009-12-01 10:11

manager   bugnote:0000311

Here is an updated proposal that also disallows overwriting.
(The first additional change here also needs to be added to
the original proposal if it is accepted instead of this
updated proposal.)

At line 33851 after:

    The application shall ensure that it does not modify the string
    pointed to by the getenv() function

add:

    [XSI], unless it is part of a string previously added to the
    environment using putenv()[/XSI]

At line 33853 change:

    The string pointed to may be overwritten by a subsequent call to
    getenv(), [CX]setenv(), unsetenv(),[/CX] [XSI]or putenv()[/XSI]
    but shall not be overwritten by a call to any other function in
    this volume of POSIX.1-2008.

to:

    [CX]The pointer returned by getenv() shall point to a string
    within the environment data pointed to by environ. This
    requirement is an extension to the C Standard, which allows
    getenv() to copy the data to an internal buffer.[/CX]

At line 33858 delete:

    The getenv() function need not be thread-safe.

At line 33878 change:

    The getenv() function is inherently not thread-safe because it
    returns a value pointing to static data.

to:

    Some earlier versions of this standard did not require getenv()
    to be thread-safe because it was allowed to return a value
    pointing to an internal buffer. However, this behaviour allowed
    by the C Standard is no longer allowed by POSIX.1. POSIX.1
    requires the environment data to be available through environ[],
    so there is no reason why getenv() can't return a pointer to the
    actual data instead of a copy. Therefore getenv() is now required
    to be thread-safe (except when another thread is modifying the
    environment).

At line 33908 delete:

    A future version may add one or more functions to access and
    modify the environment in a thread-safe manner.


At page 507 line 17494 section 2.9.1 delete getenv() from the list
of functions that need not be thread-safe.

At page 508 line 17518 change:

    any function dependent on any environment variable is not
    thread-safe if another thread is modifying the environment

to:

    the getenv() function and any function dependent on any
    environment variable are not thread-safe if another thread is
    modifying the environment

msbrown

2009-12-02 19:04

manager   bugnote:0000313

I do not view this as an error in the specification; as things currently stand this looks like a quality-of-implementation issue. I am leaning in favor of this change but it should be classified as an Enhancement Request, not Error.

msbrown

2009-12-10 16:35

manager   bugnote:0000325

Last edited: 2010-03-25 15:15

Interpretation response
------------------------

The standard does not speak to this issue, and as such no conformance distinction can be made between alternative implementations based on this. This is being referred to the sponsor.

Rationale:
-------------

None.

Notes to the Editor (not part of this interpretation):
-------------------------------------------------------
The WG recommends the following changes to a future revision of the Specification:

At line 33851 after:

    The application shall ensure that it does not modify the string
    pointed to by the getenv() function

add:

    [XSI], unless it is part of a string previously added to the
    environment using putenv()[/XSI]

At line 33853 change:

    The string pointed to may be overwritten by a subsequent call to
    getenv(), [CX]setenv(), unsetenv(),[/CX] [XSI]or putenv()[/XSI]
    but shall not be overwritten by a call to any other function in
    this volume of POSIX.1-2008.

to:

    [CX]The pointer returned by getenv() shall point to a string
    within the environment data pointed to by environ.
    Note: This requirement is an extension to the C Standard, which
    allows getenv() to copy the data to an internal buffer.[/CX]

At line 33858 delete:

    The getenv() function need not be thread-safe.

At line 33878 change:

    The getenv() function is inherently not thread-safe because it
    returns a value pointing to static data.

to:

    Some earlier versions of this standard did not require getenv()
    to be thread-safe because it was allowed to return a value
    pointing to an internal buffer. However, this behaviour allowed
    by the C Standard is no longer allowed by POSIX.1. POSIX.1
    requires the environment data to be available through environ[],
    so there is no reason why getenv() can't return a pointer to the
    actual data instead of a copy. Therefore getenv() is now required
    to be thread-safe (except when another thread modifies the
    environment).

At line 33908 delete:

    A future version may add one or more functions to access and
    modify the environment in a thread-safe manner.


At page 507 line 17494 section 2.9.1 delete getenv() from the list
of functions that need not be thread-safe.

At page 508 line 17518 change:

    any function dependent on any environment variable is not
    thread-safe if another thread is modifying the environment

to:

    the getenv() function and any function dependent on any
    environment variable are not thread-safe if another thread
    modifies the environment

Issue History

Date Modified Username Field Change
2009-11-26 10:50 geoffclare New Issue
2009-11-26 10:50 geoffclare Status New => Under Review
2009-11-26 10:50 geoffclare Assigned To => ajosey
2009-11-26 10:50 geoffclare Name => Geoff Clare
2009-11-26 10:50 geoffclare Organization => The Open Group
2009-11-26 10:50 geoffclare Section => getenv
2009-11-26 10:50 geoffclare Page Number => 1008
2009-11-26 10:50 geoffclare Line Number => 33858
2009-11-26 10:50 geoffclare Interp Status => ---
2009-11-26 16:25 drepper Note Added: 0000309
2009-12-01 10:11 geoffclare Note Added: 0000311
2009-12-02 19:04 msbrown Note Added: 0000313
2009-12-10 16:35 msbrown Interp Status --- => Pending
2009-12-10 16:35 msbrown Note Added: 0000325
2009-12-10 16:35 msbrown Type Error => Enhancement Request
2009-12-10 16:35 msbrown Status Under Review => Interpretation Required
2009-12-10 16:35 msbrown Resolution Open => Accepted As Marked
2009-12-10 16:35 msbrown Description Updated
2009-12-10 16:35 msbrown Final Accepted Text => 0000188:0000325
2010-02-12 06:38 ajosey Interp Status Pending => Proposed
2010-03-25 15:15 geoffclare Note Edited: 0000325
2010-03-25 15:16 geoffclare Interp Status Proposed => Approved
2010-09-24 14:42 Don Cragun Tag Attached: issue8
2019-12-20 12:00 geoffclare Status Interpretation Required => Applied
2020-08-26 09:19 geoffclare Relationship added related to 0001394
2024-06-11 08:53 agadmin Status Applied => Closed