View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0000188 | 1003.1(2008)/Issue 7 | System Interfaces | public | 2009-11-26 10:50 | 2024-06-11 08:53 |
Reporter | geoffclare | Assigned To | ajosey | ||
Priority | normal | Severity | Objection | Type | Enhancement Request |
Status | Closed | Resolution | Accepted As Marked | ||
Name | Geoff Clare | ||||
Organization | The Open Group | ||||
User Reference | |||||
Section | getenv | ||||
Page Number | 1008 | ||||
Line Number | 33858 | ||||
Interp Status | Approved | ||||
Final Accepted Text | 0000188:0000325 | ||||
Summary | 0000188: thread-safe getenv() | ||||
Description | The 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 Action | 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: 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 | ||||
Tags | issue8 |
related to | 0001394 | Closed | Issue 8 drafts | Another way the getenv() return string is modifiable |
|
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. |
|
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 |
|
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. |
|
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 |
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 |