The (initial) glibc year-2038 plan
The year-2038 problem will ultimately affect all code that uses 32 bits for time values. Over the past year, the Linux kernel community has begun formally hashing out its plan to transition to 64-bit time support. As a result, other development teams have been observing the kernel discussion and have started to plan their own approaches. The GNU C library (glibc) is one such project, and its developers recently drafted an initial plan of attack.
Albert Aribaud unveiled a proposed plan on the glibc mailing list on October 26, soliciting feedback. Aribaud's proposal sets out a few straightforward requirements for any eventual game plan. As was discussed in 2014, glibc will add a feature test macro that 32-bit applications can set to enable the use of year-2038-safe, 64-bit time functions—although the details surrounding the macro have changed since it was first proposed.
TIME BITS and macros
The interfaces that glibc presents to user code have been the subject of most of the debate thus far. The project had previously considered supporting both 64-bit and 32-bit time functions in the same application.
The first draft of the proposed plan provided both a _TIME64_SOURCE macro and a _TIME_BITS macro. Defining _TIME64_SOURCE would make 64-bit time functions available to the application; then defining _TIME_BITS=64 would cause all time functions to use 64-bit times by default. The _TIME_BITS=64 option is implemented by transparently mapping the standard functions and types to their internal 64-bit variants. Glibc would also set __USE_TIME_BITS64, which user code can test for to determine if the 64-bit variants are available.
A subtle effect caused by using two macros in this manner, though, is that it could enable user code to activate 64-bit time functions, but still default to using the 32-bit versions. In essence, that would allow an application to mix and match calls to (hypothetically) clock_gettime() and clock_gettime64().
On that point, some similarities were cited to the project's addition of the Large File Support (LFS) extension several years ago. The LFS extension provided a _FILE_OFFSET_BITS feature test macro; setting _FILE_OFFSET_BITS=64 would cause glibc to remap off_t and the related functions (e.g., ftello() and fseeko()) to their 64-bit equivalents (off64_t, ftello()64, and fseeko64()). But glibc also provided another option, _LARGEFILE64_SOURCE, that made the 64-bit types and functions available in addition to the 32-bit flavors.
Opinion is sharply divided as to whether or not this was a good idea; code calling the *64 functions is neither portable to other C libraries nor does it conform to standards. The same problem could plague the 64-bit time implementation, with _TIME64_SOURCE and _TIME_BITS=64 being analogous to _LARGEFILE64_SOURCE and _FILE_OFFSET_BITS=64.
Rich Felker recommended not repeating the LFS approach when implementing 64-bit time:
Not everyone concurred that the LFS approach was a bad one; Myers noted that the LFS transition, which was trickiest for third-party libraries using glibc, was eventually managed. In a separate email, though, he also expressed doubt that there were many use cases where code would need explicit access to the *64 versions of any functions. Without such use cases, having _TIME_BITS=64 both "enable" and "select" 64-bit time would be simpler.
Aribaud did remove _TIME64_SOURCE from the subsequent drafts of the plan. As things stand now, only the _TIME_BITS macro remains.
Further issues
Some points still up for discussion include whether to mandate that 64-bit time only be supported where 64-bit file offsets are supported (essentially, LFS systems), and whether there should be an attempt to fix 32-bit time functions or simply to implement 64-bit time functions and provide them for those developers wanting a solution.
Not supporting 64-bit time on systems without 64-bit file offsets would primarily serve to reduce the complexity of the implementation—that is, there would only be two permutations to consider (32-bit and 64-bit), rather than four (all 32-bit, all 64-bit, 32-bit time with 64-bit file support, and 64-bit time with 32-bit file support). There are, presumably, only a few non-LFS systems left in the wild, so not supporting them likely has little impact. In light of the project's somewhat contentious history with supporting 32-bit and 64-bit file offsets simultaneously, imposing this restriction is understandable.
The case for not attempting to fix (whatever that might mean) 32-bit time functions is, simply, that developers should know better and fix their code, using _TIME_BITS=64 to enable the new, 64-bit time functions. Any application that persists in using 32-bit time will see incorrect results for times after January 2038, but perhaps that is acceptable. Presumably, such instances would be rare, such as applications for which no source code is available.
As far as interfacing with the kernel is concerned, the basic idea is that glibc will always convert time-related type sizes between kernel space and user space. If the system is running a year-2038-safe kernel, glibc will also convert time values between kernel space and user space. It will not, however, attempt to convert values for a non-year-2038-safe kernel. A bit more nebulous is how to fix platforms that already use 64 bits to store times, but use them to store 32-bit values. Ideally, the general 64-bit time fix should not break these systems. Myers pointed out that the 32-bit time values on these system will need to have an explicit padding field.
Glibc will still need to implement and verify all of the functions and types affected by 64-bit time. Aribaud is still in the process of mapping out the complete set of APIs affected—directly and indirectly—by changing the size of time_t. But once that set of affected pieces has been determined, the question still remains whether 64-bit time should become the default.
Here again, comparisons were made to the LFS transition process. Ultimately, the large-scale transition that changing the default would trigger is a prospect that no one relishes, since it will inevitably impact many libraries and applications—as well as costing developers and users time. But it will have to happen eventually. Felker suggested that announcing a timeline for changing the default from 32-bit to 64-bit time in advance would help avoid many of the LFS transition's headaches.
For now, no such timeline has been discussed. 32-bit
time will remain the default for some time to come; making 64-bit time
the default will be left for some as-yet-undetermined future date, and
the decision will no doubt involve consultation from distributors.
There are plenty of additional details that the glibc developers will
need to work out in order to fully support 64-bit time, but reaching a
rough consensus on the approach to take and on the interfaces to use
is a good first step.
