As discussed in #15102, atime behavior may be POSIX compliant by a technicality, but it's not the expected behavior. In any case, compliance requires documenting the functions that update atime. Change-Id: I266b4d8d8a4a5d0f28f7c352d8942b417c2e31e4 Reviewed-on: https://review.haiku-os.org/c/haiku/+/10219 Reviewed-by: Adrien Destugues <[email protected]> Tested-by: Commit checker robot <[email protected]>
155 lines
6.9 KiB
ReStructuredText
155 lines
6.9 KiB
ReStructuredText
The standard C library
|
|
######################
|
|
|
|
Library organization
|
|
====================
|
|
|
|
The C library is, unlike in other POSIX systems, called libroot.so. It contains functions typically
|
|
found in libc, libm, libpthread, librt, as well as a few BeOS extensions.
|
|
|
|
It does not contain functions related to sockets networking, which are instead available in the
|
|
separate libnetwork.so.
|
|
|
|
POSIX, BSD and GNU extensions
|
|
=============================
|
|
|
|
overview
|
|
--------
|
|
|
|
The C library tries to follow the specifications set by the C standard as well as POSIX. These
|
|
provide a complete list of functions that should be implemented in the standard C library. The
|
|
library should not export any other functions, or if it does, they should be in a private namespace,
|
|
for example by prefixing their names with an underscore.
|
|
|
|
The idea is to avoid symbol name conflicts: applications are allowed to use any function names they
|
|
want, and there is a risk that the standard library accidentally uses the same name.
|
|
|
|
However, because the standards are a bit conservative, they often don't include functions that
|
|
would be very useful. Historically, other operating systems have provided non-standard extensions
|
|
in their C libraries. In particular, this is common in both glibc and BSD C libraries.
|
|
|
|
In Haiku, such extensions will be protected by a preprocessor ifdef guard, declared in separate
|
|
headers, and, whenever possible, made available in separate libraries. This allows the main C
|
|
library (libroot) to be more strictly conforming to the C and POSIX standards, while still making
|
|
popular additions available to applications.
|
|
|
|
features.h
|
|
----------
|
|
|
|
The file headers/compatibility/bsd/features.h is used to enable the declaration of these additions
|
|
in system header files.
|
|
|
|
It does so by defining the _DEFAULT_SOURCE variable (for "reasonable defaults"), which is enabled
|
|
if either of the following conditions are satisfied:
|
|
|
|
- The _GNU_SOURCE or _BSD_SOURCE preprocessor define is defined.
|
|
- The compiler is NOT in strict mode (__STRICT_ANSI__ is not defined) and _POSIX_C_SOURCE is not defined
|
|
|
|
Typically the following common cases will be used:
|
|
|
|
- The compiler is run without specific compiler flags: the default in gcc is to enable GNU extensions,
|
|
so __STRICT_ANSI__ is not defined. As a result, the extended functions are available.
|
|
- The compiler is run with -D_POSIX_C_SOURCE: compiler GNU extensions to C and C++ are enabled,
|
|
but extended functions are not available.
|
|
- The compiler is set to use a strict standard (for example -std=c11). In this case, __STRICT_ANSI__
|
|
is defined, and the extended functions are not available.
|
|
- The compiler is set to use a strict standard, but either _BSD_SOURCE or _GNU_SOURCE is defined.
|
|
In this case, the C and C++ language extensions are disabled, but the extra functions are available.
|
|
|
|
header files organization
|
|
-------------------------
|
|
|
|
In addition to the _DEFAULT_SOURCE guard, the nonstandard functions are declared in separate headers,
|
|
found in headers/compatibility/bsd and headers/compatibility/gnu, depending on where the function
|
|
was first introduced.
|
|
|
|
These directories are inserted before the standard ones (such as headers/posix). Since the extensions
|
|
are usually added in existing headers, these headers are overridden in these directories.
|
|
|
|
The overriden header uses #include_next (a gcc extension) to include the original one. It then
|
|
defines any extensions available.
|
|
|
|
There is a problem with this: #include_next is itself a nonstandard feature. So, in order to use a
|
|
fully standard compiler which would not recognize it, the compatibility headers directories should
|
|
be removed from the include paths.
|
|
|
|
libgnu and libbsd
|
|
-----------------
|
|
|
|
Moving the declarations out of the system headers is fine, but it is not enough. The function
|
|
definitions should also be moved out of libroot. So they are implemented in separate libraries,
|
|
libgnu and libbsd. Applications using these extended functions will need to link with these.
|
|
|
|
weak symbols
|
|
------------
|
|
|
|
In some cases, the code can't easily be moved out of libroot. There are various cases where this
|
|
can happen, for example:
|
|
|
|
- Other code in libroot depends on the nonstandard function
|
|
- The functions was in libroot in BeOS and can't be removed without breaking BeOS apps
|
|
|
|
In these cases, the function will be provided with an underscore at the start of its name. This
|
|
moves it to a namespace where libroot is allowed to define anything it needs. Then, a non-prefixed
|
|
version can be exported as a weak symbol. This allows applications to define their own version of
|
|
the function, since the one in libroot is "weak", the application one will be used instead for the
|
|
application code. Since code in libroot references the underscore-prefixed function only, it will
|
|
not be affected by this, and will still call the libroot-provided function.
|
|
|
|
This creates extra complexity, so, whenever possible, the functions should be moved to separate
|
|
libraries instead.
|
|
|
|
BeOS and Haiku specific functions
|
|
=================================
|
|
|
|
In addition to the standard C library, libroot also contains functions specific to BeOS and Haiku.
|
|
Unfortunately, no precautions were taken with these, and they can conflict with application defined
|
|
symbols.
|
|
|
|
We can't change this for symbols existing from BeOS, as it would break binary compatibility. We
|
|
may need to change this in R2. However, we should keep this in mind when adding new functions to
|
|
libroot. There is no well-defined solution for this currently, but the strategies documented above
|
|
can be used if needed.
|
|
|
|
POSIX non-conformities
|
|
======================
|
|
|
|
Haiku tries to follow the POSIX specification as closely as possible, however, existing design
|
|
constraints (inherited from BeOS) sometimes prevent to do so.
|
|
|
|
Negative errno codes
|
|
--------------------
|
|
|
|
POSIX requires (since Issue 6) that values for errno are positive. In BeOS and Haiku, they are
|
|
negative.
|
|
|
|
This is sometimes used in a pattern similar to this::
|
|
|
|
int getValueOrError(void)
|
|
{
|
|
if (everythingOk)
|
|
return value;
|
|
else
|
|
return -EACCESS;
|
|
}
|
|
|
|
This will not work on Haiku, as the returned value will be positive in all cases.
|
|
|
|
There is a further special case for ENOMEM, which normally has the value INT_MIN, and as such
|
|
cannot be negated at all (as -INT32_MIN cannot be stored in an int variable).
|
|
|
|
The posix_error_mapper library can be used to convert the errno values. Applications that require
|
|
positive error codes should use that library to ensure proper operation. However, this can lead
|
|
to further incompatibilities if error codes are also forwarded between an application and libraries
|
|
or add-ons that don't use the same sign for error codes.
|
|
|
|
To use the library, you also need to define B_USE_POSITIVE_POSIX_ERRORS as a preprocessor constant
|
|
before including any system headers (typically as a compiler command line switch).
|
|
|
|
Implementation of atime
|
|
-----------------------
|
|
|
|
The BFS filesytem does not store the access time.
|
|
|
|
Currently, stat() and similar functions always return the current time in the atime field.
|