diff --git a/architecture.md b/architecture.md index fd6cf673..9561ebe9 100644 --- a/architecture.md +++ b/architecture.md @@ -1,6 +1,11 @@ # Architecture -The Phoenix-RTOS operating system starting from version 3 is based on microkernel architecture. It means that system consists of microkernel implementing basic primitives and set of servers based on these primitives and communicating over it. The main advantage of such architecture is high scalability. The disadvantage is performance degradation caused by message passing. Message passing demands in some cases memory copying and additional thread context switching. +The Phoenix-RTOS operating system starting from version 3 is based on microkernel architecture. +It means that system consists of microkernel implementing basic primitives and set of servers based on these primitives +and communicating over it. +The main advantage of such architecture is high scalability. +The disadvantage is performance degradation caused by message passing. +Message passing demands in some cases memory copying and additional thread context switching. The architecture is schematically presented on figure below. @@ -8,44 +13,92 @@ The architecture is schematically presented on figure below. ## Microkernel -Microkernel implements minimum set of primitives necessary to implement other operating system components. Phoenix-RTOS microkernel implements four fundamental subsystems - memory management, process and thread management, interprocess communication and low-level I/O for redirecting the interrupts to user-level threads. Microkernel functionalities are accessible for applications through set of system calls. System call (syscall) is the operating system function implemented by the special processor instruction switching the execution privilege mode from user to system. After switching the execution mode from user to system privilege level program is able to execute privileged instructions and access the system memory segments and I/O space. +Microkernel implements minimum set of primitives necessary to implement other operating system components. +Phoenix-RTOS microkernel implements four fundamental subsystems - memory management, process and thread management, +interprocess communication and low-level I/O for redirecting the interrupts to user-level threads. Microkernel +functionalities are accessible for applications through set of system calls. System call (syscall) is the operating +system function implemented by the special processor instruction switching the execution privilege mode from user to +system. After switching the execution mode from user to system privilege level program is able to execute privileged +instructions and access the system memory segments and I/O space. To understand the microkernel architecture please refer to chapter [Kernel architecture](kernel/README.md). ## Interprocess communication -The main functionality provided by microkernel necessary to implement the operating system is the interprocess communication (IPC). In the figure above microkernel was shown as the bus between other system components and this is the main factor which differentiates the microkernel-based operating system from the traditional monolithic kernel based operating system. All system components interact with each other using message passing. For example file operations are performed by communicating with file servers. Such approach affects tremendously system scalability and modularity. The local communication based on shared memory can be easily extended to the remote communication using network. The modules (servers) implementing specific functionalities can be easily added and removed from the system due to message passing restricting interactions between them to a well-structured format. Servers partition the operating system functionality in the natural way. The message passing should be implemented in such a way that minimizes the communication overhead. Consequently it should be supported by some virtual memory mechanisms like physical memory sharing. In the further considerations it is assumed that messages are sent to the ports registered by servers. Ports together with identifiers of data structures operated by servers (e.g. files) identify operating system objects. - -Interprocess communication has been described in [Kernel - Processes and threads - Message passing](kernel/proc/msg.md) chapter. +The main functionality provided by microkernel necessary to implement the operating system is the interprocess +communication (IPC). In the figure above microkernel was shown as the bus between other system components and this +is the main factor which differentiates the microkernel-based operating system from the traditional monolithic kernel +based operating system. All system components interact with each other using message passing. For example file +operations are performed by communicating with file servers. Such approach affects tremendously system scalability and +modularity. The local communication based on shared memory can be easily extended to the remote communication using +network. The modules (servers) implementing specific functionalities can be easily added and removed from the system +due to message passing restricting interactions between them to a well-structured format. Servers partition the +operating system functionality in the natural way. The message passing should be implemented in such a way that +minimizes the communication overhead. Consequently it should be supported by some virtual memory mechanisms like +physical memory sharing. In the further considerations it is assumed that messages are sent to the ports registered by +servers. Ports together with identifiers of data structures operated by servers (e.g. files) identify operating system +objects. + +Interprocess communication has been described in [Kernel - Processes and threads - Message passing](kernel/proc/msg.md) +chapter. ## Standard library -Standard library is the set of functions constituting the basic programming environment (providing the basic API) and based on the system calls. API could be compatible with popular programming standards (ANSI C, POSIX etc.) or could be specific for the operating system. Phoenix-RTOS 3 provides its own standard library (`libphoenix`) compatible with ANSI C89 and extended with some specific functions for memory mapping and process and thread management. The library can be extended (in cooperation with servers) with additional functions to provide the POSIX compliant environment. Such environment requires much more memory than basic ANSI C native interface but allows for execution of the popular open-source UN*X applications. +Standard library is the set of functions constituting the basic programming environment (providing the basic API) and +based on the system calls. API could be compatible with popular programming standards (ANSI C, POSIX etc.) or could be +specific for the operating system. Phoenix-RTOS 3 provides its own standard library (`libphoenix`) compatible with ANSI +C89 and extended with some specific functions for memory mapping and process and thread management. The library can be +extended (in cooperation with servers) with additional functions to provide the POSIX compliant environment. Such +environment requires much more memory than basic ANSI C native interface but allows for execution of the popular +open-source UN*X applications. Standard library has been described in [Standard library](libc/README.md) chapter. ## Servers -In the microkernel architecture servers plays very important role in the whole operating system. They provide functionalities removed from the traditional, monolithic kernel and moved to the user space. Good examples of such functionalities are file management or device management (device drivers). The main method for communicating with server is message passing. Each server allocates and registers set of ports used to receive messages from other system components. For example the file server registers new port in the filesystem space. Device driver registers new name in the `/dev` directory. +In the microkernel architecture servers plays very important role in the whole operating system. They provide +functionalities removed from the traditional, monolithic kernel and moved to the user space. Good examples of +such functionalities are file management or device management (device drivers). The main method for communicating +with server is message passing. Each server allocates and registers set of ports used to receive messages from other +system components. For example the file server registers new port in the filesystem space. Device driver registers +new name in the `/dev` directory. -Server concept and server registering are described in [Kernel - Processes and threads - Servers and namespace](kernel/proc/namespace.md) chapter. +Server concept and server registering are described in +[Kernel - Processes and threads - Servers and namespace](kernel/proc/namespace.md) chapter. ## Device drivers -Device drivers are specific servers responsible for controlling devices. They can implement protocol for I/O operations enabling to use them like files. Special mechanism is used to allow user level processes to communicate with the hardware. In architectures without I/O address space where device registers are accessible in the memory address space the special memory mapping is used. When device uses I/O space (e.g. ports on IA32) special processor flag is set permitting the unprivileged code to access the parts or whole I/O space. The flag is set during runtime using specific system call. Second important issue which should be discussed here is interrupt handling. When device drivers run on user-level, interrupts are redirected to the selected processes and interrupt handling routines are implemented as regular functions. +Device drivers are specific servers responsible for controlling devices. They can implement protocol for I/O operations +enabling to use them like files. Special mechanism is used to allow user level processes to communicate with the +hardware. In architectures without I/O address space where device registers are accessible in the memory address space +the special memory mapping is used. When device uses I/O space (e.g. ports on IA32) special processor flag is set +permitting the unprivileged code to access the parts or whole I/O space. The flag is set during runtime using specific +system call. Second important issue which should be discussed here is interrupt handling. When device drivers run on +user-level, interrupts are redirected to the selected processes and interrupt handling routines are implemented as +regular functions. -To understand the device drivers architecture and method of development of new drivers please refer to chapter [Device drivers](devices/README.md). +To understand the device drivers architecture and method of development of new drivers please refer to chapter +[Device drivers](devices/README.md). ## File servers -File servers are specialized servers implementing filesystem. Similarly to device drivers they implement specific protocol for filesystem operations (for opening, closing, reading and writing files and for operating on directories). Any fileserver can handle any part of the namespace. The selected part of the namespace is assigned to the server by registering its port for the selected directory entry. When applications use the part of the namespace handled by the server during the path resolution procedure, the server`s port is returned in the object identifier and all communication is redirected to the server. +File servers are specialized servers implementing filesystem. Similarly to device drivers they implement specific +protocol for filesystem operations (for opening, closing, reading and writing files and for operating on directories). +Any fileserver can handle any part of the namespace. The selected part of the namespace is assigned to the server by +registering its port for the selected directory entry. When applications use the part of the namespace handled by the +server during the path resolution procedure, the server`s port is returned in the object identifier and all +communication is redirected to the server. File servers are described in [Filesystems](filesystems/README.md) chapter. ## Emulation servers -Microkernel architecture allows to easily emulate the application environment of existing operating systems (e.g. POSIX). To provide some OS specific mechanisms which are not supported by native Phoenix-RTOS environment (e.g. POSIX pipes, user and groups etc.) emulation servers should be provided. They implement the additional functionality and together with emulation libraries provide the application environment. The communication protocol implemented by these servers is specific for emulated application environment. +Microkernel architecture allows to easily emulate the application environment of existing operating systems +(e.g. POSIX). To provide some OS specific mechanisms which are not supported by native Phoenix-RTOS environment +(e.g. POSIX pipes, user and groups etc.) emulation servers should be provided. They implement the additional +functionality and together with emulation libraries provide the application environment. The communication protocol +implemented by these servers is specific for emulated application environment. ## See also -1. [Table of Contents](README.md) \ No newline at end of file +1. [Table of Contents](README.md) diff --git a/building/project.md b/building/project.md index 3627f5bc..96f4a9fc 100644 --- a/building/project.md +++ b/building/project.md @@ -1,6 +1,8 @@ # Reference project -The main repository of Phoenix-RTOS is the [phoenix-rtos-project](https://github.com/phoenix-rtos/phoenix-rtos-project.git). The project consists of the following Github submodule repositories. +The main repository of Phoenix-RTOS is the +[phoenix-rtos-project](https://github.com/phoenix-rtos/phoenix-rtos-project.git). +The project consists of the following Github submodule repositories. - [libphoenix](https://github.com/phoenix-rtos/libphoenix.git)
Standard C library. Written from scratch for Phoenix-RTOS @@ -23,7 +25,8 @@ The main repository of Phoenix-RTOS is the [phoenix-rtos-project](https://github - [phoenix-rtos-ports](https://github.com/phoenix-rtos/phoenix-rtos-ports.git)
Linux (and potentially other OSes) applications ported to Phoenix-RTOS - [phoenix-rtos-posixsrv](https://github.com/phoenix-rtos/phoenix-rtos-posixsrv.git)
- POSIX server; userspace server that is providing additional POSIX features not provided by the kernel itself (e.g. pipes) + POSIX server; userspace server that is providing additional POSIX features not provided by the kernel itself (e.g. + pipes) - [phoenix-rtos-tests](https://github.com/phoenix-rtos/phoenix-rtos-tests.git)
Tests based on our own framework - [phoenix-rtos-usb](https://github.com/phoenix-rtos/phoenix-rtos-usb.git)
@@ -47,11 +50,13 @@ There are also other directories and files directly in `phoenix-rtos-project`. - `scripts` - bash scripts for running Phoenix-RTOS on simulators (e.g. QEMU), -- `build.project` - bash include file, defines how to build the whole system, it is included by phoenix-rtos-build/build.sh, +- `build.project` - bash include file, defines how to build the whole system, it is included by +phoenix-rtos-build/build.sh, - `busybox-config` - configuration for busybox (baseline Linux based toolkit and shell), -- `docker-build.sh` - script for building using docker (docker allows user to not have toolchain on his or her development PC). +- `docker-build.sh` - script for building using docker (docker allows user to not have toolchain on his or +her development PC). ## See also diff --git a/building/script.md b/building/script.md index 7a79c4bf..541c4c67 100644 --- a/building/script.md +++ b/building/script.md @@ -1,6 +1,8 @@ # Building script -To build Phoenix-RTOS system image build.sh script is used. The simplest way to build the image is the following command. +To build Phoenix-RTOS system image build.sh script is used. The simplest way to build the image is the +following command. + ```bash TARGET=ia32-generic-qemu phoenix-rtos-build/build.sh all ``` @@ -8,9 +10,11 @@ TARGET=ia32-generic-qemu phoenix-rtos-build/build.sh all As you can see there can be other arguments like `all`. You can also use the `clean` argument to clean last build artifacts. + ```bash TARGET=ia32-generic-qemu phoenix-rtos-build/build.sh clean all ``` + When you want to compile only the new changes and save time you don't have to use it. The `all` argument specifies that all system components for a given target should be compiled (excluding tests). @@ -30,20 +34,24 @@ The available components are listed below: For example, in ia32-generic-qemu target `all` means `core fs image project ports`.
For the other targets `all` can be different components configurations.
-You can also choose what components do you want to build, for example the following command will build a system image without test and ports components. -The `ports` component compiling process can take a while. If you need to build the system image quickly, you can use the command above. +You can also choose what components do you want to build, for example the following command will build a system image +without test and ports components. +The `ports` component compiling process can take a while. If you need to build the system image quickly, you can use the +command above. ```bash TARGET=ia32-generic-qemu phoenix-rtos-build/build.sh core fs image project test ``` -For ia32-generic-qemu target, running the system in a separate window isn't the only option. There is the possibility to run it in a terminal, in that case, you have to set a few other variables. +For ia32-generic-qemu target, running the system in a separate window isn't the only option. There is the possibility to +run it in a terminal, in that case, you have to set a few other variables. ```bash TARGET=ia32-generic-qemu CONSOLE=serial ./phoenix-rtos-build/build.sh all ``` -After the build completes, the disk image and all files needed to run it will be created and placed in the _boot directory. +After the build completes, the disk image and all files needed to run it will be created and placed in the _boot +directory. ## See also diff --git a/corelibs/README.md b/corelibs/README.md index e5839116..92c9b8dd 100644 --- a/corelibs/README.md +++ b/corelibs/README.md @@ -2,8 +2,10 @@ Phoenix-RTOS provides libraries, which enable the development of applications. -The source code is available in the [phoenix-rtos-corelibs](https://github.com/phoenix-rtos/phoenix-rtos-corelibs) Github repository. -The example of usage can be found in the `_user` directory, placed in [phoenix-rtos-project](https://github.com/phoenix-rtos/phoenix-rtos-project). +The source code is available in the [phoenix-rtos-corelibs](https://github.com/phoenix-rtos/phoenix-rtos-corelibs) +Github repository. +The example of usage can be found in the `_user` directory, placed in +[phoenix-rtos-project](https://github.com/phoenix-rtos/phoenix-rtos-project). Read more about reference project repository [here](../project.md). diff --git a/corelibs/libcache.md b/corelibs/libcache.md index d7b22281..f190eaf2 100644 --- a/corelibs/libcache.md +++ b/corelibs/libcache.md @@ -6,36 +6,41 @@ ![image](_images/libcache.png) ## Contents -- [API](#API) - - [Data types](#data-types) - - [Functions](#functions) -- [Configurable cache parameters](#Configurable-cache-parameters) - - [Size](#size) - - [Associativity](#associativity) - - [Write policy](#write-policy) + +- [API](#api) + - [Data types](#data-types) + - [Functions](#functions) +- [Configurable cache parameters](#configurable-cache-parameters) + - [Size](#size) + - [Associativity](#associativity) + - [Write policy](#write-policy) - [Implementation](#implementation) - - [Overview](#overview) - - [Organization](#organization) - - [Bitmasks](#bitmasks) - - [Data structures](#data-structures) + - [Overview](#overview) + - [Organization](#organization) + - [Bitmasks](#bitmasks) + - [Data structures](#data-structures) - [Cache operations](#cache-operations) - - [Read](#reading-a-buffer-from-a-device-via-the-cache) - - [Write](#writing-a-buffer-to-a-device-via-the-cache) - - [Flush](#flushing-the-cache) - - [Invalidate](#invalidating-the-cache) - - [Clean](#cleaning-the-cache) + - [Read](#reading-a-buffer-from-a-device-via-the-cache) + - [Write](#writing-a-buffer-to-a-device-via-the-cache) + - [Flush](#flushing-the-cache) + - [Invalidate](#invalidating-the-cache) + - [Clean](#cleaning-the-cache) - [Running tests](#running-tests) -- [Navigation links](#See-also) +- [Navigation links](#see-also) ## API -The `libcache` library is a collection of types and functions which provides the user with tools necessary to create, operate and destroy a cache. -

-The user is obligated to supply a suitable definition of a device driver context and source memory-specific callbacks that execute write to and read from the cached source memory. + +The `libcache` library is a collection of types and functions which provides the user with tools necessary to create, +operate and destroy a cache. + +The user is obligated to supply a suitable definition of a device driver context and source memory-specific callbacks +that execute write to and read from the cached source memory. ### Data types + | Type | Description | Remarks | | ---- | ------------| ------- | -`cachectx_t` | Cache context — represents the cache table | Opaque type — can only be accessed and/or modified through/by provided API functions. +`cachectx_t` | Cache context — represents the cache table |Opaque type — can only be accessed and/or modified through/by provided API functions. `cache_devCtx_t` | Device driver context | A cached source memory-specific `struct cache_devCtx_s` definition ought to be supplied by the user.

Constitutes a part of `cache_ops_t` interface. | | `cache_ops_t` | Cached source memory interface | Mediates between the cache and the cached source memory by providing write (`cache_writeCb_t writeCb`) and read (`cache_readCb_t readCb`) callbacks as well as the device driver context (`cache_devCtx_t ctx`). | @@ -44,6 +49,7 @@ The user is obligated to supply a suitable definition of a device driver context ```c typedef ssize_t (*cache_readCb_t)(uint64_t offset, void *buffer, size_t count, cache_devCtx_t *ctx); ``` + | Status | Description | Return value | Remarks | |--------|-------------|--------------| ------- | | Declared | Read callback — a pointer to a function responsible for reading data from the source memory. The pointer is registered in the cache during a call to `cache_init` function.

Reads up to `count` bytes starting from `offset` into a `buffer`.

Utilizes additional device driver context provided in `ctx`.| **On success:** a number of bytes read from the cached source memory

**On failure:** an error number | `count` is **always** equal to cache line size.

A cached source memory-specific implementation ought to be supplied by the user.

Constitutes a part of `cache_ops_t` interface. | @@ -51,14 +57,17 @@ typedef ssize_t (*cache_readCb_t)(uint64_t offset, void *buffer, size_t count, c ```c typedef ssize_t (*cache_writeCb_t)(uint64_t offset, const void *buffer, size_t count, cache_devCtx_t *ctx); ``` + | Status | Description | Return value | Remarks | |--------|-------------|--------------| ------- | | Declared | Write callback — a pointer to a function responsible for writing data to the source memory. The pointer is registered in the cache during a call to `cache_init` function.

Writes up to `count` bytes from `buffer` under `offset`.

Utilizes additional device driver context provided in `ctx`.| **On success:** a number of bytes written to the cached source memory

**On failure:** an error number | `count` is **always** equal to cache line size.

A cached source memory-specific implementation ought to be supplied by the user.

Constitutes a part of `cache_ops_t` interface. | ### Functions + ```c cachectx_t *cache_init(size_t srcMemSize, size_t lineSize, size_t linesCnt, const cache_ops_t *ops); ``` + | Status | Description | Return value | Remarks | |--------|-------------|--------------| ------- | |Implemented

Tested| Initializes the cache for use. Stores the size of the cached source memory as `srcMemSize` (in bytes). Sets the cache line size to `lineSize` (in bytes) and the number of cache lines to `linesCnt`.

Registers cached source memory interface (`ops`) which contains write and read callbacks as well as device driver context. | **On success:** a pointer to initialized cache of type `cachectx_t`

**On failure:** NULL | The `linesCnt` argument has to be a multiple of the number of ways in a set (see: [Associativity](#associativity)).

Copies and stores the contents pointed to by `ops`: `writeCb`, `readCb` as well as the pointer `ctx`. Note that a pointer to `cache_devCtx_t` is stored, **not** its contents. @@ -66,6 +75,7 @@ cachectx_t *cache_init(size_t srcMemSize, size_t lineSize, size_t linesCnt, cons ```c int cache_deinit(cachectx_t *cache); ``` + | Status | Description | Return value | Remarks | |--------|-------------|--------------| ------- | | Implemented

Tested | Performs cache flush and invalidation and then deinitializes the cache: frees all allocated resources (cache lines, sets as well as the cache table). | **On success:** 0

**On failure:** an error number | May fail due to problems with the cached source memory (``EIO``). @@ -73,6 +83,7 @@ int cache_deinit(cachectx_t *cache); ```c ssize_t cache_read(cachectx_t *cache, uint64_t addr, void *buffer, size_t count); ``` + | Status | Description | Return value | Remarks | |--------|-------------|--------------| ------- | | Implemented

Tested| Reads from the device via the cache up to `count` bytes into a `buffer`. | **On success:** the number of read bytes

**On failure:** an error number | Fails if `buffer` is NULL or/and `addr` goes beyond the scope of the cached source memory. (`EINVAL`).

May fail due to problems with the cached source memory (`EIO`).

The behavior is undefined if read occurs beyond the end of the `buffer`. @@ -80,6 +91,7 @@ ssize_t cache_read(cachectx_t *cache, uint64_t addr, void *buffer, size_t count) ```c ssize_t cache_write(cachectx_t *cache, uint64_t addr, void *buffer, size_t count, int policy); ``` + | Status | Description | Return value | Remarks | |--------|-------------|--------------| ------- | | Implemented

Tested | Writes to the device via the cache up to `count` bytes from a `buffer` according to `policy` (see: [Write policy](#write-policy)) | **On success:** the number of written bytes

**On failure:** an error number | Fails if `buffer` is NULL or/and wrong `policy` value is supplied (`EINVAL`). Fails when `addr` goes beyond the scope of the cached source memory.

May fail due to problems with the cached source memory (`EIO`).

The behavior is undefinded if write occurs beyond the end of the `buffer`. @@ -87,6 +99,7 @@ ssize_t cache_write(cachectx_t *cache, uint64_t addr, void *buffer, size_t count ```c int cache_flush(cachectx_t *cache, const uint64_t begAddr, const uint64_t endAddr); ``` + | Status | Description | Return value | Remarks | |--------|-------------|--------------| ------- | | Implemented

Tested | Flushes a range of cache lines starting from an address `begAddr` up to `endAddr`.

Writes dirty lines (see: [Write policy](#write-policy)) marked with dirty bit to the cached source memory. Clears the dirty bit. | **On success:** 0 (i.e. all bytes from all lines marked with the dirty bit in given range were successfully written to the cached source memory)

**On failure:** an error number | Fails if `begAddr` is greater than `endAddr` or/and `begAddr` is greater than `srcMemSize` (`EINVAL`).

May fail due to problems with the cached source memory (`EIO`). @@ -94,6 +107,7 @@ int cache_flush(cachectx_t *cache, const uint64_t begAddr, const uint64_t endAdd ```c int cache_invalidate(cachectx_t *cache, const uint64_t begAddr, const uint64_t endAddr); ``` + | Status | Description | Return value | Remarks | |--------|-------------|--------------| ------- | | Implemented

Tested | Invalidates a range of cache lines starting from an address `begAddr` up to `endAddr`.

Clears the validity bit for lines in that range. | **On success:** 0 (i.e. all lines marked with the validity bit in the given range were successfully invalidated)

**On failure:** an error number | Fails if `begAddr` is greater than `endAddr` or/and `begAddr` is greater than `srcMemSize` (`EINVAL`).

This operation does **not** synchronize the dirty lines with the cached source memory and leads to **permanent** data loss. In order to save the important data it is advised to call `cache_clean` instead. @@ -101,40 +115,58 @@ int cache_invalidate(cachectx_t *cache, const uint64_t begAddr, const uint64_t e ```c int cache_clean(cachectx_t *cache, const uint64_t begAddr, const uint64_t endAddr); ``` + | Status | Description | Return value | Remarks | |--------|-------------|--------------| ------- | | Implemented

Untested | Combines cache flush and invalidation in an atomic way and performs these operations in range of addresses starting from `begAddr` up to `endAddr`. | **On success:** 0 (i.e. all lines in given range were successfully flushed to the cached source memory and invalidated)

**On failure:** an error number | Fails if `begAddr` is greater than `endAddr` or/and `begAddr` is greater than `srcMemSize` (`EINVAL`).

May fail due to problems with the cached source memory (`EIO`).

Does **not** invalidate a line that failed to flush. | ## Configurable cache parameters + ### Size -1. The size of the cache line (in bytes) and the number of the lines can be set in run-time during a call to the `cache_init` function. These paremeters cannot be reconfigured once set. + +1. The size of the cache line (in bytes) and the number of the lines can be set in run-time during a call to the +`cache_init` function. These paremeters cannot be reconfigured once set. 2. The number of cache lines has to be divisible by [associativity](#associativity). ### Associativity -The number of ways in a set (i.e. the number of lines in a set) is defined in a form of a macro directive `LIBCACHE_NUM_WAYS`. The value is set to 4 by default as it was deemed suitable for typical uses. -

-Other common associativities are 1 (a fully associative cache), 2, 4 and 8. Larger sets and higher associativity lead to fewer cache conflicts and lower miss rates at the expense of hardware cost. + +The number of ways in a set (i.e. the number of lines in a set) is defined in a form of a macro directive +`LIBCACHE_NUM_WAYS`. The value is set to 4 by default as it was deemed suitable for typical uses. + +Other common associativities are 1 (a fully associative cache), 2, 4 and 8. Larger sets and higher associativity lead +to fewer cache conflicts and lower miss rates at the expense of hardware cost. ### Write policy -There are two available write policies: write-through and write-back. The policy is set individually for every write operation by choice of a suitable value of `policy` argument of the `cache_write` function: + +There are two available write policies: write-through and write-back. The policy is set individually for every write +operation by choice of a suitable value of `policy` argument of the `cache_write` function: + - `LIBCACHE_WRITE_BACK` - `LIBCACHE_WRITE_THROUGH` -According to the write through policy the data from the written/updated line is synchronized with the cached source memory upon every write to the cache, therefore they stay coherent at all times. +According to the write through policy the data from the written/updated line is synchronized with the cached source +memory upon every write to the cache, therefore they stay coherent at all times. + +The write back policy allows the cache and the cached source memory to stay incoherent until the user requests flushing +or the old, incoherent data needs to be replaced by new data. -The write back policy allows the cache and the cached source memory to stay incoherent until the user requests flushing or the old, incoherent data needs to be replaced by new data. ## Implementation + ### Overview -`libcache` implements the cache as a set-associative cache with n ways and s sets. A cache line contains a tag, a pointer to cached data and flags indicating its validity and whether it is coherent with the cached source memory. + +`libcache` implements the cache as a set-associative cache with n ways and s sets. A cache line contains a tag, a +pointer to cached data and flags indicating its validity and whether it is coherent with the cached source memory. The number of ways in a set (associativity) is simply the maximum number of lines within a set. **The cache is implemented for 64-bit addressing.** ### Organization + The organizaton of the cache is best explained by an example:

-_Full address of 64 bits (fixed in implementation, unalterable), associativity of 4 (fixed), cache line size of 64 bytes, 32 cache lines._ +_Full address of 64 bits (fixed in implementation, unalterable), associativity of 4 (fixed), cache line size of 64 bytes +,32 cache lines._ | Parameter | How it is computed | Example | | --------- | ------------------ | ------- | Offset address width | log2(cache line size) | log2(64) = 6 bits | @@ -146,10 +178,13 @@ The above example is illustrated in the image below. ![image](_images/libcache_mem_addr.png) -_DISCLAIMER: The numbers of bits corresponding to tag, set index and offset may differ depending on your own example._ +_DISCLAIMER: The numbers of bits corresponding to tag, set index and offset may differ depending on your own example._ ### Bitmasks -Three bitmasks are computed and stored. They are applied to memory addresses in order to extract specific bits corresponding to tag, set index and offset. The tag is used to identify a cache line within a set. The offset indicates the position of a specific byte in that cache line. + +Three bitmasks are computed and stored. They are applied to memory addresses in order to extract specific bits +corresponding to tag, set index and offset. The tag is used to identify a cache line within a set. The offset indicates +the position of a specific byte in that cache line. | Parameter | How it is computed | | --------- | ------------------ | @@ -158,51 +193,101 @@ Three bitmasks are computed and stored. They are applied to memory addresses in | Offset | full address _AND_ offset mask | ### Data structures + Each cache set stores a table of cache lines (green table in image below). Moreover, it keeps: + - a table of pointers to cache lines sorted by the tags (dark grey table); -- a supplementary circular doubly linked list of pointers to the same cache lines sorted by the time of last access to these lines. The pointer to the _Most Recently Used_ cache line (MRU) is stored in the tail of the list. +- a supplementary circular doubly linked list of pointers to the same cache lines sorted by the time of last access to +these lines. The pointer to the _Most Recently Used_ cache line (MRU) is stored in the tail of the list. The image below represents the logical organization of the implemented cache. ![image](_images/libcache_impl.png) ## Cache operations -The index in set-associative cache identifies a set of cache lines that may contain the requested data. During a read or write (create/update) operation every line within the set is examined to check whether its tag matches the tag computed from a supplied memory address and that the VALID bit of that line is set. If both these conditions are met, we have a _cache hit_. Otherwise, on a _cache miss_, a new block of memory in form of a cache line has to be loaded into the set, replacing the _Least Recently Used_ (LRU) line in that set. + +The index in set-associative cache identifies a set of cache lines that may contain the requested data. During a read +or write (create/update) operation every line within the set is examined to check whether its tag matches the tag +computed from a supplied memory address and that the VALID bit of that line is set. If both these conditions are met, +we have a _cache hit_. Otherwise, on a _cache miss_, a new block of memory in form of a cache line has to be loaded +into the set, replacing the _Least Recently Used_ (LRU) line in that set. + ### Reading a buffer from a device via the cache -In order to read up to count bytes from a source memory address, a valid buffer has to be supplied. Set index, tag and offset of the first byte to be read from a cache line marked by the tag are computed from the requested memory address.

The user might want to read just a few bytes starting from the offset. However, when count goes beyond the maximum offset of the line, a read from multiple lines is performed. At first, a chunk of data of size equal to
(size of cache line - offset of the first byte)
is read into the buffer. Depending on the size of the requested data, a few next whole cache lines might be read into the buffer. The address of the first whole line is computed as follows: -
-(address of the first byte to be read - offset of the first byte) + size of a cache line
- The addresses of following lines are computed by adding the size of a whole cache line to the address of a previous line. Each of these addresses is mapped on to a specific cache set. Lookup in a set is performed according to the algorithm below: -1. The tag computed from the memory address becomes a part of a key used to perform binary search in a table of pointers to cache lines sorted by the tag (dark grey table in the image above). -2. If a line marked by the tag is found, it becomes the MRU line. The pointers in the circular doubly linked list are rearranged so that this line is stored in the tail of the list. +In order to read up to count bytes from a source memory address, a valid buffer has to be supplied. Set index, tag and +offset of the first byte to be read from a cache line marked by the tag are computed from the requested memory address. + +The user might want to read just a few bytes starting from the offset. However, when count goes beyond the +maximum offset of the line, a read from multiple lines is performed. At first, a chunk of data of size equal to +
 (size of cache line - offset of the first byte)
+
is read into the buffer. Depending on the size of the requested data, a few next whole cache lines might be read +into the buffer. The address of the first whole line is computed as follows: +
 (address of the first byte to be read - offset of the first byte) + size of a cache line 
+ The addresses of following lines are computed by adding the size of a whole cache line to the address of a previous + line. Each of these addresses is mapped on to a specific cache set. Lookup in a set is performed according to the + algorithm below: + +1. The tag computed from the memory address becomes a part of a key used to perform binary search in a table of pointers +to cache lines sorted by the tag (dark grey table in the image above). +2. If a line marked by the tag is found, it becomes the MRU line. The pointers in the circular doubly linked list are +rearranged so that this line is stored in the tail of the list. 3. The pointer to the found line is returned. The desired chunk of data is read from the obtained line and written to the buffer supplied by the user. + ### Writing a buffer to a device via the cache -Writing via the cache is implemented similarly to reading: data is written in the cache chunk-by-chunk from a supplied buffer.

The user might want to update just a few bytes in a specific cache line, hence the line needs to be found in the cache first. On success the bytes starting from the offset are updated and a chosen write policy is executed.

If it happens that a line mapped from a specific address does not exist in the cache, it is created and written to the cache according to the algorithm below: -1. The pointer to the LRU line is removed from the circular doubly linked list and dereferenced to find a pointee (a line in the green table). -2. The line pointed to may be flushed to the cached source memory for coherence. Afterwards it is substituted by a new cache line. -3. A pointer to the new cache line is added in the tail of the circular doubly linked list. The line pointed to becomes the MRU line. +Writing via the cache is implemented similarly to reading: data is written in the cache chunk-by-chunk from a supplied +buffer. + +The user might want to update just a few bytes in a specific cache line, hence the line needs to be +found in the cache first. On success the bytes starting from the offset are updated and a chosen write policy is +executed. + +If it happens that a line mapped from a specific address does not exist in the cache, it is +created and written to the cache according to the algorithm below: + +1. The pointer to the LRU line is removed from the circular doubly linked list and dereferenced to find a pointee (a +line in the green table). +2. The line pointed to may be flushed to the cached source memory for coherence. Afterwards it is substituted by a new +cache line. +3. A pointer to the new cache line is added in the tail of the circular doubly linked list. The line pointed to becomes +the MRU line. 4. The pointers to the lines are re-sorted according to the tag (dark grey table). ### Flushing the cache -The flush operation is used to synchronize the contents of the cache with the cached source memory so that they stay coherent.

The operation requires a beginning and an end address, as it is performed within a range of addresses. + +The flush operation is used to synchronize the contents of the cache with the cached source memory so that they stay +coherent. + +The operation requires a beginning and an end address, as it is performed within a range of +addresses. + ### Invalidating the cache -A range of the cached source memory addresses can be invalidated and data removed so that the lines can be overwritten. The data is not being synchronized with the cached source memory during this operation, therefore it cannot be retrieved once the lines become invalidated. -In order to save the important data on the source memory and invalidate the lines in the cache it is advised to perform cache clean instead. +A range of the cached source memory addresses can be invalidated and data removed so that the lines can be overwritten. +The data is not being synchronized with the cached source memory during this operation, therefore it cannot be +retrieved once the lines become invalidated. + +In order to save the important data on the source memory and invalidate the lines in the cache it is advised to perform +cache clean instead. ### Cleaning the cache -The clean operation combines both cache flush and cache invalidate operations in atomic way while also providing a better efficiency than if the user were to perform cache flush followed by cache invalidate. + +The clean operation combines both cache flush and cache invalidate operations in atomic way while also providing a +better efficiency than if the user were to perform cache flush followed by cache invalidate. + ## Running tests -Phoenix-RTOS libcache library provides a set of functional tests that are available in [phoenix-rtos-tests](https://github.com/phoenix-rtos/phoenix-rtos-tests/tree/master). The tests can be run for different platforms, e.g. `ia32-generic-qemu` target: -``` +Phoenix-RTOS libcache library provides a set of functional tests that are available in +[phoenix-rtos-tests](https://github.com/phoenix-rtos/phoenix-rtos-tests/tree/master). The tests can be run for +different platforms, e.g. `ia32-generic-qemu` target: + +```bash python3 phoenix-rtos-tests/runner.py -T ia32-generic-qemu -t phoenix-rtos-tests/libcache ``` ## See also + 1. [Phoenix-RTOS core libraries](README.md) 2. [Table of contents](../README.md) diff --git a/corelibs/libgraph.md b/corelibs/libgraph.md index d608af14..852be123 100644 --- a/corelibs/libgraph.md +++ b/corelibs/libgraph.md @@ -1,17 +1,18 @@ # Graphics library (libgraph) -`libgraph` is a graphics library that allows for scheduling and (possibly hardware accelerated) execution of 2D graphics operations. +`libgraph` is a graphics library that allows for scheduling and (possibly hardware accelerated) execution of 2D +graphics operations. -Source code: https://github.com/phoenix-rtos/phoenix-rtos-corelibs/tree/master/libgraph +Source code: ## Contents -- [Supported graphics adapters](#Graphics-adapters) +- [Supported graphics adapters](#graphics-adapters) - [libgraph applications](#libgraph-apps) - [libgraph interface](#libgraph-interface) -- [How to use the graphics library](#How-to-use-the-graphics-library) -- [How to use your own image in Phoenix-RTOS](#Generating-an-image-bitmap-and-displaying-it-using-libgraph) -- [Navigation links](#See-also) +- [How to use the graphics library](#how-to-use-the-graphics-library) +- [How to use your own image in Phoenix-RTOS](#generating-an-image-bitmap-and-displaying-it-using-libgraph) +- [Navigation links](#see-also) ## Graphics adapters @@ -31,10 +32,12 @@ Examples of applications, which use graphics library (`ia32-generic-qemu` target ![Output sample](_gifs/voxeldemo.gif) - Source code can be found in the `_user` directory in [phoenix-rtos-project](https://github.com/phoenix-rtos/phoenix-rtos-project.git) repository. + Source code can be found in the `_user` directory in + [phoenix-rtos-project](https://github.com/phoenix-rtos/phoenix-rtos-project.git) repository. The app can be run using the following command: - ``` + + ```bash /usr/bin/voxeldemo ``` @@ -42,10 +45,12 @@ Examples of applications, which use graphics library (`ia32-generic-qemu` target ![image](_images/rotrectangle.png) - Source code can be also found in the `_user` directory in [phoenix-rtos-project](https://github.com/phoenix-rtos/phoenix-rtos-project.git) repository. + Source code can be also found in the `_user` directory in + [phoenix-rtos-project](https://github.com/phoenix-rtos/phoenix-rtos-project.git) repository. The app can be run using the following command: - ``` + + ```bash /usr/bin/rotrectangle ``` @@ -53,37 +58,48 @@ Examples of applications, which use graphics library (`ia32-generic-qemu` target ![image](_images/test_graph.png) - Source code is available in the `gfx` directory in [phoenix-rtos-tests](https://github.com/phoenix-rtos/phoenix-rtos-tests.git) repository. + Source code is available in the `gfx` directory in + [phoenix-rtos-tests](https://github.com/phoenix-rtos/phoenix-rtos-tests.git) repository. The test can be run using the following command: - ``` + + ```bash /bin/test_graph ``` -## libgraph interface +## libgraph interface -`libgraph` functions take _`graph`_ argument which is a pointer to `graph_t` structure initialized by `graph_open()`. `graph_adapter_t` is an enum used to distinguish between different graphics adapters. +`libgraph` functions take _`graph`_ argument which is a pointer to `graph_t` structure initialized by +`graph_open()`. `graph_adapter_t` is an enum used to distinguish between different graphics adapters. + +- `int graph_init(void)` -- `int graph_init(void)`
Initializes the graphics library and all required drivers. -- `int graph_open(graph_t *graph, graph_adapter_t adapter, unsigned int mem)`
- Initializes the `graph_t` structure and opens a context for the specified graphics adapter. The uninitialized `graph_t` structure should be passed in the _`graph`_ argument and the graphics _`adapter`_ should be chosen from the following list: +- `int graph_open(graph_t *graph, graph_adapter_t adapter, unsigned int mem)` + + Initializes the `graph_t` structure and opens a context for the specified graphics adapter. The uninitialized + `graph_t` structure should be passed in the _`graph`_ argument and the graphics _`adapter`_ should be chosen from the + following list: - `GRAPH_NONE` - the graphics adapter isn't specified, in this case the function returns `-ENODEV` - `GRAPH_VIRTIOGPU` - generic VirtIO GPU graphics adapter - `GRAPH_VGA` - generic VGA graphics adapter - `GRAPH_CIRRUS` - Cirrus Logic graphics adapter - `GRAPH_ANY` - an available graphics adapter is chosen - The _`mem`_ argument specifies the total graphics tasks queue size. The bigger the _`mem`_ the more graphics tasks we can queue up. + The _`mem`_ argument specifies the total graphics tasks queue size. The bigger the _`mem`_ the more graphics tasks we + can queue up. The return value is set to `EOK`, or an error number, for example: - `-EINVAL` - specified memory value is too low - `-ENOMEM` - memory allocation for graphics context failed - `-ENODEV` - incorrect graphics adapter passed in _`adapter`_ -- `int graph_mode(graph_t *graph, graph_mode_t mode, graph_freq_t freq)`
- Sets graphics mode with specified screen refresh rate frequency. The initialized _`graph`_ structure should be passed, and _`mode`_ should be chosen from the `graph_mode_t` enum, placed in the `graph.h` header. The common graphics modes are presented below: +- `int graph_mode(graph_t *graph, graph_mode_t mode, graph_freq_t freq)` + + Sets graphics mode with specified screen refresh rate frequency. The initialized _`graph`_ structure should be passed, + and _`mode`_ should be chosen from the `graph_mode_t` enum, placed in the `graph.h` header. The common graphics modes + are presented below: - `GRAPH_DEFMODE` - default graphics mode - `GRAPH_ON` - display enabled mode - `GRAPH_OFF` - display disabled mode @@ -93,14 +109,17 @@ Examples of applications, which use graphics library (`ia32-generic-qemu` target - `GRAPH_320x200x16` - 320x200 resolution, 16-bit color mode - `GRAPH_1920x1080x32` - 1920x1080 resolution, 32-bit color mode - There should also be specified the _`freq`_ argument (`graph_freq_t` enum). The common screen refresh rates are presented below: + There should also be specified the _`freq`_ argument (`graph_freq_t` enum). The common screen refresh rates are + presented below: - `GRAPH_DEFFREQ` - default refresh rate - `GRAPH_24Hz` - 24Hz refresh rate - `GRAPH_60Hz` - 60Hz refresh rate - `GRAPH_120Hz` - 120Hz refresh rate - `GRAPH_360Hz` - 360Hz refresh rate -- `int graph_line(graph_t *graph, unsigned int x, unsigned int y, int dx, int dy, unsigned int stroke, unsigned int color, graph_queue_t queue)`
+- `int graph_line(graph_t *graph, unsigned int x, unsigned int y, int dx, int dy, unsigned int stroke, unsigned int +color, graph_queue_t queue)` + Draws a line for the specified graphics adapter context. The following arguments should be passed: - _`graph`_ - initialized `graph_t` structure - _`x`_ - start point x position, where 0 is the left edge of the screen @@ -114,13 +133,14 @@ Examples of applications, which use graphics library (`ia32-generic-qemu` target ![image](_images/def_color_palette.png) - Source: https://www.fountainware.com/EXPL/vga_color_palettes.htm + Source: - for `16-bit` color depth - it's the following format in bits: `RRRRRGGGGGGBBBBB` (e.g. `0x07E0` represents green) - for `24-bit` color depth - it's represented by `0xRRGGBB` (e.g. `0x0000FF` represents blue) - - for `32-bit` color depth - it's the following format in hex: `0xAARRGGBB`, where `A` represents alpha. With `AA` set to `0xFF` opacity equals 100%, but by default transparency isn't enabled so there can be any value. + - for `32-bit` color depth - it's the following format in hex: `0xAARRGGBB`, where `A` represents alpha. With `AA` + set to `0xFF` opacity equals 100%, but by default transparency isn't enabled so there can be any value. - _`queue`_ - graphics task queue, should be chosen from the `graph_queue_t` enum, where are following options: - `GRAPH_QUEUE_HIGH` - high priority queue @@ -128,69 +148,112 @@ Examples of applications, which use graphics library (`ia32-generic-qemu` target - `GRAPH_QUEUE_BOTH` - any queue - `GRAPH_QUEUE_DEFAULT` - default queue -- `int graph_rect(graph_t *graph, unsigned int x, unsigned int y, unsigned int dx, unsigned int dy, unsigned int color, graph_queue_t queue)`
- Draws a rectangle. Arguments are similar to those in `graph_line()` function. A drawn rectangle will be filled with a specified color. +- `int graph_rect(graph_t *graph, unsigned int x, unsigned int y, unsigned int dx, unsigned int dy, unsigned int +color, graph_queue_t queue)` + + Draws a rectangle. Arguments are similar to those in `graph_line()` function. A drawn rectangle will be filled with a + specified color. + +- `int graph_fill(graph_t *graph, unsigned int x, unsigned int y, unsigned int color, graph_fill_t type, graph_queue_t +queue)` + + Fills a closed figure with color specified in the _`color`_ argument ((_`x`_, _`y`_) should be any point inside the + figure to fill). The following `graph_fill_t` color fill methods are supported: + - `GRAPH_FILL_FLOOD` - works like Windows paint bucket tool (floods homogeneous area, all pixels inside the polygon + with color values same as the one at (_`x`_, _`y`_) flood origin point) + + - `GRAPH_FILL_BOUND` - fills the polygon until an edge of the same color as the fill color is found. It can't fill the + figure with color different than the figure boundary + +- `int graph_print(graph_t *graph, const graph_font_t *font, const char *text, unsigned int x, unsigned int y, unsigned +char dx, unsigned char dy, unsigned int color, graph_queue_t queue)` -- `int graph_fill(graph_t *graph, unsigned int x, unsigned int y, unsigned int color, graph_fill_t type, graph_queue_t queue)`
- Fills a closed figure with color specified in the _`color`_ argument ((_`x`_, _`y`_) should be any point inside the figure to fill). The following `graph_fill_t` color fill methods are supported: - - `GRAPH_FILL_FLOOD` - works like Windows paint bucket tool (floods homogeneous area, all pixels inside the polygon with color values same as the one at (_`x`_, _`y`_) flood origin point) + Prints text pointed by the _`text`_ argument. Font data should be passed to `graph_font_t` structure. The example is + stored in `gfx` directory in[phoenix-rtos-tests](https://github.com/phoenix-rtos/phoenix-rtos-tests.git) + repository (`font.h` file). The remaining arguments are similar to those from functions above. - - `GRAPH_FILL_BOUND` - fills the polygon until an edge of the same color as the fill color is found. It can't fill the figure with color different than the figure boundary +- `int graph_move(graph_t *graph, unsigned int x, unsigned int y, unsigned int dx, unsigned int dy, int mx, int my, +graph_queue_t queue)` -- `int graph_print(graph_t *graph, const graph_font_t *font, const char *text, unsigned int x, unsigned int y, unsigned char dx, unsigned char dy, unsigned int color, graph_queue_t queue)`
- Prints text pointed by the _`text`_ argument. Font data should be passed to `graph_font_t` structure. The example is stored in `gfx` directory in [phoenix-rtos-tests](https://github.com/phoenix-rtos/phoenix-rtos-tests.git) repository (`font.h` file). The remaining arguments are similar to those from functions above. + Moves data in the range specified by _`x`_, _`y`_, _`dx`_, _`dy`_ arguments to the following point: (_`x`_ + _`mx`_, + _`y`_ + _`my`_). -- `int graph_move(graph_t *graph, unsigned int x, unsigned int y, unsigned int dx, unsigned int dy, int mx, int my, graph_queue_t queue)`
- Moves data in the range specified by _`x`_, _`y`_, _`dx`_, _`dy`_ arguments to the following point: (_`x`_ + _`mx`_, _`y`_ + _`my`_). +- `graph_copy(graph_t *graph, const void *src, void *dst, unsigned int dx, unsigned int dy, unsigned int srcspan, +unsigned int dstspan, graph_queue_t queue)` -- `graph_copy(graph_t *graph, const void *src, void *dst, unsigned int dx, unsigned int dy, unsigned int srcspan, unsigned int dstspan, graph_queue_t queue)`
- Copies a bitmap pointed by the _`src`_ argument into bitmap pointed by the _`dst`_ argument. The area which is copied is limited by a rectangle with _`dx`_ and _`dy`_ dimensions. There should also be specified span arguments, which is the total width of a source/destination bitmap multiplied by its color depth. When copying some part of a bitmap, _`src`_ should point to the proper element, same with destination buffer. + Copies a bitmap pointed by the _`src`_ argument into bitmap pointed by the _`dst`_ argument. The area which is copied + is limited by a rectangle with _`dx`_ and _`dy`_ dimensions. There should also be specified span arguments, which is + the total width of a source/destination bitmap multiplied by its color depth. When copying some part of a bitmap, + _`src`_ should point to the proper element, same with destination buffer. -- `int graph_colorset(graph_t *graph, const unsigned char *colors, unsigned char first, unsigned char last)`
- Sets a color palette used for 8-bit indexed color mode. A color map should be passed in _`cmap`_ argument. The range of changing colors is set by passing _`first`_ and _`last`_ arguments. If a set color palette's size is lower than a default one, remaining colors are the same. +- `int graph_colorset(graph_t *graph, const unsigned char *colors, unsigned char first, unsigned char last)` -- `graph_colorget(graph_t *graph, unsigned char *colors, unsigned char first, unsigned char last)`
- Retrieves a color palette used in 8-bit indexed color mode.. The retrieved color map from _`first`_ to _`last`_ element is passed to a buffer pointed by the _`colors`_ argument. + Sets a color palette used for 8-bit indexed color mode. A color map should be passed in _`cmap`_ argument. The range + of changing colors is set by passing _`first`_ and _`last`_ arguments. If a set color palette's size is lower than a + default one, remaining colors are the same. -- `int graph_cursorset(graph_t *graph, const unsigned char *amask, const unsigned char *xmask, unsigned int bg, unsigned int fg)`
- Sets cursor icon, _`amask`_ (`AND` mask) and _`xmask`_ (`XOR` mask) arguments determine the shape of the cursor. Default cursor shape is defined in `cursor.h` header file placed in `gfx` directory in `phoenix-rtos-tests` repository. There is possibility to pass cursor colors - outline color (`bg` argument) and main color (`fg` argument). The following color format should be applied: `0xAARRGGBB`, where `A` represents alpha, so when it's set to `0xff` 100% opacity is provided. Opacity isn't supported for cirrus graphics adapter (default for `ia32-generic-qemu` target). +- `graph_colorget(graph_t *graph, unsigned char *colors, unsigned char first, unsigned char last)` + + Retrieves a color palette used in 8-bit indexed color mode.. The retrieved color map from _`first`_ to _`last`_ + element is passed to a buffer pointed by the _`colors`_ argument. + +- `int graph_cursorset(graph_t *graph, const unsigned char *amask, const unsigned char *xmask, unsigned int bg, unsigned +int fg)` + + Sets cursor icon, _`amask`_ (`AND` mask) and _`xmask`_ (`XOR` mask) arguments determine the shape of the cursor. + Default cursor shape is defined in `cursor.h` header file placed in `gfx` directory in `phoenix-rtos-tests` + repository. There is possibility to pass cursor colors - outline color (`bg` argument) and main color (`fg` argument). + The following color format should be applied: `0xAARRGGBB`, where `A` represents alpha, so when it's set to `0xff` + 100% opacity is provided. Opacity isn't supported for cirrus graphics adapter (default for `ia32-generic-qemu` target) + +- `int graph_cursorpos(graph_t *graph, unsigned int x, unsigned int y)` -- `int graph_cursorpos(graph_t *graph, unsigned int x, unsigned int y)`
Sets cursor position. -- `int graph_cursorshow(graph_t *graph)`
+- `int graph_cursorshow(graph_t *graph)` + Displays cursor. -- `int graph_cursorhide(graph_t *graph)`
+- `int graph_cursorhide(graph_t *graph)` + Hides cursor. -- `int graph_commit(graph_t *graph);`
+- `int graph_commit(graph_t *graph);` + Commits frame buffer changes (flushes frame buffer) in the specified graphics adapter context. -- `int graph_trigger(graph_t *graph)`
+- `int graph_trigger(graph_t *graph)` + Triggers next task from queue execution. -- `int graph_stop(graph_t *graph, graph_queue_t queue)`
+- `int graph_stop(graph_t *graph, graph_queue_t queue)` + Disable adding new tasks to specified queue, for a _`graph`_ context. -- `int graph_tasks(graph_t *graph, graph_queue_t queue)`
+- `int graph_tasks(graph_t *graph, graph_queue_t queue)` + Returns number of tasks in queue. -- `int graph_reset(graph_t *graph, graph_queue_t queue)`
+- `int graph_reset(graph_t *graph, graph_queue_t queue)` + Resets task queue. -- `int graph_vsync(graph_t *graph)`
+- `int graph_vsync(graph_t *graph) + Returns number of vertical synchronizations since the last call -- `void graph_close(graph_t *graph)`
+- `void graph_close(graph_t *graph)` + Closes a graph context, pointed by _`graph`_. -- `void graph_done(void)`
+- `void graph_done(void)` + Closes the graphics library. ## How to use the graphics library -Few simple examples of `libgraph` functions usage. Default graphics adapter (`cirrus`) for `ia32-generic-qemu` running script is used, default color depth is 4 bytes. Before calling mentioned functions following initialization was applied: +Few simple examples of `libgraph` functions usage. Default graphics adapter (`cirrus`) for `ia32-generic-qemu` running +script is used, default color depth is 4 bytes. Before calling mentioned functions following initialization was applied: ```c #include @@ -242,7 +305,8 @@ int main(void) - Printing text using libgraph - Header file with a font data in `graph_font_t` structure has to be included. The example of `font.h` is placed in `gfx` directory in [phoenix-rtos-tests](https://github.com/phoenix-rtos/phoenix-rtos-tests) repository. + Header file with a font data in `graph_font_t` structure has to be included. The example of `font.h` is placed in + `gfx` directory in [phoenix-rtos-tests](https://github.com/phoenix-rtos/phoenix-rtos-tests) repository. ```C graph_print(&graph, &font, "lorem ipsum", 300, 300, font.height, font.height, 0x00FF00, GRAPH_QUEUE_HIGH); @@ -262,7 +326,8 @@ int main(void) - Copying raw bitmap into a screen - Note that bitmaps are stored in memory in little endian format. So for 32-bit color depth first byte represents the blue color, next green, red, alpha, and so on. + Note that bitmaps are stored in memory in little endian format. So for 32-bit color depth first byte represents the + blue color, next green, red, alpha, and so on. ```C static const unsigned char greenSquareBitMap32[50][8] = { @@ -325,7 +390,9 @@ int main(void) - Setting and getting a color palette - The 8-bit color depth has to be applied, so for cirrus graphics adapter please use `GRAPH_800x600x8` instead of `GRAPH_DEFMODE`. Note that in a default color palette when using the 8-bit mode, `0x01` refers to blue and for passed color map (`cmap`) it's `{ 0xff, 0x00, 0x00}` - red. + The 8-bit color depth has to be applied, so for cirrus graphics adapter please use `GRAPH_800x600x8` instead of + `GRAPH_DEFMODE`. Note that in a default color palette when using the 8-bit mode, `0x01` refers to blue and for passed + color map (`cmap`) it's `{ 0xff, 0x00, 0x00}` - red. ```C unsigned char buff[2][3]; @@ -370,18 +437,20 @@ There are few steps to follow: - Depending on the desired format: - - for 8-bit indexed color - change the file mode (image->mode->indexed) and export the file as raw binary data (file->export and choose raw image data format) + - for 8-bit indexed color - change the file mode (image->mode->indexed) and export the file as raw binary data + (file->export and choose raw image data format) - - for other color depths - export the file to C source/header format (a dialog window pops up with additional options for color conversion) + - for other color depths - export the file to C source/header format (a dialog window pops up with additional options + for color conversion) - At this point image binary data should be available (either as a an array in `.c` or `.h` file or raw hex dump) - Custom image data formatting might be required -If the image bitmap is ready, there is possibility to display it using `graph_copy()`. Please see the proper example in [How to use libgraph](#How-to-use-the-graphics-library) chapter. - +If the image bitmap is ready, there is possibility to display it using `graph_copy()`. Please see the proper example in +[How to use libgraph](#how-to-use-the-graphics-library) chapter. ## See also 1. [Phoenix-RTOS core libraries](README.md) -2. [Table of Contents](../README.md) \ No newline at end of file +2. [Table of Contents](../README.md) diff --git a/corelibs/libswdg.md b/corelibs/libswdg.md index 8a979fd6..4f3140fd 100644 --- a/corelibs/libswdg.md +++ b/corelibs/libswdg.md @@ -1,4 +1,5 @@ -Software watchdog library +# Software watchdog library + =================== Software multi-channel watchdog implementation. @@ -15,36 +16,44 @@ Software multi-channel watchdog implementation. ```c typedef void (*swdg_callback_t)(int channel); ``` -Callback function to be provided to be executed in the event of channel timeout. `channel` param conveys information which channel timeout has occured, this allows one callback to be used for all channels. -### Functions +Callback function to be provided to be executed in the event of channel timeout. `channel` param conveys information +which channel timeout has occured, this allows one callback to be used for all channels. + +### Functions ```c void swdg_reload(int no); ``` + Reloads selected watchdog channel `no` timer. This causes channel deadline to be set to value set in configuration. ```c void swdg_disable(int no); ``` -Disables selected watchdog channel `no` timer. Configuration is kept, so channel can be reenabled without additional steps. + +Disables selected watchdog channel `no` timer. Configuration is kept, so channel can be reenabled without additional +steps. ```c void swdg_enable(int no); ``` + Enables selected watchdog channel `no` timer. Channel is refreshed on enable, so no spurious timeout can occur. ```c void swdg_chanConfig(int no, swdg_callback_t callback, time_t limit); ``` -Configures selected watchdog channel `no` with desired `callback` function and `limit` (in microseconds) deadline. +Configures selected watchdog channel `no` with desired `callback` function and `limit` (in microseconds) deadline. ```c void swdg_init(size_t chanCount, int priority); ``` -Initialize library with `chanCount` channels and watchdog thread with priority `priority`. Needs to be called before any other operation. `chanCount` has to be greater than zero, `priority` has to be greater or equal to zero (highest priority) and less than 7. +Initialize library with `chanCount` channels and watchdog thread with priority `priority`. Needs to be called before any +other operation. `chanCount` has to be greater than zero, `priority` has to be greater or equal to zero +(highest priority) and less than 7. ### Notes @@ -78,4 +87,3 @@ int main() ``` Should `doAppStuff()` function hang/crash for more than 30 seconds, system will reset. - diff --git a/corelibs/libuuid.md b/corelibs/libuuid.md index 613a4ac2..fff7bdb5 100644 --- a/corelibs/libuuid.md +++ b/corelibs/libuuid.md @@ -1,8 +1,11 @@ -Universally Unique identifiers library +# Universally Unique identifiers library + =================== -Linux libuuid compliant library used to generate unique identifiers for objects that may be accessible beyond the system. -According to `RFC 4122` and `DCE 1.1` (Distributed Computing Environment) currently supported UUID format is variant 1, version 4 (randomly/pseudo-randomly generated). +Linux libuuid compliant library used to generate unique identifiers for objects that may be accessible +beyond the system. +According to `RFC 4122` and `DCE 1.1` (Distributed Computing Environment) currently supported UUID format is variant 1, +version 4 (randomly/pseudo-randomly generated). ## Contents @@ -12,55 +15,59 @@ According to `RFC 4122` and `DCE 1.1` (Distributed Computing Environment) curren ## General information -Linux libuuid compliant library used to generate unique identifiers for objects that may be accessible beyond the system. -According to `RFC 4122` and `DCE 1.1` (Distributed Computing Environment) currently supported UUID format is variant 1, version 4 (randomly/pseudo-randomly generated). +Linux libuuid compliant library used to generate unique identifiers for objects that may be accessible beyond the +system. According to `RFC 4122` and `DCE 1.1` (Distributed Computing Environment) currently supported UUID format is +variant 1, version 4 (randomly/pseudo-randomly generated). ## Using libuuid -To use functions provided by `libuuid` please add the library to the `LIBS` variable in `Makefile` and include the required header file. Below is a simple example, which could be placed in `_user` directory: +To use functions provided by `libuuid` please add the library to the `LIBS` variable in `Makefile` and include the +required header file. Below is a simple example, which could be placed in `_user` directory: - - Makefile - linking with `libbuid` library. - ``` - NAME := uuidgen - LOCAL_SRCS := main.c - LIBS := libuuid +- Makefile - linking with `libbuid` library. - include $(binary.mk) - ``` +```c +NAME := uuidgen +LOCAL_SRCS := main.c +LIBS := libuuid +include $(binary.mk) +``` - - Source code: +- Source code: - ```C - #include - #include +```C +#include +#include - int main(void) - { - uuid_t uu; - char uuStr[37]; +int main(void) +{ + uuid_t uu; + char uuStr[37]; - uuid_generate(uu); - uuid_unparse(uu, uuStr); + uuid_generate(uu); + uuid_unparse(uu, uuStr); - printf("Generated identifier: %s\n", uuStr); + printf("Generated identifier: %s\n", uuStr); - return 0; - } - ``` + return 0; +} +``` - - Sample result: +- Sample result: - ``` + ```bash (psh)% /usr/bin/uuidgen Generated identifier: 81fb691c-fb2d-4546-54ef-231edff56a7f (psh)% ``` - ## Running tests +## Running tests - Phoenix-RTOS UUID Library provides the basic set of unit tests, which is available in [phoenix-rtos-tests](https://github.com/phoenix-rtos/phoenix-rtos-tests/tree/master). It can be run for different platforms, here is the example for the `ia32-generic-qemu` target: + Phoenix-RTOS UUID Library provides the basic set of unit tests, which is available in + [phoenix-rtos-tests](https://github.com/phoenix-rtos/phoenix-rtos-tests/tree/master). + It can be run for different platforms, here is the example for the `ia32-generic-qemu` target: - ``` + ```bash python3 phoenix-rtos-tests/runner.py -T ia32-generic-qemu -t phoenix-rtos-tests/libuuid/ ``` diff --git a/devices/README.md b/devices/README.md index 4afe0cb1..483377bf 100644 --- a/devices/README.md +++ b/devices/README.md @@ -1,20 +1,30 @@ # Device drivers -Phoenix-RTOS implements device drivers as device servers running on the user level. The communication with drivers is done via message passing using a well-defined interface for exchanging the data between programs and drivers. +Phoenix-RTOS implements device drivers as device servers running on the user level. The communication with drivers is +done via message passing using a well-defined interface for exchanging data between programs and drivers. -To control the device, two mechanisms are necessary and should be provided by the operating system kernel: access to device hardware registers and method of handling interrupts triggered by it. The architecture of these Phoenix-RTOS mechanisms has been presented in the chapter’s subsections. +To control the device, two mechanisms are necessary and should be provided by the operating system kernel: access to +device hardware registers and method of handling interrupts triggered by it. The architecture of these Phoenix-RTOS +mechanisms has been presented in the chapter’s subsections. ## Generic driver architecture -Each typical driver in Phoenix-RTOS consists of the main function which typically parses command line parameters, creates a driver communication port, registers it in the operating system, namespace, initializes a device, and starts processing of the incoming messages. +Each typical driver in Phoenix-RTOS consists of the main function which typically parses command line parameters, +creates a driver communication port, registers it in the operating system, namespace, initializes a device, and starts processing the incoming messages. -The message is fetched from the queue using the `msgRecv` syscall. This syscall blocks thread until a message is available, so the device server should implement a thread pool to process the incoming request. The client is blocked until the server responds to the message using the `msgRespond` syscall. There are two approaches for message processing - concurrent processing and iterative processing. +The message is fetched from the queue using the `msgRecv` syscall. This syscall blocks the thread until a message is +available, so the device server should implement a thread pool to process the incoming request. The client is blocked +until the server responds to the message using the `msgRespond` syscall. There are two approaches to message +processing - concurrent processing and iterative processing. + +## Concurrent processing -## Concurrent processing Messages which can be processed instantly may be serviced by one of the main loop threads. ## Iterative processing -If delays are expected (e.g. waiting for I/O) message should be inserted into the server's internal queue and processed by the internal thread. + +If delays are expected (e.g. waiting for I/O) message should be inserted into the server's internal queue and processed +by the internal thread. ## Source code diff --git a/devices/hwaccess.md b/devices/hwaccess.md index 94dcb036..06c5f40c 100644 --- a/devices/hwaccess.md +++ b/devices/hwaccess.md @@ -1,6 +1,8 @@ # Accessing hardware -This section describes advised methods of accessing hardware registers, in other words, instruction set architecture (`ISA`). Leaving aside architecture-dependent methodology, one should access hardware registers by using base address (either from data or I/O address space) and particular register offset: +This section describes advised methods of accessing hardware registers, in other words, instruction set architecture +(`ISA`). Leaving aside architecture-dependent methodology, one should access hardware registers by using base address +(either from data or I/O address space) and particular register offset: ````C /* Device registers */ @@ -21,9 +23,12 @@ This section describes advised methods of accessing hardware registers, in other ## ISA with in/out instructions -Some architectures support in/out instructions and hardware registers are not mapped in the data memory space (e.g. x86). In those architectures, it is necessary to use either compiler buildings or an inline assembler. The second option is preferred, as it increases the code portability to another compiler. +Some architectures support in/out instructions and hardware registers are not mapped in the data memory space +(e.g. x86). In those architectures, it is necessary to use either compiler buildings or an inline assembler. The second +option is preferred, as it increases the code portability to another compiler. -For IA32 `ISA` there are a set of functions defined in which should be used to access hardware registers: +For IA32 `ISA` there are a set of functions defined in which should be used to access hardware +registers: * `u8 inb(void *addr)` - read byte (8 bits) from register located on address addr * `void outb(void *addr, u8 b)` - write byte (8 bits) b to register located on address addr @@ -38,7 +43,10 @@ The following sections describe both the `MMU` and non-`MMU` approaches. ### ISA with MMU -On architectures, with `MMU` (memory management unit) driver developer doesn't have direct access to the physical memory. To be able to manipulate registers located in the main address space one has to gain access to memory located under a particular physical address by mapping this address to the virtual address space. It can be achieved by using the `mmap` syscall: +On architectures, with `MMU` (memory management unit) driver developer doesn't have direct access to the physical +memory. To be able to manipulate registers located in the main address space one has to gain access to memory located +under a particular physical address by mapping this address to the virtual address space. It can be achieved by using +the `mmap` syscall: ```c #include @@ -46,16 +54,19 @@ On architectures, with `MMU` (memory management unit) driver developer doesn't h void *vaddr = mmap(NULL, SIZE_PAGE, PROT_READ | PROT_WRITE, MAP_UNCACHED, OID_PHYSMEM, paddr); ``` -The above example maps one page (typically 4 KiB) of physical memory (as indicated by `OID_PHYSMEM`) starting from the `paddr` address with read (`PROT_READ`) and write (`PROT_WRITE`) permissions at the lowest possible virtual address (as indicated by the first argument). The `vaddr` address returned from `mmap` should be checked to make sure that it does not contain the `MAP_FAILED` value, which would indicate that `mmap` failed to perform the desired mapping. - +The above example maps one page (typically 4 KiB) of physical memory (as indicated by `OID_PHYSMEM`) starting from the +`paddr` address with read (`PROT_READ`) and write (`PROT_WRITE`) permissions at the lowest possible virtual address +(as indicated by the first argument). The `vaddr` address returned from `mmap` should be checked to make sure that it +does not contain the `MAP_FAILED` value, which would indicate that `mmap` failed to perform the desired mapping. ### ISA without MMU -On architectures without `MMU` access to the hardware registers does not require prior memory mapping. Registers can be accessed by directly setting a volatile pointer to the desired physical base address. +On architectures without `MMU` access to the hardware registers does not require prior memory mapping. Registers can be +accessed by directly setting a volatile pointer to the desired physical base address. ## See also 1. [Device drivers](README.md) 2. [Handling interrupts](interrupts.md) 3. [Message interface](interface.md) -4. [Table of Contents](../README.md) \ No newline at end of file +4. [Table of Contents](../README.md) diff --git a/devices/interface.md b/devices/interface.md index 450a1711..49bd4d62 100644 --- a/devices/interface.md +++ b/devices/interface.md @@ -1,18 +1,27 @@ # Interface -The device driver server in a Phoenix-RTOS ecosystem communicates with other processes using a message interface. In the typical case, the driver server has one port on which all requests are placed by clients. This port can be either registered within the native namespace or special file(s) can be created within the filesystem. +The device driver server in a Phoenix-RTOS ecosystem communicates with other processes using a message interface. In +the typical case, the driver server has one port on which all requests are placed by clients. This port can be either +registered within the native namespace or special file(s) can be created within the filesystem. ## Port creation -Port, the endpoint of the message communication, can be created using the `portCreate()` function. If zero is returned, then creation succeeded and the variable port now contains a unique port number assigned by the kernel. +Port, the endpoint of the message communication, can be created using the `portCreate()` function. If zero is returned, +then creation succeeded and the variable port now contains a unique port number assigned by the kernel. ## Registering within a namespace -The freshly created port can not be seen by other processes. To allow clients to find out the server's port number, it has to be registered within some namespace. If the device driver server wants to register more than one "file" it does not have to create separate ports for them. The driver needs to assign each "file" id from its private pool. +The freshly created port can not be seen by other processes. To allow clients to find out the server's port number, it +has to be registered within some namespace. If the device driver server wants to register more than one "file" it does +not have to create separate ports for them. The driver needs to assign each "file" id from its private pool. -Assume we want to create an SPI server that manages 2 instances of the device - spi0 and spi1. We can manage both using only one port by registering the same port as `/dev/spi0` with id = 1 and `/dev/spi1` with id = 2. Every message driver receives contains information to which `oid` (object id) it has been sent. This enables the driver to recognize to which special file message has been addressed to. +Assume we want to create an SPI server that manages 2 instances of the device - spi0 and spi1. We can manage both using +only one port by registering the same port as `/dev/spi0` with id = 1 and `/dev/spi1` with id = 2. Every message driver +receives contains information to which `oid` (object id) it has been sent. This enables the driver to recognize to +which special file message has been addressed to. -If the system does not have a root filesystem, a port can be registered within Phoenix native filesystem by using syscall +If the system does not have a root filesystem, a port can be registered within Phoenix native filesystem by using +syscall ```c int portRegister(u32 port, const char *name, oid_t *oid); @@ -26,7 +35,8 @@ where Syscall returns 0 on success. -On systems that contain filesystem special file can be created, which will point to the server's `oid`. In the first place we need `oid` of directory which will hold our special file: +On systems that contain filesystem special file can be created, which will point to the server's `oid`. In the first +place we need `oid` of directory which will hold our special file: ````C #include @@ -57,7 +67,8 @@ Then we can create a new special file and register: ## Message types -There are several standard types of messages, although device driver servers need to implement an only subset of them. With every message type there are 3 common fields: +There are several standard types of messages, although device driver servers need to implement an only subset of them. +With every message type there are 3 common fields: - _`type`_ - type of message, - _`pid`_ - process id of sender, @@ -73,7 +84,7 @@ This message type informs the server, there is a process trying to open one of i The server can respond to this message via the o.io.err field: - _`EOK`_ if success, -- _`ENOENT`_ if no such file exist, +- _`ENOENT`_ if no such file exist, - _`EPERM`_ if client has not sufficient privilege. ### mtClose @@ -116,11 +127,13 @@ Number of written bytes or error is returned via o.io.err. ### mtDevCtl -This message type allows defining an entirely custom structure for input and output to/from a device server. This structure should be serialized/deserialized to/from message i.raw/o.raw fields. Additional data can be passed in i.data and o.data fields. +This message type allows defining an entirely custom structure for input and output to/from a device server. This +structure should be serialized/deserialized to/from message i.raw/o.raw fields. Additional data can be passed in i.data +and o.data fields. ## See also 1. [Device drivers](README.md) 2. [Access to device hardware registers](hwaccess.md) 3. [Handling interrupts](interrupts.md) -4. [Table of Contents](../README.md) \ No newline at end of file +4. [Table of Contents](../README.md) diff --git a/devices/interrupts.md b/devices/interrupts.md index 971d02d1..004e569e 100644 --- a/devices/interrupts.md +++ b/devices/interrupts.md @@ -1,10 +1,12 @@ # Interrupts -It is often necessary to handle hardware interrupts when creating a device driver. To enable the userspace server to do so, Phoenix-RTOS provides a special callback mechanism. Driver registers interrupt handler via syscall: +It is often necessary to handle hardware interrupts when creating a device driver. To enable the userspace server to do +so, Phoenix-RTOS provides a special callback mechanism. Driver registers interrupt handler via syscall: ````C int interrupt(unsigned int n, int (*f)(unsigned int, void *), void *arg, unsigned int cond, unsigned int *handle); ```` + where: - _`n`_ is platform dependent interrupt number, @@ -13,11 +15,15 @@ where: - _`cond`_ is handle to conditional, - _`handle`_ points to variable which will hold new interrupt handle. -Interrupt syscall registers callback function to be executed when the interrupt number `n` occurs and enables (if not enabled already) this interrupt in the controller. +Interrupt syscall registers callback function to be executed when the interrupt number `n` occurs and enables (if not +enabled already) this interrupt in the controller. -The callback function is invoked directly from the kernel space with interrupts globally disabled. It allows the handler to be able to prevent the same interrupt to be executed again (e.g. when an interrupt is caused by the signal level, not edge). +The callback function is invoked directly from the kernel space with interrupts globally disabled. It allows the handler +to be able to prevent the same interrupt to be executed again (e.g. when an interrupt is caused by the signal level, not +edge). -If handler returns value >= 0 then kernel performs `condSignal()` on a conditional passed when registering interrupt. If this feature is not needed, one can pass 0 as _`cond`_. +If handler returns value >= 0 then kernel performs `condSignal()` on a conditional passed when registering interrupt. If +this feature is not needed, one can pass 0 as _`cond`_. ## See also diff --git a/devices/libsdio/README.md b/devices/libsdio/README.md index 3ea4684b..dc1466b8 100644 --- a/devices/libsdio/README.md +++ b/devices/libsdio/README.md @@ -2,7 +2,8 @@ ## General description -libsdio is a static, precompiled library containing a generic SDIO driver which directly controls the platform hardware. This driver defines an API providing basic interface control functionality. +libsdio is a static, precompiled library containing a generic SDIO driver which directly controls the platform hardware. +This driver defines an API providing basic interface control functionality. ## Platform support @@ -76,7 +77,8 @@ typedef void (*sdio_event_handler_t)(void *arg); Following sections describe the API in detail, including the behaviour of certain functions. -> **NOTE:** Codes returned by API calls are defined in `` header, which provides more detailed information about specific values. +> **NOTE:** Codes returned by API calls are defined in `` header, which provides more detailed information +about specific values. --- @@ -89,7 +91,8 @@ typedef enum { **Description:** -This enumeration type is meant as parameter for `sdio_transferDirect` and `sdio_transferBulk` functions to indicate the direction of a given data transfer. +This enumeration type is meant as parameter for `sdio_transferDirect` and `sdio_transferBulk` functions to indicate the +direction of a given data transfer. --- @@ -99,7 +102,9 @@ typedef void (*sdio_event_handler_t)(void *arg); **Description:** -This type describes a callback for an interrupt handler. Handlers of interrupts events are assigned to a specific event, and every event can only have a single handler. Handler argument is provided during handler registration using `sdio_eventRegister`, and will remain unchanged until the handler registration is modified via the same function. +This type describes a callback for an interrupt handler. Handlers of interrupts events are assigned to a specific event, +and every event can only have a single handler. Handler argument is provided during handler registration using +`sdio_eventRegister`, and will remain unchanged until the handler registration is modified via the same function. --- @@ -109,9 +114,12 @@ int sdio_init(void); **Description:** -This function initializes the SDIO inteface hardware and tries to detect and select the connected device. It has to be called before any other API function. Should no device be present or it does not respond to SDIO initialization sequence, this function shall return an error code and free resources it acquired. +This function initializes the SDIO inteface hardware and tries to detect and select the connected device. It has to be +called before any other API function. Should no device be present or it does not respond to SDIO initialization +sequence, this function shall return an error code and free resources it acquired. -> **NOTE:** Calling this function more than once after successful completion will have no effect. In order to reinitialize the interface, `sdio_free` should be called between concurrent `sdio_init` calls instead. +> **NOTE:** Calling this function more than once after successful completion will have no effect. In order to +reinitialize the interface, `sdio_free` should be called between concurrent `sdio_init` calls instead. **Parameters:** @@ -133,9 +141,11 @@ void sdio_free(void); **Description:** -This function frees the SDIO bus, reset the host controller, deregister and disable all previously registered event handlers. Calling this function before `sdio_init` has no effect. +This function frees the SDIO bus, reset the host controller, deregister and disable all previously registered event +handlers. Calling this function before `sdio_init` has no effect. -> **NOTE:** Due to its current implementation, calling this function does not allow for creation of new library instances in other running processes. +> **NOTE:** Due to its current implementation, calling this function does not allow for creation of new library +instances in other running processes. **Parameters:** @@ -150,9 +160,11 @@ This function frees the SDIO bus, reset the host controller, deregister and disa ```c int sdio_config(uint32_t freq, uint16_t blocksz); ``` + **Description:** -This function provides a configuration interface for the SDIO bus controller. This function can be called at any time after `sdio_init`. +This function provides a configuration interface for the SDIO bus controller. This function can be called at any time +after `sdio_init`. **Parameters:** @@ -178,7 +190,9 @@ int sdio_transferDirect(sdio_dir_t dir, uint32_t address, uint8_t area, uint8_t **Description:** -This function initiates a direct, single 8-bit register read/write opetation. When `dir` is specified as `sdio_write` the byte inside the `data` buffer is written to the device, otherwise if `dir` equals `sdio_read` , the buffer is set to the value read from the device. +This function initiates a direct, single 8-bit register read/write opetation. When `dir` is specified as `sdio_write` +the byte inside the `data` buffer is written to the device, otherwise if `dir` equals `sdio_read` , the buffer is set +to the value read from the device. > **NOTE:** This function is a blocking call which only returns upon successful transfer completion or failure. @@ -208,7 +222,8 @@ int sdio_transferBulk(sdio_dir_t dir, int blockMode, uint32_t address, uint8_t a **Description:** -This function initiates an indirect, multi-byte transfer of up to 2048 bytes at once. As is the case with `sdio_transferDirect`, this call can service bi-directional transfers. +This function initiates an indirect, multi-byte transfer of up to 2048 bytes at once. As is the case with +`sdio_transferDirect`, this call can service bi-directional transfers. > **NOTE:** This function is a blocking call which only returns upon successful transfer completion or failure. @@ -223,9 +238,10 @@ This function initiates an indirect, multi-byte transfer of up to 2048 bytes at | [in/out] `uint8_t *data` | bi-directional multi byte buffer | *any valid pointer* | | [in] `size_t len` | total transfer size in bytes | <=2048 | -> **NOTE:** `len` parameter has to be a multiple of `blocksz` when performing a block transfer with `blockMode` set to *true*. - -> **NOTE:** `address` parameter specifies only the base address of the transfer. If `blockMode` is set to *true*, then the address is automatically incremented by the device with every completed block. +> **NOTE:** `len` parameter has to be a multiple of `blocksz` when performing a block transfer with `blockMode` set to +*true*. +> **NOTE:** `address` parameter specifies only the base address of the transfer. If `blockMode` is set to *true*, then +the address is automatically incremented by the device with every completed block. **Returns:** @@ -243,7 +259,10 @@ This function initiates an indirect, multi-byte transfer of up to 2048 bytes at int sdio_eventRegister(uint8_t event, sdio_event_handler_t handler, void *arg); ``` -This function registers an event handler to be called when a given interrupt event occurs. An interrupt event will not be signalled until its detection is enabled by `sdio_eventEnable`. Please note that only one handler can be registered per event - calling this function multiple times for the same event will result in the previous handler being overwritten. In order to deregister the handler one can pass `NULL` as the `handler` parameter. +This function registers an event handler to be called when a given interrupt event occurs. An interrupt event will not +be signalled until its detection is enabled by `sdio_eventEnable`. Please note that only one handler can be registered +per event - calling this function multiple times for the same event will result in the previous handler being +overwritten. In order to deregister the handler one can pass `NULL` as the `handler` parameter. **Parameters:** @@ -270,7 +289,8 @@ This function registers an event handler to be called when a given interrupt eve int sdio_eventEnable(uint8_t event, int enabled); ``` -This function can enable or disable interrupt event signalling of the SD host controller. If a handler is registered via `sdio_eventRegister` for a given enabled event, it will be called when an interrupt fires. +This function can enable or disable interrupt event signalling of the SD host controller. If a handler is registered via +`sdio_eventRegister` for a given enabled event, it will be called when an interrupt fires. **Parameters:** @@ -287,4 +307,3 @@ This function can enable or disable interrupt event signalling of the SD host co |---------|-------------------------------| | EOK | success | | -EINVAL | provided `event` is not valid | - diff --git a/filesystems/README.md b/filesystems/README.md index 7fe9344c..0d18063b 100644 --- a/filesystems/README.md +++ b/filesystems/README.md @@ -1,6 +1,7 @@ # Filesystems -Filesystems in Phoenix-RTOS are supported using file servers. File servers are specialized servers implementing specific communication protocols. During the start, each file server registers its port in the filesystem space. +Filesystems in Phoenix-RTOS are supported using file servers. File servers are specialized servers implementing specific +communication protocols. During the start, each file server registers its port in the filesystem space. ## Source code @@ -14,4 +15,4 @@ The documentation of a particular server is provided within its source code repo ## See also -1. [Table of Contents](../README.md) \ No newline at end of file +1. [Table of Contents](../README.md) diff --git a/hostutils/README.md b/hostutils/README.md index 5a8371ab..f87a2121 100644 --- a/hostutils/README.md +++ b/hostutils/README.md @@ -1,8 +1,11 @@ # Host utilities -Phoenix-RTOS host utilities are functional tools used by the host computer in which, for example, we flash a system image to a device. +Phoenix-RTOS host utilities are functional tools used by the host computer in which, for example, we flash a system +image to a device. -The source code of host utilities is placed in the [phoenix-rtos-hostutils](https://github.com/phoenix-rtos/phoenix-rtos-utils) Github repository. If you don't know what are `phoenix-rtos` repositories you can check the [reference project repository](../building/project.md) chapter. +The source code of host utilities is placed in the +[phoenix-rtos-hostutils](https://github.com/phoenix-rtos/phoenix-rtos-utils) Github repository. If you don't know what +are `phoenix-rtos` repositories you can check the [reference project repository](../building/project.md) chapter. ## Components diff --git a/hostutils/psdisk.md b/hostutils/psdisk.md index 07c9e278..212df355 100644 --- a/hostutils/psdisk.md +++ b/hostutils/psdisk.md @@ -1,24 +1,31 @@ # psdisk `psdisk` is a tool responsible for creating a partition table where sources are placed under the following link: -https://github.com/phoenix-rtos/phoenix-rtos-filesystems/tree/master/ptable - + ## Preliminary information -In Phoenix-RTOS this memory scheme was introduced in a flash server (https://github.com/phoenix-rtos/phoenix-rtos-devices/tree/master/storage/imxrt-flash) for armv7m7-imxrt106x-evk (NXP i.MX RT106x). It can be distinguished by the following partition types: + +In Phoenix-RTOS this memory scheme was introduced in a flash server +() for armv7m7-imxrt106x-evk +(NXP i.MX RT106x). It can be distinguished by the following partition types: + - raw - partition provides direct access only to a selected part of memory, -- MeterFS - partition contains access to a file system created for meter profile data storage (https://github.com/phoenix-rtos/phoenix-rtos-filesystems/tree/master/meterfs). +- MeterFS - partition contains access to a file system created for meter profile data storage +(). -In the mentioned flash server, a partition table has to be located in the last sector of the flash memory. Due to this fact, the user can generate an image that covers the whole memory with a partition table that is located in the last sector or only an image containing a partition table. +In the mentioned flash server, a partition table has to be located in the last sector of the flash memory. Due to this +fact, the user can generate an image that covers the whole memory with a partition table that is located in the last +sector or only an image containing a partition table. To generate an image with a flash memory size, the user should use `-o` option. ## Examples -The following example generates a partition table for MICRON MT25QL01GBBB. The size of the memory and sector bases on data from https://pl.mouser.com/datasheet/2/671/MT25Q_QLKT_L_01G_BBB_0-1283539.pdf +The following example generates a partition table for MICRON MT25QL01GBBB. The size of the memory and sector bases on +data from ### Creating partition table -``` +```bash ./psdisk partitionTable.img -m 0x8000000,0x1000 -p raw1,0,0x10000,0x51 -p raw2,0x20000,0x1000,0x51 -p meterfs,0x50000,0x50000,0x75 ``` @@ -26,7 +33,7 @@ The following example generates a partition table for MICRON MT25QL01GBBB. The s ### Updating partition table -``` +```bash ./psdisk partitionTable.img -m 0x8000000,0x1000 -p raw4,0x100000,0x10000,0x51 ``` diff --git a/kernel/README.md b/kernel/README.md index 00aa4b1c..778bb361 100644 --- a/kernel/README.md +++ b/kernel/README.md @@ -1,6 +1,7 @@ # Kernel -Phoenix-RTOS is based on the written from scratch dedicated microkernel and consists of about 20K lines of code (LoC). Microkernel is responsible for: +Phoenix-RTOS is based on the written from scratch dedicated microkernel and consists of about 20K lines of code (LoC). +Microkernel is responsible for: * memory management * thread and process management @@ -9,11 +10,11 @@ Phoenix-RTOS is based on the written from scratch dedicated microkernel and cons Kernel is divided into five subsystems. -- hal - hardware abstraction layer -- lib - common routines -- vm - virtual memory management -- proc - process and thread management -- test - internal tests for kernel subsystems +* hal - hardware abstraction layer +* lib - common routines +* vm - virtual memory management +* proc - process and thread management +* test - internal tests for kernel subsystems ## Kernel source code diff --git a/kernel/hal/README.md b/kernel/hal/README.md index cdb30987..ccbf7af5 100644 --- a/kernel/hal/README.md +++ b/kernel/hal/README.md @@ -1,8 +1,10 @@ # HAL subsystem -HAL (Hardware Abstraction Layer) is the kernel hardware dependent subsystem used for adopting it to the particular hardware platform. It provides the unified interface for other kernel subsystems. It is the only subsystem required to be changed when kernel is ported to the new hardware architecture. +HAL (Hardware Abstraction Layer) is the kernel hardware-dependent subsystem used for adapting it to the particular +hardware platform. It provides a unified interface for other kernel subsystems. It is the only subsystem required to be +changed when the kernel is ported to the new hardware architecture. -HAL implements following functionalities: +HAL implements the following functionalities: * kernel initialization, * basic type definitions, @@ -15,51 +17,88 @@ HAL implements following functionalities: * timer support, * context switching. -Theses functionalities are briefly discussed in this chapter. +These functionalities are briefly discussed in this chapter. ## Kernel initialization -After loading kernel into the memory HAL initializaiton is executed. Typically this code is located in `_init.S` file and it is written in assembly language. Initialization function sets specific processor registers (e.g. control registers, segment registers, MPU/MMU registers), prepares kernel address space and passes control to `main()` function. +After loading kernel into the memory HAL initialization is executed. Typically this code is located in `_init.S` file +and it is written in assembly language. The initialization function sets specific processor registers (e.g. control +registers, segment registers, MPU/MMU registers), prepares kernel address space, and passes control to `main()` +function. ## Basic types -Phoenix-RTOS 3 microkernel uses basic C types and few kernel-specific types defined in HAL. +Phoenix-RTOS 3 microkernel uses basic C types and a few kernel-specific types defined in HAL. ## Syspage -The low-level kernel initialization is based on `syspage_t` structure. This structure is prepared during the bootstrap process by operating system loader. It is stored on physical memory at address chosen by the loader. The `syspage_t` definition depends on the hardware architecture and provides information like physical memory maps, interrupts tables, preloaded user application etc. It should be treated as the main structure used for operating system configuration. +The low-level kernel initialization is based on `syspage_t` structure. This structure is prepared during the bootstrap +process by the operating system loader. It is stored in physical memory at the address chosen by the loader. +The `syspage_t`definition depends on the hardware architecture and provides information like physical memory maps, +interrupts tables, +preloaded user application, etc. It should be treated as the main structure used for operating system configuration. ## Spinlocks -Spinlocks are basic primitives used for active synchronizaton of parallely executed instruction streams. They are implemented using special processor instruction (called test-and-set) used for atomic exchange of the value stored in the processor register with the value stored in the memory. From programmer point of view spinlock behaves like binary semaphore but the main difference is the active waiting. If spinlock is locked on the one processor and code running on other processor tries to lock it again the execution of the the locking operation fails and is repeated until it will be succeeded. To check the spinlock state in the memory the test-and-set instruction is used. In one operation the value indicating the lock is stored in the memory and previous value is retrieved into the register. If the value from memory indicates the lock the operation is repeated. +Spinlocks are basic primitives used for active synchronization of parallelly executed instruction streams. They are +implemented using special processor instruction (called test-and-set) used for the atomic exchange of the value stored +in the processor register with the value stored in the memory. From a programmer's point of view, spinlock behaves like +a binary semaphore but the main difference is the active waiting. If spinlock is locked on one processor and code +running on another processor tries to lock it again the execution of the locking operation fails and is repeated until +it will be succeeded. To check the spinlock state in the memory the test-and-set instruction is used. In one operation +the value indicating the lock is stored in the memory and the previous value is retrieved into the register. If the +value from memory indicates the lock the operation is repeated. ## Console -Console is used for presenting kernel messages until first process and terminal drivers are started. It is typically based on UART but it can use other display devices (on IA32 there is console based on VGA graphics adapter and keyboard). Console should work from the early boot stage and therefore it should be kept as simple as possible and should use no interrupts and other HAL mechanisms. +The console is used for presenting kernel messages until the first process and terminal drivers are started. It is +typically based on UART but it can use other display devices (on IA32 there is a console based on a VGA graphics adapter +and keyboard). The console should work from the early boot stage and therefore it should be kept as simple as possible +and should use no interrupts and other HAL mechanisms. ## String functions -HAL provides set of string functions used for data copying and string manipulation. They correspond to ANSI C functions provided by compiler but compiler`s functions are not intentionally used. The intention was to implement these functions from scratch to control the details of implementation and external references. +HAL provides a set of string functions used for data copying and string manipulation. They correspond to ANSI +C functions provided by the compiler but the compiler`s functions are not intentionally used. The +intention was to implement these functions from scratch to control the details of implementation and external +references. ## MMU or MPU management -HAL is responsible for the lowest part of the memory managements subsystem - `pmap`. This layer provides functions used for controlling the MMU or MPU. When no memory control units are available these functions should be empty. +HAL is responsible for the lowest part of the memory management subsystem - `pmap`. This layer provides functions used +for controlling the MMU or MPU. When no memory control units are available these functions should be empty. ## Exception and interrupts -HAL plays important role in exceptions and interrupts handling. It handles interrupts controller, implements the interrupt and exception stubs and interrupt and exception service routines invocations. Interrupts routines can reside in the kernel address space or in process address space. When interrupt handler is located in process address space the process `pmap` object is passed during the interrupt handler installation and before servicing interrupt the address space is switched. +HAL plays an important role in exception and interrupts handling. It handles the interrupts controller, implements the +interrupt and exception stubs, and interrupt and exception service routines invocations. Interrupts routines can reside +in the kernel address space or in the process address space. When the interrupt handler is located in the +process address space the process `pmap` object is passed during the interrupt handler installation and +before servicing interrupt the address +space is switched. ## Timer -Timer is the fundamental device for operating system kernel. It is used for preemptive scheduling and time management. HAL is responsible for implementation of two timers - scheduler timer and high precision timer. On some architectures they can be based on one hardware device but commonly the are based on two separated devices. The interface provided for upper layer unifies these devices and hides implementation details. +Timer is the fundamental device for the operating system kernel. It is used for preemptive scheduling and time +management. HAL is responsible for the implementation of two timers - a scheduler timer and high precision timer. +On some architectures, they can be based on one hardware device but commonly the are based on two separate devices. +The interface provided for the upper layer unifies these devices and hides implementation details. -HAL implements one functions for operating on timers and defines two interrupt numbers respectively for timer used for scheduling and for timer used for time management. +HAL implements one function for operating on timers and defines two interrupt numbers respectively for timers used for +scheduling and for timers used for time management. ## Context switching -Context switching is the most exciting part of HAL. In Phoenix-RTOS is assumed the context switching is based on thread kernel stack switching. When interrupt is raised interrupt stub function (implemented in HAL) is called and stores the current thread context (registers and other data) on the top of the kernel stack before it passes control to the interrupt dispatching function and finally to the registered interrupt service routine. After interrupt dispatching and service routine execution control is returned to the interrupt stub which restores the saved context. +Context switching is the most exciting part of HAL. In Phoenix-RTOS is assumed the context switching is based on thread +kernel stack switching. When interrupt is raised interrupt stub function (implemented in HAL) is called and stores the +current thread context (registers and other data) on the top of the kernel stack before it passes control to the +interrupt dispatching function and finally to the registered interrupt service routine. After interrupt dispatching and +service routine execution control is returned to the interrupt stub which restores the saved context. -The last register stored on the kernel stack is the current stack pointer and it can be changed by interrupt service routine to another one. This happens if interrupt routine executes the scheduler and context switch appears. In such case the control is passed to the new thread. If the next thread is executing in the separate address space (belongs to other process) before switching to the new thread scheduler switches the address space using `pmap_switch()` function. +The last register stored on the kernel stack is the current stack pointer and it can be changed by interrupt service +routine to another one. This happens if interrupt routine executes the scheduler and context switch appears. In such +case the control is passed to the new thread. If the next thread is executing in the separate address space (belongs to +other process) before switching to the new thread scheduler switches the address space using `pmap_switch()` function. Context is described using `cpu_contex_t` structure. diff --git a/kernel/hal/armv7a.md b/kernel/hal/armv7a.md index b4751e9c..5aec5002 100644 --- a/kernel/hal/armv7a.md +++ b/kernel/hal/armv7a.md @@ -1,6 +1,7 @@ # HAL for ARMv7 Cortex-A based targets -ARMv7m HAL layer supports microcontrollers based on ARM Cortex-Ax architecture. Source code is located in `hal/armv7a` directory. +ARMv7m HAL layer supports microcontrollers based on ARM Cortex-Ax architecture. Source code is located in `hal/armv7a` +directory. ## Initialization diff --git a/kernel/hal/armv7m.md b/kernel/hal/armv7m.md index 469b3e38..36ee7457 100644 --- a/kernel/hal/armv7m.md +++ b/kernel/hal/armv7m.md @@ -1,6 +1,7 @@ # HAL for ARMv7 Cortex-M based targets -ARMv7m HAL layer supports microcontrollers based on ARM Cortex-Mx architecture. Source code is located in `hal/armv7m` directory. +ARMv7m HAL layer supports microcontrollers based on ARM Cortex-Mx architecture. Source code is located in `hal/armv7m` +directory. ## Initialization @@ -9,7 +10,8 @@ ARMv7m HAL layer supports microcontrollers based on ARM Cortex-Mx architecture. .word _end + 1024 + 256 .word _start -First two words on memory address 0x00000000 define initial stack and code entrypoint. Stack is set at the end of BSS + size of the stack. +First two words on memory address 0x00000000 define initial stack and code entrypoint. Stack is set at the end of +BSS + size of the stack. > .word _exceptions_dispatch /* NMI */ diff --git a/kernel/hal/ia32.md b/kernel/hal/ia32.md index d79ad658..e7356905 100644 --- a/kernel/hal/ia32.md +++ b/kernel/hal/ia32.md @@ -4,13 +4,19 @@ HAL for IA32 architecture is located in `hal/ia32`. This chapter presents some i ## Initialization -To prevent mixing of 16-bit code with 32-bit code and to load programs into the memory the loader is used. Loader is executed when computer starts and it is able to load programs (stored in ELF) from a filesystem supported by boot firmware (e.g. UEFI) or from specified disk device (when BIOS is used). +To prevent mixing of 16-bit code with 32-bit code and to load programs into the memory the loader is used. Loader is +executed when computer starts and it is able to load programs (stored in ELF) from a filesystem supported by boot +firmware (e.g. UEFI) or from specified disk device (when BIOS is used). -All memory locations of kernel, programs, page directories, page tables, descriptor tables are stored in `syspage_t` structure passed to the kernel. When loader works in the real model and kernel and programs are loaded into memory loader prepares GDT and IDT tables and switches CPU into the protected mode. Control is passed to kernel initialization code located in `_init.S` file. When loader is executed in the protected mode kernel prepares new GDT and IDT tables, reloads GDTR and IDTR registers and after this initialization code is executed. +All memory locations of kernel, programs, page directories, page tables, descriptor tables are stored in `syspage_t` +structure passed to the kernel. When loader works in the real model and kernel and programs are loaded into memory +loader prepares GDT and IDT tables and switches CPU into the protected mode. Control is passed to kernel initialization +code located in `_init.S` file. When loader is executed in the protected mode kernel prepares new GDT and IDT tables, +reloads GDTR and IDTR registers and after this initialization code is executed. -The brief analysis of initialization code is presented below. +The brief analysis of initialization code is presented below. -``` +```asm movw $SEL_KDATA, %ax movw %ax, %ss movw %ax, %ds @@ -19,17 +25,20 @@ The brief analysis of initialization code is presented below. movw %ax, %gs ``` -First instructions loads kernel data selector `SEL_KDATA` into segment registers. Kernel data selector points to descriptor in GDT defining the segment from address `0x00000000` to `0xffffffff` on privilege level 0 with RW attributes. +First instructions loads kernel data selector `SEL_KDATA` into segment registers. Kernel data selector points to +descriptor in GDT defining the segment from address `0x00000000` to `0xffffffff` +on privilege level 0 with RW attributes. -``` +```asm /* Locate system page */ movl %esp, %eax movl (%eax), %esi ``` -Next instruction sequence copies the `syspage_t` address from the stack into `esi` register. This address will be stored after paging initialization in `syspage` variable. +Next instruction sequence copies the `syspage_t` address from the stack into `esi` register. This address will be stored +after paging initialization in `syspage` variable. -``` +```asm /* Disable A20 line mask */ call _init_empty8042 movb $0xd1, %al @@ -40,9 +49,10 @@ Next instruction sequence copies the `syspage_t` address from the stack into `es call _init_empty8042 ``` -Before enabling paging A20 line masking is disabled. Enabled A20 line masking prevents use of linear memory addresses greater than 1MB. +Before enabling paging A20 line masking is disabled. Enabled A20 line masking prevents use of linear memory addresses +greater than 1MB. -``` +```asm /* Create empty page directory */ _init_setupPaging: (..) @@ -55,7 +65,7 @@ Before enabling paging A20 line masking is disabled. Enabled A20 line masking pr After disabling A20 line the page directory and page table are created and paging is enabled. -``` +```asm /* Relocate stack, GDT and IDT */ addl $VADDR_KERNEL, %esp addl $2, %esi @@ -70,7 +80,7 @@ After disabling A20 line the page directory and page table are created and pagin After enabling paging IDTR and GDTR registers are reload with relocated values. -``` +```asm /* Now jump to main function */ lea main, %eax pushl %eax @@ -79,10 +89,9 @@ After enabling paging IDTR and GDTR registers are reload with relocated values. The last part of code passes control to `main()` function. - ## Syspage definition -``` +```c #pragma pack(1) typedef struct _syspage_t { @@ -115,7 +124,7 @@ The last part of code passes control to `main()` function. Spinlocks are implemented using `xchg` instruction. The locking function has been presented below. -``` +```c static inline void hal_spinlockSet(hal_spinlock_t *spinlock) { __asm__ volatile @@ -141,7 +150,7 @@ First instruction stores flags on the stack. The context for IA32 has been presented below. -``` +```c typedef struct { u32 savesp; u32 edi; @@ -165,7 +174,8 @@ The context for IA32 has been presented below. } cpu_context_t; ``` -First part of the context is stored on the kernel stack automatically by CPU. After this part the general purpose registers are stored. On top of the stack is pushed the stack pointer for context switching. +First part of the context is stored on the kernel stack automatically by CPU. After this part the general purpose +registers are stored. On top of the stack is pushed the stack pointer for context switching. ## See also diff --git a/kernel/hal/riscv64.md b/kernel/hal/riscv64.md index d0b0012b..4d1f6b46 100644 --- a/kernel/hal/riscv64.md +++ b/kernel/hal/riscv64.md @@ -18,7 +18,7 @@ Kernel execution starts from `_start` symbol located in `_init.S` file. First instructions mask interrupts and disable FPU. -``` +```assembler /* Initialize syspage */ la a0, syspage la t0, pmap_common @@ -29,19 +29,21 @@ First instructions mask interrupts and disable FPU. The next step is setting the `syspage` pointer. -``` +```assembler call dtb_parse ``` -The hardware configuration is passed to kerne using Device Tree Blob (DTB). Pointer to DTB is stored in `a1` register. DTB parser extracts information necessary to kernel from tree and stores it in kernel structure. It could be used later by other components using `dtb_` functions. +The hardware configuration is passed to kerne using Device Tree Blob (DTB). Pointer to DTB is stored in `a1` register. +DTB parser extracts information necessary to kernel from tree and stores it in kernel structure. It could be used +later by other components using `dtb_` functions. -``` +```assembler call _pmap_preinit ``` After evaluating hardware configuration initial kernel page tables are initialized. -``` +```assembler li a1, VADDR_KERNEL la a0, _start li t0, 0xffffffffc0000000 @@ -67,7 +69,7 @@ The relocation offset is calculated. And relocation of stack and syspage is performed. -``` +```assembler /* Point stvec to virtual address of intruction after satp write */ la a0, 1f add a0, a0, a1 @@ -85,7 +87,7 @@ And relocation of stack and syspage is performed. The above sequence enables paging and pass execution to proper virtual address by setting the trap vector. -``` +```assembler /* Add dummy page fault trap handler */ la a0, .Lsecondary_park csrw stvec, a0 @@ -103,4 +105,4 @@ The above sequence enables paging and pass execution to proper virtual address b 2. [Kernel - HAL for ARMv7 Cortex-M based targets](armv7m.md) 3. [Kernel - HAL for ARMv7 Cortex-A based targets](armv7a.md) 4. [Kernel - HAL for IA32 targets](ia32.md) -5. [Table of Contents](../../README.md) \ No newline at end of file +5. [Table of Contents](../../README.md) diff --git a/kernel/proc/README.md b/kernel/proc/README.md index 846876a2..e98b7824 100644 --- a/kernel/proc/README.md +++ b/kernel/proc/README.md @@ -4,74 +4,150 @@ Process and thread abstractions are used to control the program execution in Pho ## Process -Process is the abstraction used for resource aggregation and to define the linear address space for the program execution. Process linear address space is defined using address spaces. Each process contains set of address spaces (each of them is described by its own memory map) accessible via its linear address space. On MMU architectures these address spaces are accessible using paging technique and segment definitions. On non-MMU architectures address spaces are accessible in the process linear address space using a segment definitions only (e.g. using MPU on ARM). +Process is the abstraction used for resource aggregation and to define the linear address space for the program +execution. Process linear address space is defined using address spaces. Each process contains set of address spaces +(each of them is described by its own memory map) accessible via its linear address space. On MMU architectures these +address spaces are accessible using paging technique and segment definitions. On non-MMU architectures address spaces +are accessible in the process linear address space using a segment definitions only (e.g. using MPU on ARM). ## Thread -Thread represents the program instruction stream and it is executed by processor concurrently with other threads. It means that execution of each thread is interrupted (periodically by system timer or aperiodically by external hardware interrupts), the processor state resulting from the thread execution is preserved and other thread is selected for the execution. If a computer system is equipped with many processor cores many threads are in fact executed concurrently. If only single processor core is available only one thread is executed in the particular time slot. The execution of threads is controller by operating system scheduler, a special subprogram invoked after each thread interruption deciding what thread from the ready thread pool should be executed on current processor in the following time slot. Generally speaking thread represents the instruction stream executed concurrently with other streams within a program. - -Thread can be associated with the kernel or with a process. When thread is associated with the kernel it can use only kernel address spaces. When it is associated with a process it can use all address spaces associated wit the process and kernel. When the access to the address space requires switching the processor to the privileged execution mode (e.g. access to kernel address spaces) the thread can do this using specific kernel function. Should be noticed that such transition between mode is carefully controlled by the operating system. The processor can enter into the particular mode using only well-defined entry points (e.g. after receiving hardware interrupt or executing program trap) handled by the operating system. The discussion of processor execution mode is presented below. +Thread represents the program instruction stream and it is executed by processor concurrently with other threads. It +means that execution of each thread is interrupted (periodically by system timer or aperiodically by external +hardware interrupts), the processor state resulting from the thread execution is preserved and other thread is selected +for the execution. If a computer system is equipped with many processor cores many threads are in fact executed +concurrently. If only single processor core is available only one thread is executed in the particular time slot. The +execution of threads is controller by operating system scheduler, a special subprogram invoked after each thread +interruption deciding what thread from the ready thread pool should be executed on current processor in the following +time slot. Generally speaking thread represents the instruction stream executed concurrently with other streams within +a program. + +Thread can be associated with the kernel or with a process. When thread is associated with the kernel it can use only +kernel address spaces. When it is associated with a process it can use all address spaces associated wit the process +and kernel. When the access to the address space requires switching the processor to the privileged execution mode +(e.g. access to kernel address spaces) the thread can do this using specific kernel function. Should be noticed that +such transition between mode is carefully controlled by the operating system. The processor can enter into the +particular mode using only well-defined entry points (e.g. after receiving hardware interrupt or executing program trap) + handled by the operating system. The discussion of processor execution mode is presented below. ## Operating system resources -During execution, thread can use operating system resources provided in the kernel or process context. The typical resources assigned to process are mutexes, conditional variables, files, network sockets, ports etc. These resources (kernel objects) are shared among executed processes and can be accessed by the particular process after opening. Operating system resources are accessible in the process context via handles. The simplest example of process resource is a file. After successful file opening the file handle is created (file descriptor in UN\*X terminology). Handle can be used to perform input and output operations on the opened file and can be inherited by child processes created by the process. The handle inheritance is widely used in current applications because it is promoted by POSIX standard and popular UN*X operating systems. +During execution, thread can use operating system resources provided in the kernel or process context. The typical +resources assigned to process are mutexes, conditional variables, files, network sockets, ports etc. These resources +(kernel objects) are shared among executed processes and can be accessed by the particular process after opening. +Operating system resources are accessible in the process context via handles. The simplest example of process resource +is a file. After successful file opening the file handle is created (file descriptor in UN\*X terminology). Handle can +be used to perform input and output operations on the opened file and can be inherited by child processes created by the +process. The handle inheritance is widely used in current applications because it is promoted by POSIX standard and +popular UN*X operating systems. To understand properly Phoenix-RTOS process model it should be discussed either for MMU and non-MMU architectures. ## Process model on architectures equipped with MMU Process model for MMU architectures has been presented on the following picture. -
- -
- -The linear address space is defined individually per process using MMU (Memory Management Unit) and virtual addressing. It means that the linear address space is virtual and each linear address is translated into the physical address. The translation of virtual address takes place with a granulation of memory page size and is performed using MMU (Memory Management Unit) - a hardware unit located between CPU address bus and system address bus. -The hardware mechanism used for the virtual address translation depends on the hardware platform. On some hardware architectures the virtual address translation is performed using special data structures (page tables) located in the physical memory and using hardware page walking algorithm embedded into the MMU. On other architectures the virtual to physical address associations are controlled directly by the operating system using specific MMU registers. In this approach operating system must define its own structures describing virtual address translations for each process. - -When thread context and associated process context are switched the MMU state is changed to define the linear address space. This can result with performance degradation because new definitions must be downloaded from physical memory into into the MMU. Therefore threads scheduling algorithm should minimize the MMU context switching. Some hardware architectures provide mechanisms extending the standard virtual address definition with bits identifying the process linear address space to prevent the MMU flushing during each process context switch. Unfortunately these mechanisms (e.g. ARM ASID) are in most cases insufficient because of limited range of these identifiers and are not used by operating systems. - -The virtual addressing has a great impact on program creation, execution and process separation. Due to virtual memory the linear address space of each process can use the same address ranges and each program can be loaded into the memory without performing the address relocations. The linear address space of each process can use the private address spaces (defined per-process) and global address spaces e.g. kernel address space. It should be noticed the kernel address space have to be mapped into the linear address space of each process because it is necessary to provide operating system services. + -Virtual addressing and private address spaces have also big impact on memory sharing. When a new process is created it can define its own private map based on already allocated and named physical memory (see [Memory objects](../vm/objects.md)). This map can be derived from the map of parent process or can be established from scratch. The smart use of copy-on-write technique allow to allocate the physical memory only for local modifications made by process threads during their execution (see [Memory objects](../vm/objects.md)). +The linear address space is defined individually per process using MMU (Memory Management Unit) and virtual addressing. +It means that the linear address space is virtual and each linear address is translated into the physical address. The +translation of virtual address takes place with a granulation of memory page size and is performed using MMU +(Memory Management Unit) - a hardware unit located between CPU address bus and system address bus. + +The hardware mechanism used for the virtual address translation depends on the hardware platform. On some hardware +architectures the virtual address translation is performed using special data structures (page tables) located in the +physical memory and using hardware page walking algorithm embedded into the MMU. On other architectures the virtual to +physical address associations are controlled directly by the operating system using specific MMU registers. In this +approach operating system must define its own structures describing virtual address translations for each process. + +When thread context and associated process context are switched the MMU state is changed to define the linear address +space. This can result with performance degradation because new definitions must be downloaded from physical memory +into into the MMU. Therefore threads scheduling algorithm should minimize the MMU context switching. Some hardware +architectures provide mechanisms extending the standard virtual address definition with bits identifying the process +linear address space to prevent the MMU flushing during each process context switch. Unfortunately these mechanisms +(e.g. ARM ASID) are in most cases insufficient because of limited range of these identifiers and are not used by +operating systems. + +The virtual addressing has a great impact on program creation, execution and process separation. Due to virtual memory +the linear address space of each process can use the same address ranges and each program can be loaded into the memory +without performing the address relocations. The linear address space of each process can use the private address spaces +(defined per-process) and global address spaces e.g. kernel address space. It should be noticed the kernel address space +have to be mapped into the linear address space of each process because it is necessary to provide operating system +services. + +Virtual addressing and private address spaces have also big impact on memory sharing. When a new process is created it +can define its private map based on already allocated and named physical memory (see +[Memory objects](../vm/objects.md)). This map can be derived from the map of parent process or can be established from +scratch. The smart use of copy-on-write technique allow to allocate the physical memory only for local modifications +made by process threads during their execution (see [Memory objects](../vm/objects.md)). ## Process model on architectures not equipped with MMU The process model on non-MMU architecture has been presented below. -
-
-The main difference between process model on MMU and non-MMU architectures is the lack of virtual addressing. Each process uses the same linear address space. Some of linear addresses can be excluded from the process linear address space using segment definition unit (e.g. MPU on ARM) or can be excluded conditionally depending and the processor execution mode. +The main difference between process model on MMU and non-MMU architectures is the lack of virtual addressing. Each +process uses the same linear address space. Some of linear addresses can be excluded from the process linear address +space using segment definition unit (e.g. MPU on ARM) or can be excluded conditionally depending and the processor +execution mode. ## Processor execution modes -Modern processors execute instructions using several execution modes. Execution modes allow to separate sensitive software parts (e.g. operating system kernel or machine emulation layer) from other software components. When processor enters into the particular mode only hardware resources (i.e. I/O space, memory segments) and processor programming model specific for this mode can be used. +Modern processors execute instructions using several execution modes. Execution modes allow to separate sensitive +software parts (e.g. operating system kernel or machine emulation layer) from other software components. When processor +enters into the particular mode only hardware resources (i.e. I/O space, memory segments) and processor programming +model specific for this mode can be used. -There are three commonly used and widely known processor execution modes – kernel mode (supervisor mode), user mode (application mode) and machine mode (machine emulation mode). +There are three commonly used and widely known processor execution modes – kernel mode (supervisor mode), user mode +(application mode) and machine mode (machine emulation mode). -The first of them is devoted for the operating system kernel execution, provides practically unlimited access to the hardware resources and privileged processor instructions can be used. +The first of them is devoted for the operating system kernel execution, provides practically unlimited access to the +hardware resources and privileged processor instructions can be used. -The user mode is used for user program (application) executions, provides limited access to the hardware resources, only user memory segments can be used and instruction set is limited to unprivileged instruction. +The user mode is used for user program (application) executions, provides limited access to the hardware resources, +only user memory segments can be used and instruction set is limited to unprivileged instruction. -The machine mode (e.g. SMM on IA32 or Machine Mode on RISC-V) is used "below" the operating system. It is used for hardware virtualization when some hardware resources are required and are not implemented in the hardware or it is used for processor initialization. The existence of this mode should be especially considered when the software with the real-time constraints is executed, because the hardware virtualization (code execution in the machine emulation mode) can be the source of unexpected program execution jitter. This mode allows usually for higher privileges than supervisor mode and is usually hidden from the operating system. +The machine mode (e.g. SMM on IA32 or Machine Mode on RISC-V) is used "below" the operating system. It is used for +hardware virtualization when some hardware resources are required and are not implemented in the hardware or it is used +for processor initialization. The existence of this mode should be especially considered when the software with the +real-time constraints is executed, because the hardware virtualization (code execution in the machine emulation mode) +can be the source of unexpected program execution jitter. This mode allows usually for higher privileges than supervisor +mode and is usually hidden from the operating system. -Because of software partitioning requirements on some processors new execution modes are introduced. These modes are used to separate some parts of the application code (e.g. parts involved in security) from untrusted parts of application. The good example of such mode is TrustZone extension on ARM or privileges rings on IA32 (introduced in 1986). +Because of software partitioning requirements on some processors new execution modes are introduced. These modes are +used to separate some parts of the application code (e.g. parts involved in security) from untrusted parts of +application. The good example of such mode is TrustZone extension on ARM or privileges rings on IA32 +(introduced in 1986). ## Thread transitioning between execution modes -During program execution within a thread, processor can transit between many execution modes. Transitioning takes place as the consequence of hardware interrupt, exception or program trap. When one of the mentioned events appears processor transit into the execution mode defined by interrupt/exception/trap vector descriptor. After the transition to the specified execution mode the processor programming model is extended with instructions specific for this mode and address spaces specific to this mode are accessible for the program. When execution on particular execution mode finishes program returns to the previous mode and restores previous program execution context. This return is performed using special processor instruction. On most processors it is the instruction use to notify of the end of interrupt handling. +During program execution within a thread, processor can transit between many execution modes. Transitioning takes place +as the consequence of hardware interrupt, exception or program trap. When one of the mentioned events appears processor +transit into the execution mode defined by interrupt/exception/trap vector descriptor. After the transition to the +specified execution mode the processor programming model is extended with instructions specific for this mode and +address spaces specific to this mode are accessible for the program. When execution on particular execution mode +finishes program returns to the previous mode and restores previous program execution context. This return is performed +using special processor instruction. On most processors it is the instruction use to notify of the end of interrupt +handling. ## Process separation -Phoenix-RTOS process model based on address spaces complemented by execution modes constitutes a very powerful mechanism for program separation. Global address spaces can be selectively mapped into the linear address space of selected processes. Private address spaces can effectively prevent the interference between processes, but they can be seamlessly used when MMU is available. +Phoenix-RTOS process model based on address spaces complemented by execution modes constitutes a very powerful mechanism +for program separation. Global address spaces can be selectively mapped into the linear address space of selected +processes. Private address spaces can effectively prevent the interference between processes, but they can be seamlessly +used when MMU is available. -Some of address spaces (e.g. kernel address space) can be attributed with the processor execution mode required to access to them. Using extended processor execution modes (e.g. ARM TrustZone or IA32 rings) the intermediate privilege modes can be introduced. This technique allows to separate the sensitive parts or program executed within a process from other parts. Privileged and separated address spaces mapped into many processes can consist shared data and code used for example for emulation or to implement managed execution environments. +Some of address spaces (e.g. kernel address space) can be attributed with the processor execution mode required to +access to them. Using extended processor execution modes (e.g. ARM TrustZone or IA32 rings) the intermediate privilege +modes can be introduced. This technique allows to separate the sensitive parts or program executed within a process +from other parts. Privileged and separated address spaces mapped into many processes can consist shared data and code +used for example for emulation or to implement managed execution environments. ## Implementation structure -The process and thread management subsystem is located in the `src/proc` subdirectory. The routines related to context switching are implemented in the HAL. +The process and thread management subsystem is located in the `src/proc` subdirectory. The routines related to context +switching are implemented in the HAL. ## See also diff --git a/kernel/proc/forking.md b/kernel/proc/forking.md index 60603e77..fb78b35b 100644 --- a/kernel/proc/forking.md +++ b/kernel/proc/forking.md @@ -1,38 +1,76 @@ # Kernel - Processes and threads - Management -Processes are created in Phoenix-RTOS using forking technique. When new process is created the current process forks into two processes - parent (process which initializes fork) and child. There are two forking functions used for process creation in Phoenix-RTOS - each of them should be used depending on the platform and MMU presence. The differences between these functions and circumstances of their usage are discussed in this chapter. +Processes are created in Phoenix-RTOS using forking technique. When new process is created the current process +forks into two processes - parent (process which initializes fork) and child. There are two forking functions +used for process creation in Phoenix-RTOS - each of them should be used depending on the platform and MMU presence. +The differences between these functions and circumstances of their usage are discussed in this chapter. ## Creating new process using `fork()` -The well-known method of creating new process in general purpose operating systems (e.g. UN*X) is a forking. The explanation of this method is quite simple. In the certain point of time a thread within a process calls `fork()` system call which creates a new process (child process) based on linear address space and operating system resources used by process calling `fork()` (parent process) and launches the thread within a child process. From this point of time processes are separated and they operate on their own address spaces. It means that all modification of process memory are visible only within them. For example lets consider process A forking into processes A and B. After forking, one of the threads of process A modifies variable located at address `addr` and stores there value 1 and thread of process B modifies the same variable at address `addr` and stores there 2. The modification are specific for the forked processes and operating system assures that process A sees the variable located at `addr` as 1 and process B sees it as 2. - -This technique can be only implemented when processors is equipped with MMU providing mechanisms for memory virtualization (e.g. paging) which enables programs to use the same linear address to access different segments of physical memory. On processors lacked of MMU the `fork()` method is unavailable and it is replaced by `vfork()`. +The well-known method of creating new process in general purpose operating systems (e.g. UN*X) is a forking. +The explanation of this method is quite simple. In the certain point of time a thread within a process calls `fork()` +system call which creates a new process (child process) based on linear address space and operating system resources +used by process calling `fork()` (parent process) and launches the thread within a child process. From this point of +time processes are separated and they operate on their own address spaces. It means that all modification of process +memory are visible only within them. For example lets consider process A forking into processes A and B. After forking, +one of the threads of process A modifies variable located at address `addr` and stores there value 1 and thread of +process B modifies the same variable at address `addr` and stores there 2. The modification are specific for the forked +processes and operating system assures that process A sees the variable located at `addr` as 1 and process B sees it as +2. + +This technique can be only implemented when processors is equipped with MMU providing mechanisms for memory +virtualization (e.g. paging) which enables programs to use the same linear address to access different segments of +physical memory. On processors lacked of MMU the `fork()` method is unavailable and it is replaced by `vfork()`. ## Creating new process using `vfork()` -Historically `vfork()` is designed to be used in the specific case where the child will `exec()` another program, and the parent can block until this happens. A traditional `fork()` requires duplicating all the memory of the parent process in the child what leads to a significant overhead. The goal of the `vfork()` function was to reduce this overhead by preventing unnecessary memory copying when new process is created. Usually after process creation using `fork()` function a new program is executed. In such case traditional fork before `exec()` leads to unnecessary overhead (memory is copied to the child process then is freed and replaced by new memory objects as the result of `exec()`). +Historically `vfork()` is designed to be used in the specific case where the child will `exec()` another program, and +the parent can block until this happens. A traditional `fork()` requires duplicating all the memory of the parent +process in the child what leads to a significant overhead. The goal of the `vfork()` function was to reduce this +overhead by preventing unnecessary memory copying when new process is created. Usually after process creation using +`fork()` function a new program is executed. In such case traditional fork before `exec()` leads to unnecessary +overhead (memory is copied to the child process then is freed and replaced by new memory objects as the result of +`exec()`). -In UN*X operating system history "The Mach VM system" added Copy On Write (COW), which made the `fork()` much cheaper, and in BSD 4.4, `vfork()` was made synonymous to `fork()`. +In UN*X operating system history "The Mach VM system" added Copy On Write (COW), which made the `fork()` much cheaper, +and in BSD 4.4, `vfork()` was made synonymous to `fork()`. -`vfork()` function has another important repercussions for non-MMU architectures. Because of it semantics it allows to launch a new process it the same way like using `fork()` what enables application portability. +`vfork()` function has another important repercussions for non-MMU architectures. Because of it semantics it allows to +launch a new process it the same way like using `fork()` what enables application portability. -Some consider the semantics of `vfork()` to be an architectural blemish and POSIX.1-2008 removed `vfork()` from the standard and replaced by `posix_spawn()`. The POSIX rationale for the `posix_spawn()` function notes that that function, which provides functionality equivalent to `fork()`+`exec()`, is designed to be implementable on systems that lack an MMU. +Some consider the semantics of `vfork()` to be an architectural blemish and POSIX.1-2008 removed `vfork()` from the +standard and replaced by `posix_spawn()`. The POSIX rationale for the `posix_spawn()` function notes that that function, +which provides functionality equivalent to `fork()`+`exec()`, is designed to be implementable on systems that lack an +MMU. ## Process termination -Process can be terminated abnormally - as the consequence of receiving signal or normally after executing `exit()` function. When process exits all of its threads are terminated, all memory objects are unmapped and all resource handles are freed/closed. The parent process receives `SIGCHLD` signal notifying it about the child termination. `SIGCHLD` signal plays other important role in process termination sequence. It allows to safety remove the remaining child process resources which are not able to be removed during the process runtime (e.g last thread kernel stack). +Process can be terminated abnormally - as the consequence of receiving signal or normally after executing `exit()` +function. When process exits all of its threads are terminated, all memory objects are unmapped and all resource handles +are freed/closed. The parent process receives `SIGCHLD` signal notifying it about the child termination. `SIGCHLD` +signal plays other important role in process termination sequence. It allows to safety remove the remaining child +process resources which are not able to be removed during the process runtime (e.g last thread kernel stack). ## Program execution -To execute a new program the binary object representing it should be mapped into the process linear address space and control have to be passed to the program entry point. This is the responsibility of `exec()` family functions. +To execute a new program the binary object representing it should be mapped into the process linear address space and +control have to be passed to the program entry point. This is the responsibility of `exec()` family functions. -On non-MMU architectures there is one important step performed after binary object is mapped and before control is passed to the program entry point. This step is the program relocation which recalculates some of program structures (e.g. `GOT`) used for accessing variables during the runtime. The relocation depends on the current memory location of program. +On non-MMU architectures there is one important step performed after binary object is mapped and before control is +passed to the program entry point. This step is the program relocation which recalculates some of program structures +(e.g. `GOT`) used for accessing variables during the runtime. The relocation depends on the current memory location of +program. ## Thread management -While process represents a memory space and operating system resources devoted for particular executed program the thread represents the program instruction stream executed concurrently to other threads in the process context (using defined linear address space and associated operating system resources). To manage threads `beginthread()`, `endthread()` functions should be used. +While process represents a memory space and operating system resources devoted for particular executed program the +thread represents the program instruction stream executed concurrently to other threads in the process context +(using defined linear address space and associated operating system resources). To manage threads `beginthread()`, +`endthread()` functions should be used. -`beginthread()` function starts a new thread using function address and stack allocated by a calling thread. The kernel stacks for all of desired thread execution modes are allocated. `endthread()` function terminates calling thread and releases allocated kernel stacks. +`beginthread()` function starts a new thread using function address and stack allocated by a calling thread. The kernel +stacks for all of desired thread execution modes are allocated. `endthread()` function terminates calling thread and +releases allocated kernel stacks. ## See also diff --git a/kernel/proc/msg.md b/kernel/proc/msg.md index 605ecf3a..cf2d64e0 100644 --- a/kernel/proc/msg.md +++ b/kernel/proc/msg.md @@ -1,13 +1,15 @@ # Kernel - Processes and threads - Message passing -Message passing is the fundamental functionality of the operating system kernel which acts as a basic method of interaction between operating system components. Message passing in Phoenix-RTOS is synchronous. Sending thread is suspended until the receiving thread receives a message and responds to it. +Message passing is the fundamental functionality of the operating system kernel which acts as a basic method of +interaction between operating system components. Message passing in Phoenix-RTOS is synchronous. Sending thread is +suspended until the receiving thread receives a message and responds to it. ## Ports Port is the communication endpoint used for passing messages between executed threads. - ## Data transfer + Kernel implements message passing by the following functions. ```c @@ -20,17 +22,29 @@ extern int proc_respond(u32 port, msg_t *msg, unsigned int rid); Structure `msg_t` identifies message type and and consist of two main parts - input part and output part. -Input part points to the input buffer and defines its size. It contains also a small buffer for passing the message application header. The output part has symmetrical architecture to input buffer. It contains the pointer to output buffer, output buffer data length and buffer for output application header. +Input part points to the input buffer and defines its size. It contains also a small buffer for passing the message +application header. The output part has symmetrical architecture to input buffer. It contains the pointer to output +buffer, output buffer data length and buffer for output application header. -When message is sent by the `proc_send` function the sending thread is suspended until the receiving thread executes `proc_recv` function, reads data from input buffer, writes the final answer to the output buffer and executes `proc_respond`. The `rid` word identifies the receiving context and should be provided to the `proc_respond` function. There is possible to execute a lot of instruction between receiving and responding procedure. Responding function is used to wake-up the sending thread and inform it that data in output buffer are completed. +When message is sent by the `proc_send` function the sending thread is suspended until the receiving thread executes +`proc_recv` function, reads data from input buffer, writes the final answer to the output buffer and executes +`proc_respond`. The `rid` word identifies the receiving context and should be provided to the `proc_respond` function. +There is possible to execute a lot of instruction between receiving and responding procedure. Responding function is +used to wake-up the sending thread and inform it that data in output buffer are completed. -To prevent copying of big data blocks over the kernel when communication goes between threads assigned to separate processes special optimization is introduced. When message is received by the receiving thread input and output buffers are transparently mapped into the receiver address space. To prevent interference with other data, if any of these buffers is not aligned with the page, the heading or tailing part of this buffer is copied to the newly allocated page mapped instead of the original page. When receiving thread responses to the message the buffers are unmapped and heading or tailing parts are copied to the original page located in sender address space. This technique is briefly presented on following figure. +To prevent copying of big data blocks over the kernel when communication goes between threads assigned to separate +processes special optimization is introduced. When message is received by the receiving thread input and output buffers +are transparently mapped into the receiver address space. To prevent interference with other data, if any of these +buffers is not aligned with the page, the heading or tailing part of this buffer is copied to the newly allocated page +mapped instead of the original page. When receiving thread responses to the message the buffers are unmapped and heading +or tailing parts are copied to the original page located in sender address space. This technique is briefly presented on +following figure. -There is another type of optimization. If input or output data size is lower then page size and data fits into the buffer used for application header passing the data is copied instead of using virtual memory capabilities which provide extra overhead for small messages. - - +There is another type of optimization. If input or output data size is lower then page size and data fits into the +buffer used for application header passing the data is copied instead of using virtual memory capabilities which provide +extra overhead for small messages. ## See also diff --git a/kernel/proc/namespace.md b/kernel/proc/namespace.md index e86d428c..beeec364 100644 --- a/kernel/proc/namespace.md +++ b/kernel/proc/namespace.md @@ -1,11 +1,18 @@ # Kernel - Processes and threads - Namespace -The namespace and port registering functionality is used by operating system servers (e.g. device drivers, file servers) as a basic method of integration with the other operating system components. For example if a thread working in the process context opens the file given by specific path, it indirectly lookups for the port of the file server handling this object and finally receives the `oid_t`(port, id) structure identifying the file on the server. It is done because the file server handling particular file during start registers its port in the namespace handled by the other server or by the kernel. File server mount its namespace to the existing namespace handled by existing file servers. The namespace mounting functionality is presented on the following picture. +The namespace and port registering functionality is used by operating system servers (e.g. device drivers, file servers) +as a basic method of integration with the other operating system components. For example if a thread working in the +process context opens the file given by specific path, it indirectly lookups for the port of the file server handling +this object and finally receives the `oid_t`(port, id) structure identifying the file on the server. It is done because +the file server handling particular file during start registers its port in the namespace handled by the other server +or by the kernel. File server mount its namespace to the existing namespace handled by existing file servers. The +namespace mounting functionality is presented on the following picture. -In case of device drivers they registers special names in the namespace and associate them with the specific `oids`. -When program opens the file registered by a device driver it receives `oid` pointed directly to the device driver server, so all communication is redirected to this server. This idea has been briefly presented on following figure. +In case of device drivers they registers special names in the namespace and associate them with the specific `oids`. +When program opens the file registered by a device driver it receives `oid` pointed directly to the device driver +server, so all communication is redirected to this server. This idea has been briefly presented on following figure. diff --git a/kernel/proc/scheduler.md b/kernel/proc/scheduler.md index 2ed708a2..88d36faa 100644 --- a/kernel/proc/scheduler.md +++ b/kernel/proc/scheduler.md @@ -1,26 +1,35 @@ # Kernel - Processes and threads - Scheduler -The operating system scheduler controls threads execution with a predetermined policy. It is a part of Phoenix-RTOS having the most significant influence on the performance and responsiveness of the whole system. + +The operating system scheduler controls threads execution with a predetermined policy. It is a part of Phoenix-RTOS +having the most significant influence on the performance and responsiveness of the whole system. ## Scheduling policy -The scheduling algorithm is defined in the `threads_schedule` function. It is invoked by timer interrupt or voluntary reschedule (`hal_cpuReschedule`). Each function's invocation changes the context of the currently executed thread to the next one, available in a thread's ready queue. The scheduling policy determined which thread shall be chosen for the next execution. In Phoenix-RTOS a priority preempted round-robin algorithm is used. There are eight priority levels, the smallest value holds the highest priority. +The scheduling algorithm is defined in the `threads_schedule` function. It is invoked by timer interrupt or voluntary +reschedule (`hal_cpuReschedule`). Each function's invocation changes the context of the currently executed thread to +the next one, available in a thread's ready queue. The scheduling policy determined which thread shall be chosen for +the next execution. In Phoenix-RTOS a priority preempted round-robin algorithm is used. There are eight priority levels, +the smallest value holds the highest priority. -The thread management unit contains an eight-element array, where each of them holds a pointer to the list of threads of the same priority. A scheduling algorithm is defined as follows: +The thread management unit contains an eight-element array, where each of them holds a pointer to the list of threads of +the same priority. A scheduling algorithm is defined as follows: 1. The `threads_common.spinlock` is set before any operations on common data. 2. The current thread's context for the interrupted core is saved and added to the end of its priority list. -3. The next available thread with the highest priority is selected to be run and is removed from the ready thread list. If a selected thread is a ghost (a thread whose process has ended execution) and has not been executed in a supervisor mode, it is added to the ghosts list and the reaper thread is woke up. +3. The next available thread with the highest priority is selected to be run and is removed from the ready thread list. +If a selected thread is a ghost (a thread whose process has ended execution) and has not been executed in a supervisor +mode, it is added to the ghosts list and the reaper thread is woke up. 4. For the selected thread, the following actions are performed: * a global pointer to the current thread is changed to the selected one, * a pointer to the kernel stack is updated to the stack of a new thread, * a memory map is changed to the map associated with the thread's process, * signal handlers are performed, * performance data is saved in a perf unit, - * in the `hal_cpuRestore` pointer to the stack in a context of current thread is updated with a pointer to the stack of selected thread. When the scheduler finishes work, the context of selected thread restore is performed. + * in the `hal_cpuRestore` pointer to the stack in a context of current thread is updated with a pointer to the stack + of selected thread. When the scheduler finishes work, the context of selected thread restore is performed. 5. The cpu usage is updated for the current and selected thread. 6. At the end of the modification of the `threads_common.spinlock` is cleared. - ## See also 1. [Kernel - Processes and threads](README.md) diff --git a/kernel/proc/sync.md b/kernel/proc/sync.md index 516d32a5..782dc225 100644 --- a/kernel/proc/sync.md +++ b/kernel/proc/sync.md @@ -1,18 +1,35 @@ # Kernel - Processes and threads - Synchronization primitives -Phoenix-RTOS kernel implements three widely used methods for synchronization of concurrently executed instruction streams. +Phoenix-RTOS kernel implements three widely used methods for synchronization of concurrently executed instruction +streams. ## Spinlocks -Spinlocks are used in kernel for active synchronization of instruction streams executed in parallel on multiple processing cores. They are implemented using special processor instruction allowing to atomically exchange value stored in processor register with a value stored in a memory at specified linear address. This processor instruction belongs to the class of so-called `test-and-set` instructions introduced especially for synchronization purposes. Their logic may slightly vary between specific processor architectures but the overall semantic remains consistent with atomic exchange between memory and processor register. +Spinlocks are used in kernel for active synchronization of instruction streams executed in parallel on multiple +processing cores. They are implemented using special processor instruction allowing to atomically exchange value stored +in processor register with a value stored in a memory at specified linear address. This processor instruction belongs +to the class of so-called `test-and-set` instructions introduced especially for synchronization purposes. Their logic +may slightly vary between specific processor architectures but the overall semantic remains consistent with atomic +exchange between memory and processor register. -Spinlocks are the basic method of synchronization used to implement mechanisms based on the thread scheduling. They are used to synchronize access to scheduler thread lists or to synchronize access before thread scheduler is initialized or when data is shared among threads and interrupt handlers. +Spinlocks are the basic method of synchronization used to implement mechanisms based on the thread scheduling. They are +used to synchronize access to scheduler thread lists or to synchronize access before thread scheduler is initialized or +when data is shared among threads and interrupt handlers. -Spinlock logic is quite simple. When program tries to enter into the critical section which should be executed exclusively by only one instruction stream it checks the spinlock value in memory by exchanging it with the value 0 meaning that access to the critical section has been granted. If the spinlock value read from memory and swapped atomically with 0 was greater then 0 processor can start the further instruction stream execution. If not it should repeat previous exchange until it checks that access was not granted before the check (spinlock value gathered from memory during the swap was 1). +Spinlock logic is quite simple. When program tries to enter into the critical section which should be executed +exclusively by only one instruction stream it checks the spinlock value in memory by exchanging it with the value 0 +meaning that access to the critical section has been granted. If the spinlock value read from memory and swapped +atomically with 0 was greater then 0 processor can start the further instruction stream execution. If not it should +repeat previous exchange until it checks that access was not granted before the check (spinlock value gathered from +memory during the swap was 1). -Spinlocks are widely used to synchronize memory access between synchronous code executed as main instruction stream and asynchronous code executed as interrupt/exception handlers so before spinlock `test-and-set` operation, interrupts on the current processing core should be disabled and the processor state connected with interrupt handling should be preserved. +Spinlocks are widely used to synchronize memory access between synchronous code executed as main instruction stream and +asynchronous code executed as interrupt/exception handlers so before spinlock `test-and-set` operation, interrupts on +the current processing core should be disabled and the processor state connected with interrupt handling should be +preserved. -Overall spinlock lock implementation has been presented below in C using preprocessor macros to represent blocks of processor-specific assembly code. +Overall spinlock lock implementation has been presented below in C using preprocessor macros to represent blocks of +processor-specific assembly code. ```c SAVE_INTERRUPTS_STATE(CURRENT_CPU, state); @@ -21,7 +38,9 @@ Overall spinlock lock implementation has been presented below in C using preproc while (!TEST_AND_SET(0, spinlock)); ``` -Spinlock unlocking operation is quite simple. Processor atomically changes spinlock value in memory to non-zero and restores its interrupt state based on state saved in spinlock. It is worth to add that operation on spinlock should save and restore processor state from the variable assigned specifically for this particular processor. +Spinlock unlocking operation is quite simple. Processor atomically changes spinlock value in memory to non-zero and +restores its interrupt state based on state saved in spinlock. It is worth to add that operation on spinlock should +save and restore processor state from the variable assigned specifically for this particular processor. ```c TEST_AND_SET(1, spinlock); @@ -30,13 +49,15 @@ Spinlock unlocking operation is quite simple. Processor atomically changes spinl ## Locks and mutexes -Locks are used to synchronize access to critical sections inside kernel using scheduling mechanism. The main difference between locks and spinlocks is that they use passive waiting (removal from scheduler queues) instead of active waiting (iterations until spinlock value becomes non-zero). Locks can be used only when process subsystem is initializes and scheduler is working. +Locks are used to synchronize access to critical sections inside kernel using scheduling mechanism. The main difference +between locks and spinlocks is that they use passive waiting (removal from scheduler queues) instead of active waiting +(iterations until spinlock value becomes non-zero). Locks can be used only when process subsystem is initializes and +scheduler is working. -Each lock consist of spinlock, state variable and waiting queue. +Each lock consist of spinlock, state variable and waiting queue. ## Conditional variables - ## See also 1. [Kernel - Processes and threads](README.md) diff --git a/kernel/syscalls/README.md b/kernel/syscalls/README.md index a9f5e68a..ee909bf3 100644 --- a/kernel/syscalls/README.md +++ b/kernel/syscalls/README.md @@ -1,35 +1,50 @@ # System calls -System call (commonly abbreviated to syscall) is an entry point to execute a specific user program's request to a service from the kernel. The operating system kernel runs in a privileged mode to protect a sensitive software and hardware parts from the other software components. A user application executing in an unprivileged mode does not have access to the protected data. Performing a hardware interrupt or conducting a trap handled by the kernel, the user application can obtain sensitive data from the kernel, e.g. an information about all processes running in the system. +System call (commonly abbreviated to syscall) is an entry point to execute a specific user program's request to a +service from the kernel. The operating system kernel runs in a privileged mode to protect a sensitive software and +hardware parts from the other software components. A user application executing in an unprivileged mode does not have +access to the protected data. Performing a hardware interrupt or conducting a trap handled by the kernel, the user +application can obtain sensitive data from the kernel, e.g. an information about all processes running in the system. ## Prototypes and definition -In Phoenix-RTOS prototypes and definitions of the the system calls are located in the `libphoenix` library. A list of the all system calls is placed in a `phoenix-rtos-kernel/include/syscalls.h` header files, grouped by categories. +In Phoenix-RTOS prototypes and definitions of the the system calls are located in the `libphoenix` library. A list of +the all system calls is placed in a `phoenix-rtos-kernel/include/syscalls.h` header files, grouped by categories. -System call prototypes should be placed in the an appropriate header file in the `libphoenix` standard library, referring to the syscall's category. -System call definitions are placed in the `arch/$(TARGET_SUFF)/syscalls.S` file and are created based on a syscall list via macro. Each definition triggers an exception (e.g. SuperVisor Call - svc instruction for ARM Cortex-M or Cortex-A) with an appropriate syscall identification number handled by the kernel in the privileged mode. Arguments are passed according to the target platform ABI (Application Binary Interface). +System call prototypes should be placed in the an appropriate header file in the `libphoenix` standard library, +referring to the syscall's category. +System call definitions are placed in the `arch/$(TARGET_SUFF)/syscalls.S` file and are created based on a syscall list +via macro. Each definition triggers an exception (e.g. SuperVisor Call - svc instruction for ARM Cortex-M or Cortex-A) +with an appropriate syscall identification number handled by the kernel in the privileged mode. Arguments are passed +according to the target platform ABI (Application Binary Interface). -Handler definitions for system calls are located in the `phoenix-rtos-kernel/syscalls.c` file. Each handler should contain an appropriate return type consistent with the prototype in `libphoenix` (in practice `int`) and take the user stack pointer as an argument. The syscall's parameters can be obtained from the user stack using the macro `GETFROMSTACK(stack_ptr, arg_type, var, id)`. +Handler definitions for system calls are located in the `phoenix-rtos-kernel/syscalls.c` file. Each handler should +contain an appropriate return type consistent with the prototype in `libphoenix` (in practice `int`) and take the user +stack pointer as an argument. The syscall's parameters can be obtained from the user stack using the macro +`GETFROMSTACK(stack_ptr, arg_type, var, id)`. -Phoenix-RTOS in kernel mode has access to the calling process memory, so the pointer to the data in the user space can be passed as an argument to system call and used in the kernel space. +Phoenix-RTOS in kernel mode has access to the calling process memory, so the pointer to the data in the user space can +be passed as an argument to system call and used in the kernel space. ## Adding syscall -An example of adding a system call is conducted based on the `threadsinfo` syscall. The procedure should be performed as follows: +An example of adding a system call is conducted based on the `threadsinfo` syscall. The procedure should be performed as +follows: -1. Add syscall's declaration in `libphoenix`, e.g. `libphoenix/inlude/sys/threads.h`: +1.Add syscall's declaration in `libphoenix`, e.g. `libphoenix/inlude/sys/threads.h`: ```C extern int threadsinfo(int n, threadinfo_t *info); ``` -2. Update the syscall list in `phoenix-rtos-kernel/include/syscalls.h`. It is recommended to insert a new syscall at the end of the list: +2.Update the syscall list in `phoenix-rtos-kernel/include/syscalls.h`. It is recommended to insert a new syscall at the +end of the list: ```C ID(threadsinfo) \ ``` -3. Create a syscall handler in `phoenix-rtos-kernel/syscalls.c`: +3.Create a syscall handler in `phoenix-rtos-kernel/syscalls.c`: ```C int syscalls_threadsinfo(void *ustack) @@ -61,7 +76,8 @@ An example of adding a system call is conducted based on the `threadsinfo` sysca } ``` -4. The system call can be invoked in user application by including `sys/threads.h` header. This example syscall is used by the `ps` applet in the `psh` (Phoenix-Shell). +4.The system call can be invoked in user application by including `sys/threads.h` header. This example syscall is used +by the `ps` applet in the `psh` (Phoenix-Shell). ## See also diff --git a/kernel/syscalls/file.md b/kernel/syscalls/file.md index 4474077c..b5ccb67b 100644 --- a/kernel/syscalls/file.md +++ b/kernel/syscalls/file.md @@ -8,9 +8,8 @@ GETFROMSTACK(ustack, oid_t *, oid, 1); GETFROMSTACK(ustack, unsigned int, mode, 2); ```` -Adds file given by `oid` to process resources. Added process resource is identified by handle returned in `h` variable. The access mode is set to `mode`. - -
+Adds file given by `oid` to process resources. Added process resource is identified by handle returned in `h` variable. +The access mode is set to `mode`. ## `syscalls_fileOpen` (`syscalls_sys_open`) @@ -19,8 +18,6 @@ GETFROMSTACK(ustack, const char *, filename, 0); GETFROMSTACK(ustack, int, oflag, 1); ```` -
- ## DEPRECATED `syscalls_fileSet` => `syscalls_fileRead`, `syscalls_fileWrite` ````C @@ -33,8 +30,6 @@ GETFROMSTACK(ustack, unsigned, mode, 4); Updates file parameters for file given by resource handle `h`. -
- ## DEPRECATED `syscalls_fileGet` => `syscalls_fileRead`, `syscalls_fileWrite` ````C @@ -47,8 +42,6 @@ GETFROMSTACK(ustack, unsigned *, mode, 4); Retrieves file parameters for file given by resource handle `h`. -
- ## DEPRECATED `syscalls_fileRemove` => `syscalls_fileClose` ````C @@ -57,8 +50,6 @@ GETFROMSTACK(ustack, unsigned int, h, 0); Removes file given by `h` from resources of calling process. -
- ## DEPRECATED `syscalls_resourceDestroy` => `syscalls_fileClose`, `syscalls_mutexDestroy`, `syscalls_condDestroy` ````C @@ -67,8 +58,6 @@ GETFROMSTACK(ustack, unsigned int, h, 0); Destroys resource given by `h`. -
- ## `syscalls_fileRead` (`syscalls_sys_read`) ````C @@ -77,8 +66,6 @@ GETFROMSTACK(ustack, void *, buf, 1); GETFROMSTACK(ustack, size_t, nbyte, 2); ```` -
- ## `syscalls_fileWrite` (`syscalls_sys_write`) ````C @@ -87,16 +74,12 @@ GETFROMSTACK(ustack, void *, buf, 1); GETFROMSTACK(ustack, size_t, nbyte, 2); ```` -
- ## `syscalls_fileClose` (`syscalls_sys_close`) ````C GETFROMSTACK(ustack, int, fildes, 0); ```` -
- ## `syscalls_fileLink` (`syscalls_sys_link`) ````C @@ -104,16 +87,12 @@ GETFROMSTACK(ustack, const char *, path1, 0); GETFROMSTACK(ustack, const char *, path2, 1); ```` -
- ## `syscalls_fileUnlink` (`syscalls_sys_unlink`) ````C GETFROMSTACK(ustack, const char *, pathname, 0); ```` -
- ## `syscalls_fileCtl` (`syscalls_sys_fcntl`) ````C @@ -121,8 +100,6 @@ GETFROMSTACK(ustack, unsigned int, fd, 0); GETFROMSTACK(ustack, unsigned int, cmd, 1); ```` -
- ## `syscalls_fileTrunc` (`syscalls_sys_ftruncate`) ````C @@ -130,8 +107,6 @@ GETFROMSTACK(ustack, int, fildes, 0); GETFROMSTACK(ustack, off_t, length, 1); ```` -
- ## `syscalls_fileSeek` (`syscalls_sys_lseek`) ````C @@ -140,16 +115,12 @@ GETFROMSTACK(ustack, off_t, offset, 1); GETFROMSTACK(ustack, int, whence, 2); ```` -
- ## `syscalls_fileDup` (`syscalls_sys_dup`) ````C GETFROMSTACK(ustack, int, fildes, 0); ```` -
- ## `syscalls_fileDup2` (`syscalls_sys_dup2`) ````C @@ -157,16 +128,12 @@ GETFROMSTACK(ustack, int, fildes, 0); GETFROMSTACK(ustack, int, fildes2, 1); ```` -
- ## `syscalls_filePipe` (`syscalls_sys_pipe`) ````C GETFROMSTACK(ustack, int *, fildes, 0); ```` -
- ## `syscalls_fileMakeFifo` (`syscalls_sys_mkfifo`) ````C @@ -174,8 +141,6 @@ GETFROMSTACK(ustack, const char *, path, 0); GETFROMSTACK(ustack, mode_t, mode, 1); ```` -
- ## `syscalls_fileChangeMode` (`syscalls_sys_chmod`) ````C @@ -183,8 +148,6 @@ GETFROMSTACK(ustack, const char *, path, 0); GETFROMSTACK(ustack, mode_t, mode, 1); ```` -
- ## `syscalls_fileStat` (`syscalls_sys_fstat`) ````C @@ -192,8 +155,6 @@ GETFROMSTACK(ustack, int, fd, 0); GETFROMSTACK(ustack, struct stat *, buf, 1); ```` -
- ## `syscalls_fileIoCtl` (`syscalls_sys_ioctl`) ````C @@ -201,8 +162,6 @@ GETFROMSTACK(ustack, int, fildes, 0); GETFROMSTACK(ustack, unsigned long, request, 1); ```` -
- ## `syscalls_fileTimes` (`syscalls_sys_utimes`) ````C @@ -210,8 +169,6 @@ GETFROMSTACK(ustack, const char *, filename, 0); GETFROMSTACK(ustack, const struct timeval *, times, 1); ```` -
- ## `syscalls_filePoll` (`syscalls_sys_poll`) ````C diff --git a/kernel/syscalls/ipc.md b/kernel/syscalls/ipc.md index c3194c1b..02b6c45e 100644 --- a/kernel/syscalls/ipc.md +++ b/kernel/syscalls/ipc.md @@ -8,8 +8,6 @@ GETFROMSTACK(ustack, u32 *, port, 0); Creates new communication queue and returns its identifier in `port` variable. -
- ## `syscalls_portDestroy` ````C @@ -18,8 +16,6 @@ GETFROMSTACK(ustack, u32, port, 0); Destroys communication queue identified by `port` variable. -
- ## `syscalls_portRegister` ````C @@ -30,8 +26,6 @@ GETFROMSTACK(ustack, oid_t *, oid, 2); Registers `port` in the namespace at `name` and returns object identifier `oid` identifying this association. -
- ## `syscalls_msgSend` ````C @@ -39,9 +33,8 @@ GETFROMSTACK(ustack, u32, port, 0); GETFROMSTACK(ustack, msg_t *, msg, 1); ```` -Sends message `msg` to queue identified by `port`. Execution of calling thread is suspended until receiving thread responds to this message. - -
+Sends message `msg` to queue identified by `port`. Execution of calling thread is suspended until receiving thread +responds to this message. ## `syscalls_msgRecv` @@ -63,8 +56,6 @@ GETFROMSTACK(ustack, unsigned long int, rid, 2); Responds to message `msg` using reception context `rid`. -
- ## `syscalls_lookup` ````C @@ -73,29 +64,19 @@ GETFROMSTACK(ustack, oid_t *, file, 1); GETFROMSTACK(ustack, oid_t *, dev, 2); ```` -Lookups for object identifier (`port` and resource `id`) associated with `name`. Object identifier representing file is returned in `file` variable. If file is associated with other object the other object id is returned in `dev`. - -
+Lookups for object identifier (`port` and resource `id`) associated with `name`. Object identifier representing file is +returned in `file` variable. If file is associated with other object the other object id is returned in `dev`. ## `syscalls_signalHandle` -
- ## `syscalls_signalPost` -
- ## `syscalls_signalMask` -
- ## `syscalls_signalSuspend` -
- ## DEPRECATED `syscalls_sys_tkill` => `syscalls_signalPost` - ## See also 1. [System calls](README.md) diff --git a/kernel/syscalls/mem.md b/kernel/syscalls/mem.md index 57e0157c..e819d113 100644 --- a/kernel/syscalls/mem.md +++ b/kernel/syscalls/mem.md @@ -13,9 +13,8 @@ GETFROMSTACK(ustack, oid_t *, oid, 4); GETFROMSTACK(ustack, offs_t, offs, 5); ```` -Maps part of object given by `oid`, `offs` and `size` at `vaddr` with protection attributes given by `prot` using mapping mode defined by `flags`. - -
+Maps part of object given by `oid`, `offs` and `size` at `vaddr` with protection attributes given by `prot` using +mapping mode defined by `flags`. ## `syscalls_memUnmap` (`syscalls_munmap`) @@ -26,30 +25,22 @@ GETFROMSTACK(ustack, size_t, size, 1); Unmaps part of address space defined by `vaddr` and `size`. -
- ## `syscalls_memDump` (`syscalls_mmdump`) Returns memory map entries associated with calling process. -
- ## `syscalls_memGetInfo` (`syscalls_meminfo`) ````C GETFROMSTACK(ustack, meminfo_t *, info, 0); ```` -
- ## `syscalls_memGetPhysAddr` (`syscalls_va2pa`) ````C GETFROMSTACK(ustack, void *, va, 0); ```` -
- ## See also 1. [System calls](README.md) diff --git a/kernel/syscalls/perf.md b/kernel/syscalls/perf.md index 2e9aa5cc..03d18a42 100644 --- a/kernel/syscalls/perf.md +++ b/kernel/syscalls/perf.md @@ -8,8 +8,6 @@ GETFROMSTACK(ustack, unsigned, pid, 0); Starts performance monitoring for proces given by `pid`. -
- ## `syscalls_perfRead` (`syscalls_perf_read`) ````C @@ -19,8 +17,6 @@ GETFROMSTACK(ustack, size_t, sz, 1); Reads gathered performance monitoring events. -
- ## `syscalls_perfFinish` (`syscalls_perf_finish`) Finishes performance monitoring. @@ -28,4 +24,4 @@ Finishes performance monitoring. ## See also 1. [System calls](README.md) -2. [Table of Contents](../../README.md) \ No newline at end of file +2. [Table of Contents](../../README.md) diff --git a/kernel/syscalls/platform.md b/kernel/syscalls/platform.md index 6d04086e..3c85dca2 100644 --- a/kernel/syscalls/platform.md +++ b/kernel/syscalls/platform.md @@ -8,14 +8,10 @@ GETFROMSTACK(ustack, void *, ptr, 0); Executes platform controll call with argument given by `ptr`. -
- ## `syscall_platformWdogReload` (`syscalls_wdgreload`) Reloads watchdog device when it is available. -
- ## `syscalls_platformSyspageProg` (`syscalls_syspageprog`) ````C @@ -23,8 +19,6 @@ GETFROMSTACK(ustack, syspageprog_t *, prog, 0); GETFROMSTACK(ustack, int, i, 1); ```` -
- ## `syscalls_platformKeepIdle` (`syscalls_keepidle`) ````C diff --git a/kernel/syscalls/proc.md b/kernel/syscalls/proc.md index ed4c4f12..fc43fcb8 100644 --- a/kernel/syscalls/proc.md +++ b/kernel/syscalls/proc.md @@ -4,13 +4,10 @@ Forks current process into two processes. -
- ### `syscalls_procVirtualFork` (`syscalls_vforksvc`) -Forks current process into two processes, but they initialy share the address space until `exec()` or `exit()` calls are called. Parent process execution is suspended until `exec()` or `exit()` call as well. - -
+Forks current process into two processes, but they initialy share the address space until `exec()` or `exit()` calls are + called. Parent process execution is suspended until `exec()` or `exit()` call as well. ### `syscalls_procExec` (`syscalls_exec`) @@ -20,8 +17,6 @@ GETFROMSTACK(ustack, char **, argv, 1); GETFROMSTACK(ustack, char **, envp, 2); ```` -
- ### `syscalls_procSpawnSyspage` ````C @@ -30,8 +25,6 @@ GETFROMSTACK(ustack, char *, name, 1); GETFROMSTACK(ustack, char **, argv, 2); ```` -
- ### `syscalls_procSpawn` (`syscalls_sys_spawn`) ````C @@ -40,16 +33,12 @@ GETFROMSTACK(ustack, char **, argv, 1); GETFROMSTACK(ustack, char **, envp, 2); ```` -
- ### `syscalls_procExit` (`syscalls_sys_exit`) ````C GETFROMSTACK(ustack, int, code, 0); ```` -
- ### `syscalls_procWait` (`syscalls_sys_waitpid`) ````C @@ -58,20 +47,14 @@ GETFROMSTACK(ustack, int *, stat, 1); GETFROMSTACK(ustack, int, options, 2); ```` -
- ### `syscalls_procGetID` (`syscalls_getpid`) Returns current process identifier -
- ### `syscalls_procGetParentID` (`syscalls_getppid`) Returns parent process identifier -
- ### `syscalls_procSetGroupID` (`syscalls_sys_setpgid`) ````C @@ -79,24 +62,14 @@ GETFROMSTACK(ustack, pid_t, pid, 0); GETFROMSTACK(ustack, pid_t, pgid, 1); ```` -
- ### DEPRECATED `syscalls_sys_setpgrp` => `syscalls_procSetGroupID` -
- ### `syscalls_procGetGroupID` (`syscalls_sys_getpgid`) -
- ### DEPRECATED `syscalls_sys_getpgrp` => `syscalls_procGetGroupID` -
- ### `syscalls_procSetSession` (`syscalls_sys_setsid`) -
- ## See also 1. [System calls](README.md) diff --git a/kernel/syscalls/riscv.md b/kernel/syscalls/riscv.md index fb0d5d5f..3a438636 100644 --- a/kernel/syscalls/riscv.md +++ b/kernel/syscalls/riscv.md @@ -6,8 +6,6 @@ GETFROMSTACK(ustack, char, c, 0); ```` -
- ## `syscalls_sbiGetChar` (`syscalls_sbi_getchar`) ## See also diff --git a/kernel/syscalls/socket.md b/kernel/syscalls/socket.md index 9a657814..49edc27c 100644 --- a/kernel/syscalls/socket.md +++ b/kernel/syscalls/socket.md @@ -8,9 +8,8 @@ GETFROMSTACK(ustack, struct sockaddr *, address, 1); GETFROMSTACK(ustack, socklen_t *,address_len, 2); ```` -Accepts incomming connection on socket given by `socket`. Connection information is returned in variables `address` and `len`. - -
+Accepts incomming connection on socket given by `socket`. Connection information is returned in variables `address` and + `len`. ## `syscalls_sockAccept4` (`syscalls_sys_accept4`) @@ -21,9 +20,8 @@ GETFROMSTACK(ustack, socklen_t *,address_len, 2); GETFROMSTACK(ustack, int, flags, 3); ```` -
- ## `syscalls_sockBind` (`syscalls_sys_bind`) + ````C GETFROMSTACK(ustack, int, socket, 0); GETFROMSTACK(ustack, const struct sockaddr *, address, 1); @@ -64,7 +62,6 @@ GETFROMSTACK(ustack, const void *, optval, 3); GETFROMSTACK(ustack, socklen_t, optlen, 4); ```` - ## `syscalls_sockGetSockOpt` (`syscalls_sys_getsockopt`) ````C diff --git a/kernel/syscalls/sync.md b/kernel/syscalls/sync.md index dff9dbe3..3c442ec8 100644 --- a/kernel/syscalls/sync.md +++ b/kernel/syscalls/sync.md @@ -48,7 +48,9 @@ GETFROMSTACK(ustack, unsigned int, m, 1); GETFROMSTACK(ustack, time_t, timeout, 2); ```` -Waits on conditional given by 'h' for number of microseconds given by `timeout`. Before suspending a calling thread execution mutex identified by `m` handle is unlocked to enable other thread modifying variables used to check condtonals after conditional signalisation. When conditional variable is signaled mutex `m` is locked. +Waits on conditional given by 'h' for number of microseconds given by `timeout`. Before suspending a calling thread +execution mutex identified by `m` handle is unlocked to enable other thread modifying variables used to check condtonals +after conditional signalisation. When conditional variable is signaled mutex `m` is locked. libc wrapper: [int condWait(handle_t h, handle_t m, time_t timeout)](../../libc/functions/c/condWait.phrtos.md) diff --git a/kernel/syscalls/threads.md b/kernel/syscalls/threads.md index d90359af..a038e83c 100644 --- a/kernel/syscalls/threads.md +++ b/kernel/syscalls/threads.md @@ -11,24 +11,19 @@ GETFROMSTACK(ustack, void *, arg, 4); GETFROMSTACK(ustack, unsigned int *, id, 5); ```` -Starts thread from entry point given by `start` at priority defined by `priority`. Thread stack is defined by `stack` and `stacksz` arguments. Executed thread id is returned in `id` variable. - -
+Starts thread from entry point given by `start` at priority defined by `priority`. Thread stack is defined by `stack` +and `stacksz` arguments. Executed thread id is returned in `id` variable. ## `syscalls_threadDestroy` (`syscalls_endthread`) Terminates executing thread. -
- ## `syscalls_threadWait` (`syscalls_threadJoin`) ````C GETFROMSTACK(ustack, time_t, timeout, 0); ```` -
- ## `syscalls_threadSleep` (`syscalls_usleep`) ````C @@ -37,8 +32,6 @@ GETFROMSTACK(ustack, unsigned int, us, 0); Suspends thread execution for number of microseconds defined by `us`. -
- ## `syscalls_threadGetInfo` (`syscalls_threadinfo`) ````C @@ -48,22 +41,16 @@ GETFROMSTACK(ustack, threadinfo_t *, info, 1); Returns thread information `info` for thread given by `n`. -
- ## `syscalls_threadGetID` (`syscalls_gettid`) Returns identifier of calling thread. -
- ## `syscalls_threadSetPriority` (`syscalls_priority`) ````C GETFROMSTACK(ustack, int, priority, 0); ```` -
- ## See also 1. [System calls](README.md) diff --git a/kernel/vm/README.md b/kernel/vm/README.md index 2dfc52a4..13aa3e3b 100644 --- a/kernel/vm/README.md +++ b/kernel/vm/README.md @@ -1,30 +1,81 @@ # Memory management -Memory management is the most important part of any operating system kernel, as it has a great impact on the overall system performance and scalability. The main goal of the memory management is to provide physical memory for the purpose of kernel and running programs represented by processes. - -In most modern general-purpose operating systems, memory management is based on paging technique and the Memory Management Unit (MMU) is used. The MMU is available across many popular hardware architectures (e.g. IA32, x86-64, ARMv7 Cortex-A, RISC-V) and is used for translating the linear addresses used by programs executed on the processor core into the physical memory addresses. This translation is based on linear-physical address associations defined inside MMU which are specific for each running process allowing to separate them from each-other. The evolution of paging technique and current use of it in general purpose operating systems are briefly discussed in the further parts of this chapter. - -The assumption of use of paging technique as the basic method of accessing the memory for running processes is insufficient when operating system shall handle many hardware architectures starting from low-power microcontrollers and ending with advanced multi-core architectures with gigabytes of physical memory because MMU is available only on some of them. Moreover many modern architectures used for IoT device development and massively parallelized multi-core computers are equipped with a non-uniform physical memory (NUMA) with different access characteristics. For example in modern microcontrollers some physical memory segments can be tightly coupled with processor enabling to run real-time application demanding minimal jitter (e.g. for signal processing). On multi-core architectures some physical memory segment can by tightly coupled with particular set of processing cores while others segments can be accessible over switched buses what results in delayed access and performance degradation. Having this in mind in Phoenix-RTOS it was decided to redefine the traditional approach to memory management and some new memory management abstractions and mechanisms were proposed. These abstractions and mechanisms allow to unify the approach for memory management on many types of memory architectures. To understand the details and purpose of these mechanism memory hardware architecture issues are briefly discussed in this chapter before Phoenix-RTOS memory management functions are briefly presented. +Memory management is the most important part of any operating system kernel, as it has a great impact on the overall +system performance and scalability. The main goal of the memory management is to provide physical memory for the purpose + of kernel and running programs represented by processes. + +In most modern general-purpose operating systems, memory management is based on paging technique and the Memory +Management Unit (MMU) is used. The MMU is available across many popular hardware architectures (e.g. IA32, x86-64, ARMv7 +Cortex-A, RISC-V) and is used for translating the linear addresses used by programs executed on the processor core into +the physical memory addresses. This translation is based on linear-physical address associations defined inside MMU +which are specific for each running process allowing to separate them from each-other. The evolution of paging +technique and current use of it in general purpose operating systems are briefly discussed in the further parts of this +chapter. + +The assumption of use of paging technique as the basic method of accessing the memory for running processes is +insufficient when operating system shall handle many hardware architectures starting from low-power microcontrollers and +ending with advanced multi-core architectures with gigabytes of physical memory because MMU is available only on +some of them. Moreover many modern architectures used for IoT device development and massively parallelized multi-core +computers are equipped with a non-uniform physical memory (NUMA) with different access characteristics. For example in +modern microcontrollers some physical memory segments can be tightly coupled with processor enabling to run real-time +application demanding minimal jitter (e.g. for signal processing). On multi-core architectures some physical memory +segment can by tightly coupled with particular set of processing cores while others segments can be accessible over +switched buses what results in delayed access and performance degradation. Having this in mind in Phoenix-RTOS it was +decided to redefine the traditional approach to memory management and some new memory management abstractions and +mechanisms were proposed. These abstractions and mechanisms allow to unify the approach for memory management on many +types of memory architectures. To understand the details and purpose of these mechanism memory hardware architecture +issues are briefly discussed in this chapter before Phoenix-RTOS memory management functions are briefly presented. ## Paging technique and Memory Management Unit -Processors equipped with MMU are typically used in servers, personal computers and mobile devices such as tablets and smartphones. In this architecture, the linear addresses used by executed program are translated to physical memory addresses using MMU associated with the processor core. This translation is performed with a defined granulation and the piece of the linear address space used for translation to physical address is called a memory page. Typically, the page size used in modern systems varies from 4KB to gigabytes, but in the past, e.g. on the PDP-10, VAX-11 architectures, it was much smaller (512 or 1KB). - -MMU holds set of associations between linear and physical addresses defined for the process currently executed on the core. When process context is switched associations specific for the process are flushed from MMU and changed with associations defined for the new process chosen for execution. The structure used for defining these association is commonly and incorrectly called page table and stored in physical memory. On many architectures associations used for defining the linear address space are automatically downloaded to MMU when linear address is reached for the first time and association is not present in MMU. This task is performed by a part of MMU called Hardware Page Walker. On some architectures with simple MMU (e.g. eSI-RISC) the operating system define associations by controlling MMU directly using its registers. In this case page table structure depends on software. The role of the MMU in memory address translation is illustrated in the figure below. +Processors equipped with MMU are typically used in servers, personal computers and mobile devices such as tablets and +smartphones. In this architecture, the linear addresses used by executed program are translated to physical memory +addresses using MMU associated with the processor core. This translation is performed with a defined granulation and +the piece of the linear address space used for translation to physical address is called a memory page. Typically, the +page size used in modern systems varies from 4KB to gigabytes, but in the past, e.g. on the PDP-10, VAX-11 +architectures, it was much smaller (512 or 1KB). + +MMU holds set of associations between linear and physical addresses defined for the process currently executed on the +core. When process context is switched associations specific for the process are flushed from MMU and changed with +associations defined for the new process chosen for execution. The structure used for defining these association is +commonly and incorrectly called page table and stored in physical memory. On many architectures associations used for +defining the linear address space are automatically downloaded to MMU when linear address is reached for the first time +and association is not present in MMU. This task is performed by a part of MMU called Hardware Page Walker. On some +architectures with simple MMU (e.g. eSI-RISC) the operating system define associations by controlling MMU directly +using its registers. In this case page table structure depends on software. The role of the MMU in memory address +translation is illustrated in the figure below. -In the further considerations the linear address space defined using paging technique will be named synonymously as the virtual address space. +In the further considerations the linear address space defined using paging technique will be named synonymously as the +virtual address space. ### Initial concept of paging technique -The concept of paging was first introduced in the late 1960s in order to organize the program memory overlaying for hierarchical memory systems consisting of transistor-based memory, core memory, magnetic disks and tapes. Historically, the virtual address space size was comparable to the physical memory size. The page table was used to point to the data location in the hierarchical memory system and to associate the physical memory location, called a page frame, with the virtual page. When the program accessed the virtual page, processor checked whether the page was present in the physical memory via the presence bit in the page table. If the page was not present in the physical memory, the program execution was interrupted and the page was loaded by the operating system into the physical memory via additional bits defining the data location in the page table. Once the presence bit was successfully loaded and set, the program execution was resumed. The original paging technique is presented below. +The concept of paging was first introduced in the late 1960s in order to organize the program memory overlaying for +hierarchical memory systems consisting of transistor-based memory, core memory, magnetic disks and tapes. Historically, +the virtual address space size was comparable to the physical memory size. The page table was used to point to the data +location in the hierarchical memory system and to associate the physical memory location, called a page frame, with the +virtual page. When the program accessed the virtual page, processor checked whether the page was present in the physical +memory via the presence bit in the page table. If the page was not present in the physical memory, the program execution +was interrupted and the page was loaded by the operating system into the physical memory via additional bits defining +the data location in the page table. Once the presence bit was successfully loaded and set, the program execution was +resumed. The original paging technique is presented below. ### Current use of paging technique -Over the years, paging has morphed into a technique used for defining the process memory space and for process separation. In general-purpose operating systems, paging is fundamental for memory management. Each process runs in its own virtual memory space and uses all address ranges for their needs. The address space is defined by a set of virtual-to-physical address associations for the MMU defined in the physical memory and stored in a structure which is much more complicated than a page table used in early computers. This is necessary in order to optimize memory consumption and speed up the virtual-to-physical memory translations. When a process is executed on a selected processor, the address space is switched to its virtual space, which prevents it from interfering with other processes. The address space is switched by providing the MMU with new sets of virtual-to-physical associations. In this scheme, some physical pages (for example parts of the program text) can be shared among processes by mapping them simultaneously into two or more processes to minimize the overall memory usage. +Over the years, paging has morphed into a technique used for defining the process memory space and for process +separation. In general-purpose operating systems, paging is fundamental for memory management. Each process runs in its +own virtual memory space and uses all address ranges for their needs. The address space is defined by a set of +virtual-to-physical address associations for the MMU defined in the physical memory and stored in a structure which is +much more complicated than a page table used in early computers. This is necessary in order to optimize memory +consumption and speed up the virtual-to-physical memory translations. When a process is executed on a selected +processor, the address space is switched to its virtual space, which prevents it from interfering with other processes. +The address space is switched by providing the MMU with new sets of virtual-to-physical associations. In this scheme, +some physical pages (for example parts of the program text) can be shared among processes by mapping them simultaneously +into two or more processes to minimize the overall memory usage. @@ -32,19 +83,54 @@ A memory management system which relies on paging describes the whole physical m ## Direct physical memory access complemented with Memory Protection Unit or segmentation -Entry-level microcontrollers based on ARM Cortex-M architecture massively used in common electronics devices are typically equipped with embedded FLASH memories and tens of kilobytes of SRAM. Both FLASH and SRAM are accessible using the same address space. Because of small amount of RAM the MMU is useless and can lead to memory usage overhead. - -To provide separation of running processes and used by them physical memory the Memory Protection Unit is used. Memory Protection Unit takes part in memory addressing and typically allows to partition memory access by defining set of segments which can be used during the program execution. The number of these segments is usually limited (4, 8, 16). The access to defined memory segments can be even associated with processor execution mode, so program executed in supervisor mode can operate on more segments then when it is executed in user mode. Processor execution modes and methods of transitioning between them have been Discussed in chapter [Processes and threads](proc/README.md). - -There are two strategies of using MPU and memory segmentation. First and more flexible is strategy of switching whole MPU context when process context is switched. This demands to reload of all segments defined by MPU for the executed process with the new set defined for the newly chosen process. The big advantage of this technique is that processes are strictly separated because each of them uses its own set of user segments and shares the privileged segments (e.g. kernel segments). There are two disadvantages of this technique caused by typical MPU limitations. The process of redefining segments is slow because it requires the invalidation of cache memories. The method of defining segments in MPU is limited because segment address and size definition depends on chosen granulation. For example some segments can be defined only if all set of MPU registers is used. - -The second strategy, used in Phoenix-RTOS, is based on memory regions/segments defined for the whole operating system and shared between processes. It means that processes can use during its execution few assigned predefined memory regions called further memory maps. These regions are defined during operating system bootstrap with respect of MPU register semantics and can be inline with physical memory characteristic. For example separate regions can be defined for TCM (Tightly Coupled Memory) with short access time and separate regions can be defined for cached RAM. The set of regions assigned to the process is defined during process start-up. When a process context is switched the proper process set of MPU definition is activated using enable/disable bits. This can be done much faster in comparison to reloading the whole region definitions. The main disadvantage of described approach is the limited number of regions which can be used by running processes. This results in a weaker separation of running processes because they must use shared memory regions and erroneous thread of one process can destroy data in another process sharing the same memory region. But it should be emphasized that this technique complemented with proper definition of memory regions can allow to fullfil safety requirements of many types of applications e.g. applications based on software partitioning into two parts with different safety requirements. - -Discussion of techniques used for protecting memory when direct physical memory access is used should be complemented by presentation of memory segmentation mechanisms popularized widely by x86 microprocessors. The segmentation technique was developed on early computers to simplify the program loading and execution process. When a process is to be executed, its corresponding segmentation are loaded into non-contiguous memory though every segment is loaded into a contiguous block of available memory. The location of program segments in physical memory is defined by special set of processor registers called segment registers and processor instructions are using offsets calculated according to segment base addresses. This technique prevents from using relocation/recalculation of program addresses after it is loaded to memory and before its execution is started. This technique was heavily extended in second generation of x86 processors (80286) by adding the ability to define segments attributes, limits and privilege levels. This technique of processes separation was used on some early operating system for PC like MS Windows 3.0 and IBM OS/2. Nowadays it has been replaced with paging. +Entry-level microcontrollers based on ARM Cortex-M architecture massively used in common electronics devices are +typically equipped with embedded FLASH memories and tens of kilobytes of SRAM. Both FLASH and SRAM are accessible using +the same address space. Because of small amount of RAM the MMU is useless and can lead to memory usage overhead. + +To provide separation of running processes and used by them physical memory the Memory Protection Unit is used. Memory +Protection Unit takes part in memory addressing and typically allows to partition memory access by defining set of +segments which can be used during the program execution. The number of these segments is usually limited (4, 8, 16). The +access to defined memory segments can be even associated with processor execution mode, so program executed in +supervisor mode can operate on more segments then when it is executed in user mode. Processor execution modes and +methods of transitioning between them have been Discussed in chapter [Processes and threads](proc/README.md). + +There are two strategies of using MPU and memory segmentation. First and more flexible is strategy of switching whole +MPU context when process context is switched. This demands to reload of all segments defined by MPU for the executed +process with the new set defined for the newly chosen process. The big advantage of this technique is that processes are +strictly separated because each of them uses its own set of user segments and shares the privileged segments +(e.g. kernel segments). There are two disadvantages of this technique caused by typical MPU limitations. The process of +redefining segments is slow because it requires the invalidation of cache memories. The method of defining segments in +MPU is limited because segment address and size definition depends on chosen granulation. For example some segments can +be defined only if all set of MPU registers is used. + +The second strategy, used in Phoenix-RTOS, is based on memory regions/segments defined for the whole operating system +and shared between processes. It means that processes can use during its execution few assigned predefined memory +regions called further memory maps. These regions are defined during operating system bootstrap with respect of MPU +register semantics and can be inline with physical memory characteristic. For example separate regions can be defined +for TCM (Tightly Coupled Memory) with short access time and separate regions can be defined for cached RAM. The set of +regions assigned to the process is defined during process start-up. When a process context is switched the proper +process set of MPU definition is activated using enable/disable bits. This can be done much faster in comparison to +reloading the whole region definitions. The main disadvantage of described approach is the limited number of regions +which can be used by running processes. This results in a weaker separation of running processes because they must use +shared memory regions and erroneous thread of one process can destroy data in another process sharing the same memory +region. But it should be emphasized that this technique complemented with proper definition of memory regions can allow +to fullfil safety requirements of many types of applications e.g. applications based on software partitioning into two +parts with different safety requirements. + +Discussion of techniques used for protecting memory when direct physical memory access is used should be complemented by +presentation of memory segmentation mechanisms popularized widely by x86 microprocessors. The segmentation technique was +developed on early computers to simplify the program loading and execution process. When a process is to be executed, +its corresponding segmentation are loaded into non-contiguous memory though every segment is loaded into a contiguous +block of available memory. The location of program segments in physical memory is defined by special set of processor +registers called segment registers and processor instructions are using offsets calculated according to segment base +addresses. This technique prevents from using relocation/recalculation of program addresses after it is loaded to memory +and before its execution is started. This technique was heavily extended in second generation of x86 processors (80286) +by adding the ability to define segments attributes, limits and privilege levels. This technique of processes separation +was used on some early operating system for PC like MS Windows 3.0 and IBM OS/2. Nowadays it has been replaced with +paging. ## Non-uniform memory access - ## Memory management subsystem structure Memory management subsystem provides following functionalities: @@ -59,31 +145,51 @@ These functions will be briefly discussed and elaborated more in the particular ### Physical memory allocation -Physical memory allocation is the lowest level of the memory management subsystem. It is used to provide memory for the purposes of kernel or mapped object. The are two ways of obtaining physical memory depending on the type of hardware memory architectures. When paging technique is used the memory is allocated using physical memory pages (page frames). On architecture with direct physical memory access the physical memory is allocated using address space allocation in the particular memory map. It is planned to generalize these techniques in the next version of Phoenix-RTOS memory management subsystem. To understand the physical memory allocation algorithm on architectures using paging technique please refer to [Physical memory allocation using memory pages](page.md). To understand the physical memory allocation algorithm on architectures with direct memory access please refer to [Physical memory allocation](phys.md). +Physical memory allocation is the lowest level of the memory management subsystem. It is used to provide memory for the +purposes of kernel or mapped object. The are two ways of obtaining physical memory depending on the type of hardware +memory architectures. When paging technique is used the memory is allocated using physical memory pages (page frames). +On architecture with direct physical memory access the physical memory is allocated using address space allocation in +the particular memory map. It is planned to generalize these techniques in the next version of Phoenix-RTOS memory +management subsystem. To understand the physical memory allocation algorithm on architectures using paging technique +please refer to [Physical memory allocation using memory pages](page.md). To understand the physical memory allocation +algorithm on architectures with direct memory access please refer to [Physical memory allocation](phys.md). ### Memory mapper -When the page allocator allocates a set of pages, the set must be mapped into an address space to be accessible. The memory address space is managed by the next memory management layer, i.e. the memory mapper. The memory mapper uses a memory map structures to describe memory segments located in address spaces. In MMU architectures, each process owns a separate memory map, and there is one kernel memory map defining the kernel address space. In non-MMU architectures, there is only one map shared by all processes and the kernel. +When the page allocator allocates a set of pages, the set must be mapped into an address space to be accessible. +The memory address space is managed by the next memory management layer, i.e. the memory mapper. The memory mapper uses +a memory map structures to describe memory segments located in address spaces. In MMU architectures, each process owns +a separate memory map, and there is one kernel memory map defining the kernel address space. In non-MMU architectures, +there is only one map shared by all processes and the kernel. ### Hardware dependent layer (pmap) -The `pmap` abstraction constitutes the lowest level of the memory management implemented in the HAL. This abstraction implements an interface for managing the MMU and hides hardware details from the upper layers. Its most important function is the `pmap_enter()`, which is used for mapping the page into the process virtual address space. - - - +The `pmap` abstraction constitutes the lowest level of the memory management implemented in the HAL. This abstraction +implements an interface for managing the MMU and hides hardware details from the upper layers. Its most important +function is the `pmap_enter()`, which is used for mapping the page into the process virtual address space. ### Kernel fine-grained allocator -These two abstractions allow for memory allocation based on the needs of the kernel and processes with the resolution of page size. Such resolution is too large for dynamic allocation of kernel structures and could result in internal memory fragmentation and memory wasting. To omit these problems, zone allocator and fine-grained allocator are developed. They constitute the next layers of the memory management subsystem. + +These two abstractions allow for memory allocation based on the needs of the kernel and processes with the resolution of +page size. Such resolution is too large for dynamic allocation of kernel structures and could result in internal memory +fragmentation and memory wasting. To omit these problems, zone allocator and fine-grained allocator are developed. They +constitute the next layers of the memory management subsystem. ### Memory objects -First introduced in the Mach operating system, a memory object defines an entity containing data which could be partially or completely loaded into the memory and mapped into one or more address spaces. A good example of this is a binary object representing the program image (e.g. `/bin/sh`). -Memory objects were introduced so that processes could share physical memory; they allow for identifying and defining sets of memory pages or segments of physical memory in non-MMU architectures. When one process maps an object into its memory map, the object occupies some physical pages. When another process uses the same object, the same pages (in the case of a read-only mapping) or their copies (in the case of a write mapping) are mapped. +First introduced in the Mach operating system, a memory object defines an entity containing data which could be +partially or completely loaded into the memory and mapped into one or more address spaces. A good example of this is a +binary object representing the program image (e.g. `/bin/sh`). +Memory objects were introduced so that processes could share physical memory; they allow for identifying and defining +sets of memory pages or segments of physical memory in non-MMU architectures. When one process maps an object into its +memory map, the object occupies some physical pages. When another process uses the same object, the same pages (in the +case of a read-only mapping) or their copies (in the case of a write mapping) are mapped. ## Implementation structure -The memory management subsystem is located in the `src/vm` subdirectory. The lowest `pmap` layer is implemented in the HAL. +The memory management subsystem is located in the `src/vm` subdirectory. The lowest `pmap` layer is implemented in +the HAL. ## Chapter information diff --git a/kernel/vm/kmalloc.md b/kernel/vm/kmalloc.md index 928cc070..d7784637 100644 --- a/kernel/vm/kmalloc.md +++ b/kernel/vm/kmalloc.md @@ -1,24 +1,36 @@ # Fine grained allocator -Fine grained allocator implemented by `vm_kmalloc()` function is the main method of dynamic memory allocation used by the Phoenix-RTOS kernel. The operating system kernel uses dynamic data structures to manage dynamic data structures created during the operating system runtime (e.g. process descriptors, threads descriptors, ports). Size of these structure varies from few bytes to tens of kilobytes. The allocator is able to allocate either the group of memory pages and to manage the fragments allocated within the page. +Fine grained allocator implemented by `vm_kmalloc()` function is the main method of dynamic memory allocation used by +the Phoenix-RTOS kernel. The operating system kernel uses dynamic data structures to manage dynamic data structures +created during the operating system runtime (e.g. process descriptors, threads descriptors, ports). Size of these +structure varies from few bytes to tens of kilobytes. The allocator is able to allocate either the group of memory pages +and to manage the fragments allocated within the page. ## Architecture Fine grained allocator is based on zone allocator. The architecture is presented on the following picture. -Main allocator data structure is `sizes[]` table. Table entries points to list of zone allocators consisting fragments with sizes proportional to the entry number. Fragments have sizes equal to `2^e` where `e` is the entry number. +Main allocator data structure is `sizes[]` table. Table entries points to list of zone allocators consisting fragments +with sizes proportional to the entry number. Fragments have sizes equal to `2^e` where `e` is the entry number. ## Memory allocation -The first step of allocation process is the calculation of entry number. The best fit strategy is used, so the requested size is rounded to the nearest power of two. After calculating the entry number the fragment is allocated from the first zone associated with the entry number. +The first step of allocation process is the calculation of entry number. The best fit strategy is used, so the requested +size is rounded to the nearest power of two. After calculating the entry number the fragment is allocated from the first +zone associated with the entry number. -If the selected entry is empty and there is no empty zones associated with the entry, the new zone is created and added to the list. New zone is added either to `sizes[]` table and to the zone RB-tree. The zone RB-tree is used to find the proper zone when a fragment is released. +If the selected entry is empty and there is no empty zones associated with the entry, the new zone is created and added +to the list. New zone is added either to `sizes[]` table and to the zone RB-tree. The zone RB-tree is used to find the +proper zone when a fragment is released. -If the allocated fragment is the last free fragment from the zone, the zone is removed from the entry zone list and is linked with the used zones list. +If the allocated fragment is the last free fragment from the zone, the zone is removed from the entry zone list and is +linked with the used zones list. ## Memory deallocation -When fragment is deallocated the first step is to find proper zone based on its virtual address. The zone RB-tree is searched. When zone is established the fragment is released using `vm_zfree()` call and returned to the zone. When zone is empty it is released and allocated memory is returned to the operating system pool. +When fragment is deallocated the first step is to find proper zone based on its virtual address. The zone RB-tree is +searched. When zone is established the fragment is released using `vm_zfree()` call and returned to the zone. When zone +is empty it is released and allocated memory is returned to the operating system pool. ## See also diff --git a/kernel/vm/mapper.md b/kernel/vm/mapper.md index 81a846ad..c80090da 100644 --- a/kernel/vm/mapper.md +++ b/kernel/vm/mapper.md @@ -1,12 +1,22 @@ # Memory mapper -After memory pages are allocated, they must be mapped into the process or kernel address space so that the memory can be used by the kernel or user processes. A memory mapper is a part of memory management system which is responsible for this process and manages the available address space. +After memory pages are allocated, they must be mapped into the process or kernel address space so that the memory can be +used by the kernel or user processes. A memory mapper is a part of memory management system which is responsible for +this process and manages the available address space. -In non-MMU architectures, the kernel and user processes share the same address space. In architectures with a paged memory, address spaces are separated but the kernel is mapped into each of them. The kernel mapping is shared among the processes, using specific features of virtual-to-physical address resolution. To illustrate, the IA32 architecture’s MMU uses two-level page tables: after the kernel is initialized, all kernel page tables are created on the second level and used by the first level page tables, created during process creation. +In non-MMU architectures, the kernel and user processes share the same address space. In architectures with a paged +memory, address spaces are separated but the kernel is mapped into each of them. The kernel mapping is shared among the +processes, using specific features of virtual-to-physical address resolution. To illustrate, the IA32 architecture’s MMU +uses two-level page tables: after the kernel is initialized, all kernel page tables are created on the second level and +used by the first level page tables, created during process creation. ## Memory map -A memory map (`vm_map_t` structure) is the main structure used for describing the address space. Built using the red-black tree structure, the memory map stores entries (`map_entry_t`) which describe the memory segments. The memory map belongs both to the kernel and processes. In non-MMU architectures, the kernel and processes share the same memory map. In MMU architectures, each process has its own separate memory map defining the user mappings. The kernel uses a separate memory map which describes the parts of the address space which belong to the kernel. +A memory map (`vm_map_t` structure) is the main structure used for describing the address space. Built using the +red-black tree structure, the memory map stores entries (`map_entry_t`) which describe the memory segments. The memory +map belongs both to the kernel and processes. In non-MMU architectures, the kernel and processes share the same memory +map. In MMU architectures, each process has its own separate memory map defining the user mappings. The kernel uses a +separate memory map which describes the parts of the address space which belong to the kernel. The map definition and its entry is presented below. @@ -19,7 +29,9 @@ The map definition and its entry is presented below. } vm_map_t; ``` -The `start`, `stop` attributes define the beginning and ending of the address space described by the map. The `pmap` attribute defines the `pmap` structure encapsulating the hardware-dependent structures used by the MMU for address resolution. The tree attribute stores the red-black tree of map entries. +The `start`, `stop` attributes define the beginning and ending of the address space described by the map. The `pmap` +attribute defines the `pmap` structure encapsulating the hardware-dependent structures used by the MMU for address +resolution. The tree attribute stores the red-black tree of map entries. ```c typedef struct _map_entry_t { @@ -39,7 +51,13 @@ The `start`, `stop` attributes define the beginning and ending of the address sp } map_entry_t; ``` -Each `map_entry_t` constitutes a tree node (the `linkage` field) and the tree is constructed on the basis of the virtual address value (`vaddr`). The virtual address points to the segment address. It is complemented by the segment size, segment attributes and two special attributes: `rmaxgap` and `lmaxgap`, which store the size of the maximum gap between the segments in the left or right subtree of the current node. The segment attributes are defined by the `flags` field. The `object` field points to the object mapped into the address space. The `NULL` value of this field contains the information that mapping is anonymous (no object is mapped). The offset (`offs`) defines the in-object location of the data which should be copied into the memory. +Each `map_entry_t` constitutes a tree node (the `linkage` field) and the tree is constructed on the basis of the virtual +address value (`vaddr`). The virtual address points to the segment address. It is complemented by the segment size, +segment attributes and two special attributes: `rmaxgap` and `lmaxgap`, which store the size of the maximum gap between +the segments in the left or right subtree of the current node. The segment attributes are defined by the `flags` field. +The `object` field points to the object mapped into the address space. The `NULL` value of this field contains the +information that mapping is anonymous (no object is mapped). The offset (`offs`) defines the in-object location of the +data which should be copied into the memory. ### Understanding the map tree representation @@ -47,13 +65,28 @@ The figure below briefly presents the idea behind describing the address space w -The sample tree presented in the figure above will help you better understand the map structure. The root node points to the segment located approximately in the middle of the address space described by the map (the address range is defined by the `start`, `stop` attributes). The maximum gap in the left subtree is the gap marked with green color. The maximum gap in the right subtree is the gap marked with dark purple. The left child of the root node points to the segment in the middle of the left (lower) half of the address space. The right child of the root node points to the segment located in the middle of the right (upper) half of the address space. In the right subtree, where the right child of the map root node constitutes the root node, the maximum left gap is marked with dark blue. The maximum right gap for this subtree is marked with dark purple. A similar analysis may be performed for the other parts of the tree. +The sample tree presented in the figure above will help you better understand the map structure. The root node points to +the segment located approximately in the middle of the address space described by the map (the address range is defined +by the `start`, `stop` attributes). The maximum gap in the left subtree is the gap marked with green color. The maximum +gap in the right subtree is the gap marked with dark purple. The left child of the root node points to the segment in +the middle of the left (lower) half of the address space. The right child of the root node points to the segment located +in the middle of the right (upper) half of the address space. In the right subtree, where the right child of the map +root node constitutes the root node, the maximum left gap is marked with dark blue. The maximum right gap for this +subtree is marked with dark purple. A similar analysis may be performed for the other parts of the tree. ## Mapping algorithm -Page mapping is performed using the `_map_find()` function. The function tries to find the first suitable address for the mapping which is greater than the address specified as the argument and closest to it. The right maximum gap and the left maximum gap attributes are used for this operation so as to achieve a logarithmic algorithm complexity. The other argument provided for this function is a page set, obtained during page allocation. The function returns the nearest left and right neighbor entries. The returned entries are used to check whether the mapping is performed for the same object as the left and right neighbors. If the left or right neighbor attributes are the same as the required mapping attributes, and the mapping is performed for the same object as the left or right neighbors, the left or right entry is expanded respectively and no new entry is inserted into the tree. +Page mapping is performed using the `_map_find()` function. The function tries to find the first suitable address for +the mapping which is greater than the address specified as the argument and closest to it. The right maximum gap and the +left maximum gap attributes are used for this operation so as to achieve a logarithmic algorithm complexity. The other +argument provided for this function is a page set, obtained during page allocation. The function returns the nearest +left and right neighbor entries. The returned entries are used to check whether the mapping is performed for the same +object as the left and right neighbors. If the left or right neighbor attributes are the same as the required mapping +attributes, and the mapping is performed for the same object as the left or right neighbors, the left or right entry is +expanded respectively and no new entry is inserted into the tree. -The mapping algorithm is presented below. Due to its complexity, it will be discussed step by step: a fragment of the code is followed by an explanation of each step. +The mapping algorithm is presented below. Due to its complexity, it will be discussed step by step: a fragment of the +code is followed by an explanation of each step. ```c void *_map_find(vm_map_t *map, void *vaddr, size_t size, map_entry_t **prev, map_entry_t **next) @@ -88,7 +121,8 @@ The address of the mapping is checked according to the map range. } ``` -The mapping address and sizes are compared with the left child of the node. If the address is less than the address of the current node and there is a space for the mapping, the left child is selected for the next iteration. +The mapping address and sizes are compared with the left child of the node. If the address is less than the address of +the current node and there is a space for the mapping, the left child is selected for the next iteration. ```c if (size <= e->rmaxgap) { @@ -116,7 +150,8 @@ If the mapping address is not less than the address of the current node, the tre e = lib_treeof(map_entry_t, linkage, e->linkage.parent); ``` -If we get lost in the tree (the mapping address should be decreased to fulfill the size requirement), the tree is traversed up until the right child with a proper maximum gap is found. +If we get lost in the tree (the mapping address should be decreased to fulfill the size requirement), the tree is +traversed up until the right child with a proper maximum gap is found. ```c for (*next = e; (*next)->linkage.parent != &nil; @@ -127,7 +162,9 @@ If we get lost in the tree (the mapping address should be decreased to fulfill t *next = lib_treeof(map_entry_t, linkage, (*next)->linkage.parent); ``` -When we find a new node from which we should move to the right, the right neighbor is established. The tree is traversed starting from the parent of the new node until the node representing the right becomes the left child. In this case, the right neighbor is the parent of this node. +When we find a new node from which we should move to the right, the right neighbor is established. The tree is traversed +starting from the parent of the new node until the node representing the right becomes the left child. In this case, +the right neighbor is the parent of this node. ```c *prev = e; @@ -142,7 +179,8 @@ The left neighbor points to the new node. e = lib_treeof(map_entry_t, linkage, e->linkage.right); ``` -The tree is traversed to the right, starting from the new node. If the new node does not have the right child, the mapping is performed after the new node. +The tree is traversed to the right, starting from the new node. If the new node does not have the right child, the +mapping is performed after the new node. ```c } @@ -170,13 +208,19 @@ There is a dependency problem with memory mappings. ## Object mapping function -It is not possible to map pages directly into the process address space on the user level. Instead, there is mechanism for mapping objects which is based on page mapping. See the next sections for a description of objects and related mechanisms. +It is not possible to map pages directly into the process address space on the user level. Instead, there is mechanism +for mapping objects which is based on page mapping. See the next sections for a description of objects and related +mechanisms. -The `vm_mmap()` function maps object into the address space starting from address specified as function argument. Other function arguments define the size of the mapping, the attributes of the finally created memory segment, the object handle and flags determining the function behavior. If fixed mapping is specified in the flags argument mapping tries to map object at specified address. If address range of requested mapping overlaps with existing mapping the function will fail. +The `vm_mmap()` function maps object into the address space starting from address specified as function argument. Other +function arguments define the size of the mapping, the attributes of the finally created memory segment, the object +handle and flags determining the function behavior. If fixed mapping is specified in the flags argument mapping tries +to map object at specified address. If address range of requested mapping overlaps with existing mapping the function +will fail. ### Memory regions -A NUMA machine has different memory controllers with different distances to specific CPUs. +A NUMA machine has different memory controllers with different distances to specific CPUs. ## See also diff --git a/kernel/vm/objects.md b/kernel/vm/objects.md index f44bf936..ef0b7565 100644 --- a/kernel/vm/objects.md +++ b/kernel/vm/objects.md @@ -1,88 +1,176 @@ # Objects -Memory objects were introduced to share the physical memory between processes allowing to identifying the sets of allocated memory pages or segments of physical memory on non-MMU architectures. When process maps object into its memory space kernel allocates physical memory for the objects data and copies it from the backing storage (e.g. filesystem). When other process maps the same object into its address space the most of already allocated memory for the object purposes can be shared. Only the memory for local in-process modifications should be allocated. The technique used for allocating the memory for the purposes of in-process object modifications when the write access is performed is known as copy-on-write. It is based on some features of MMU or segment management unit -Memory objects are used to optimize the memory usage. They are also used as the basis for shared libraries. The shared libraries are the libraries loaded during the process execution. They are loaded using object mapping technique, what result that only one library code instance exists in memory. Library data segments are allocated using copy-on-write technique. To use the shared library in the process context the dynamic linking should be performed. +Memory objects were introduced to share the physical memory between processes allowing to identifying the sets of +allocated memory pages or segments of physical memory on non-MMU architectures. When process maps object into its memory +space kernel allocates physical memory for the objects data and copies it from the backing storage (e.g. filesystem). +When other process maps the same object into its address space the most of already allocated memory for the object +purposes can be shared. Only the memory for local in-process modifications should be allocated. The technique used for +allocating the memory for the purposes of in-process object modifications when the write access is performed is known as +copy-on-write. It is based on some features of MMU or segment management unit -Memory objects were introduced in Mach operating system. They were quickly derived from it and implemented in UN*X BSD and other operating systems. The Mach and BSD implementations were not optimal because of the way of implementation of copy-on-write strategy when processes are forked. This problem was solved by BSD UVM memory management subsystem by introducing the anonymous mapping abstraction. +Memory objects are used to optimize the memory usage. They are also used as the basis for shared libraries. The shared +libraries are the libraries loaded during the process execution. They are loaded using object mapping technique, what +result that only one library code instance exists in memory. Library data segments are allocated using copy-on-write +technique. To use the shared library in the process context the dynamic linking should be performed. -This chapter briefly presents memory objects idea and the memory objects architecture supported by Phoenix-RTOS microkernel. +Memory objects were introduced in Mach operating system. They were quickly derived from it and implemented in UN*X BSD +and other operating systems. The Mach and BSD implementations were not optimal because of the way of implementation of +copy-on-write strategy when processes are forked. This problem was solved by BSD UVM memory management subsystem by +introducing the anonymous mapping abstraction. + +This chapter briefly presents memory objects idea and the memory objects architecture supported by Phoenix-RTOS +microkernel. ## Understanding the process address space -Process’s address space is constituted by set of mapped objects. In traditional operating system memory objects correspond with files or devices (and are identified by `vnode`, `inode` etc.) or with anonymous objects representing the dynamically allocated physical memory. The are two strategies of retrieving object data into the process memory – immediate retrieval strategy when object is mapped (e.g. during process start) and lazy on-demand retrieval strategy when virtual page is first-time accessed during the runtime. +Process’s address space is constituted by set of mapped objects. In traditional operating system memory objects +correspond with files or devices (and are identified by `vnode`, `inode` etc.) or with anonymous objects representing +the dynamically allocated physical memory. The are two strategies of retrieving object data into the process memory – +immediate retrieval strategy when object is mapped (e.g. during process start) and lazy on-demand retrieval strategy +when virtual page is first-time accessed during the runtime. -The process address space in the traditional operating system (e.g. BSD) is graphically presented on following picture. Black circles represent pages allocated for the object purposes, holding the object data. +The process address space in the traditional operating system (e.g. BSD) is graphically presented on following picture. +Black circles represent pages allocated for the object purposes, holding the object data. -The first memory segment is constituted by the data from `/bin/process` file. It is mapped as the text, so it means that it is marked as readable and executable. - -The segment located right after the `text` segment is linked with data from the same file, but it’s marked as data (readable and writable). The following segment is `bss` holding the uninitialized process data. This segment is associated with anonymous object. The anonymous object is the special object allocated by memory management subsystem for storing the process data created during the process load or the process execution. The `bss` segment is marked as readable and writable. At the end of user address space exist the last data segment named as `stack`. This is the process stack (stack used by the main thread). As well as `bss` and `heap` segments it is connected with anonymous object. After the stack kernel segments are mapped. These segments are inaccessible when the thread runs on the user-level. When control is transferred explicitly to the kernel via the system call or implicitly via interrupt, the executed program is able to access this memory. The described mechanism of separation of the kernel from user memory is the basic mechanism constituting the operating system security and reliability and preventing the interference between the operating system and processes. +The first memory segment is constituted by the data from `/bin/process` file. It is mapped as the text, so it means that +it is marked as readable and executable. + +The segment located right after the `text` segment is linked with data from the same file, but it’s marked as data +(readable and writable). The following segment is `bss` holding the uninitialized process data. This segment is +associated with anonymous object. The anonymous object is the special object allocated by memory management subsystem +for storing the process data created during the process load or the process execution. The `bss` segment is marked as +readable and writable. At the end of user address space exist the last data segment named as `stack`. This is the +process stack (stack used by the main thread). As well as `bss` and `heap` segments it is connected with anonymous +object. After the stack kernel segments are mapped. These segments are inaccessible when the thread runs on the +user-level. When control is transferred explicitly to the kernel via the system call or implicitly via interrupt, +the executed program is able to access this memory. The described mechanism of separation of the kernel from user memory +is the basic mechanism constituting the operating system security and reliability and preventing the interference +between the operating system and processes. The process address space in Phoenix-RTOS is presented on the following figure. -In Phoenix-RTOS objects are supported by operating system servers and are referenced by `oid` identifiers. Each `oid` consists of server communication port number and in-server object identifier. If object is accessed within the process the memory management subsystem allocates the new page and asks the server identified by `oid` for the data. The data is retrieved from the server by sending the proper messages and are stored in the allocated page and mapped into the process at requested virtual address. - -The main difference between the monolithic kernel approach and Phoenix-RTOS is that memory segments correspond to objects identified by oids (port and in-server id) handled by external servers, so operating system kernel is free of file abstraction. This allows to maintain the small size of kernel and emulate many file sharing and inheritance strategies on the user level (POSIX, Windows etc.) or event to create the final operating system lacked of filesystem abstraction. +In Phoenix-RTOS objects are supported by operating system servers and are referenced by `oid` identifiers. Each `oid` +consists of server communication port number and in-server object identifier. If object is accessed within the process +the memory management subsystem allocates the new page and asks the server identified by `oid` for the data. The data is +retrieved from the server by sending the proper messages and are stored in the allocated page and mapped into the +process at requested virtual address. +The main difference between the monolithic kernel approach and Phoenix-RTOS is that memory segments correspond to +objects identified by oids (port and in-server id) handled by external servers, so operating system kernel is free of +file abstraction. This allows to maintain the small size of kernel and emulate many file sharing and inheritance +strategies on the user level (POSIX, Windows etc.) or event to create the final operating system lacked of filesystem +abstraction. ## Memory objects in Mach/BSD operating systems -To understand the memory objects idea let’s analyze the traditional approach implemented in Mach/BSD operating systems. The structure of Mach/BSD memory subsystem in the process context is presented on the following figure. +To understand the memory objects idea let’s analyze the traditional approach implemented in Mach/BSD operating systems. +The structure of Mach/BSD memory subsystem in the process context is presented on the following figure. -The process virtual address space is described by `vmspace` structure holding the list of memory maps (user and kernel map) . Each map stores entries defining the segment addresses, attributes and linked with particular memory objects. +The process virtual address space is described by `vmspace` structure holding the list of memory maps +(user and kernel map) . Each map stores entries defining the segment addresses, attributes and linked with +particular memory objects. -The additional important structure defined within the process is `pmap`. It is defined in HAL layer and holds all hardware dependent data used for virtual address translation (e.g. pointers to page directories, tables, address space identifier ASID etc.). +The additional important structure defined within the process is `pmap`. It is defined in HAL layer and holds all +hardware dependent data used for virtual address translation (e.g. pointers to page directories, tables, address +space identifier ASID etc.). -Each object stores physical pages allocated to preserve object data in physical memory (black circles). As it was mentioned before object are identified by vnodes (filesystem pointers) or can exist only in the memory management subsystem as anonymous objects. +Each object stores physical pages allocated to preserve object data in physical memory (black circles). As it was +mentioned before object are identified by vnodes (filesystem pointers) or can exist only in the memory management +subsystem as anonymous objects. -Each memory object on the system has a pager that points to a list of functions used by the object to fetch and store pages between physical memory and backing store. Pages are read in from backing store when a process requires them (immediately or in case of page fault when lazy on-demand strategy is in use). Pages are written out to backing store at the request of a program (e.g., via the `msync` system call), when physical memory is scarce when process is swapped out , or when the object that owns the pages is freed. +Each memory object on the system has a pager that points to a list of functions used by the object to fetch and store +pages between physical memory and backing store. Pages are read in from backing store when a process requires them +(immediately or in case of page fault when lazy on-demand strategy is in use). Pages are written out to backing store +at the request of a program (e.g., via the `msync` system call), when physical memory is scarce when process is swapped +out , or when the object that owns the pages is freed. ### Shadow objects used for copy-on-write (BSD VM) -The BSD VM system manages copy-on-write mappings of memory objects by using shadow objects. A shadow object is an anonymous memory object that contains the modified pages of a copy-on-write mapped memory object. The map entry mapping a copy-on-write area of memory points to the shadow object allocated for it. Shadow objects point to the object they are shadowing. When searching for pages in a copy-on-write mapping, the shadow object pointed to by the map entry is searched first. If the desired page is not present in the shadow object, then the underlying object is searched. The underlying object may either be a file object or another shadow object. The search continues until the desired page is found, or there are no more underlying objects. The list of objects that connect a copy-on-write map entry to the bottom-most object is called a shadow object chain. +The BSD VM system manages copy-on-write mappings of memory objects by using shadow objects. A shadow object is an +anonymous memory object that contains the modified pages of a copy-on-write mapped memory object. The map entry mapping +a copy-on-write area of memory points to the shadow object allocated for it. Shadow objects point to the object they are +shadowing. When searching for pages in a copy-on-write mapping, the shadow object pointed to by the map entry is +searched first. If the desired page is not present in the shadow object, then the underlying object is searched. The +underlying object may either be a file object or another shadow object. The search continues until the desired page is +found, or there are no more underlying objects. The list of objects that connect a copy-on-write map entry to the +bottom-most object is called a shadow object chain. The following figure shows how shadow object chains are formed in BSD VM. - -A three-page file object is copy-on-write memory mapped into a process’ address space. The first column shows the first step of memory mappings. The new entry with the needs-copy and copy-on-write flags is allocated. It points the underlying object. Once a write fault occurs, a new memory object is created and that object tracks all the pages that have been copied and modified. - -The second column shows what happens when the process writes to the middle page of the object. Since the middle page is either unmapped or mapped read-only, writing to it triggers a page fault. The fault routine looks up the appropriate map entry and notes that it is a needs-copy copy-on-write mapping. It first clears needs-copy by allocating a shadow object and inserting it between the map entry and the underlying object. Then it copies the data from the middle page of the backing object into a new page that is inserted into the shadow object. The shadow object’s page can then be mapped read-write into the faulting process’ address space. - -The third column shows the BSD VM data structures after the process with the copy-on-write mapping forks a child, the parent writes to the middle page, and the child writes to the right-hand page. When the parent forks, the child receives a copy-on-write copy of the parent’s mapping. This is done by write protecting the parent’s mappings and setting needs-copy in both processes. When the parent faults on the middle page, a second shadow object is allocated for it and inserted on top of the first shadow object. When the child faults on the right-hand page the same thing happens, resulting in the allocation of a third shadow object. +A three-page file object is copy-on-write memory mapped into a process’ address space. The first column shows the first +step of memory mappings. The new entry with the needs-copy and copy-on-write flags is allocated. It points the +underlying object. Once a write fault occurs, a new memory object is created and that object tracks all the pages that +have been copied and modified. + +The second column shows what happens when the process writes to the middle page of the object. Since the middle page is +either unmapped or mapped read-only, writing to it triggers a page fault. The fault routine looks up the appropriate map +entry and notes that it is a needs-copy copy-on-write mapping. It first clears needs-copy by allocating a shadow object +and inserting it between the map entry and the underlying object. Then it copies the data from the middle page of the +backing object into a new page that is inserted into the shadow object. The shadow object’s page can then be mapped +read-write into the faulting process’ address space. + +The third column shows the BSD VM data structures after the process with the copy-on-write mapping forks a child, the +parent writes to the middle page, and the child writes to the right-hand page. When the parent forks, the child receives +a copy-on-write copy of the parent’s mapping. This is done by write protecting the parent’s mappings and setting +needs-copy in both processes. When the parent faults on the middle page, a second shadow object is allocated for it and +inserted on top of the first shadow object. When the child faults on the right-hand page the same thing happens, +resulting in the allocation of a third shadow object. Shadow objects are very problematic In terms of operating system efficiency and resource management. -Presented copy-on-write mechanism can leak memory by allowing pages that are no longer accessible to remain within an object chain. In the example the remaining shadow object chain contains three copies of the middle page, but only two are accessible. The page in the first shadow object is no longer accessible and should be freed to prevent the memory leak. BSD VM attempts to collapse a shadow object chain when it is possible (e.g. when new shadow object is created), but searching for objects that can be collapsed is a complex process. - -In BSD VM, a copy-on-write map entry points to a chain of shadow objects. There is no limit on the number of objects that can reside in a single shadow object chain and creating the shadow object or copying the page demands the inefficient looping over many shadow objects. +Presented copy-on-write mechanism can leak memory by allowing pages that are no longer accessible to remain within an +object chain. In the example the remaining shadow object chain contains three copies of the middle page, but only two +are accessible. The page in the first shadow object is no longer accessible and should be freed to prevent the memory +leak. BSD VM attempts to collapse a shadow object chain when it is possible (e.g. when new shadow object is created), +but searching for objects that can be collapsed is a complex process. +In BSD VM, a copy-on-write map entry points to a chain of shadow objects. There is no limit on the number of objects +that can reside in a single shadow object chain and creating the shadow object or copying the page demands the +inefficient looping over many shadow objects. ### Anonymous memory mapping (BSD UVM) -To solve problems with shadow objects chaining the anonymous mapping was introduced (SunOS VM system). It based on two abstractions - anon and amap. +To solve problems with shadow objects chaining the anonymous mapping was introduced (SunOS VM system). It based on two +abstractions - anon and amap. -Anon is the structure representing page of anonymous memory. It is created when copy-on-write flags of map entry are set and process writes data to memory. Amap the structure created for particular map entry when needs-copy for the entry is set. Amap stores anons created for the map entry. +Anon is the structure representing page of anonymous memory. It is created when copy-on-write flags of map entry are set +and process writes data to memory. Amap the structure created for particular map entry when needs-copy for the entry is +set. Amap stores anons created for the map entry. -When process is forked the memory space of child process is created based on memory space of parent process. All of memory segments (map entries) of parent and child processes are marked as read-only and needs-copy flag is set. Amaps are initially shared between segments (map entries) of child and parent process, but the number of references to each shared amap is set to minimum two. The writable pages belonging to shared entries are mapped in MMU as read only. When one of the processes accesses the segment of memory with needs-copy flag the new amap is created and anons are copied from the original amap. The number of references of each copied anon is incremented and is set to minimum two. The needs-copy flag of map entry is cleared and new anon based on anon from the original amap is created (data is copied from page pointed by original anon to page from the new anon). The number of original anon references is decremented and if number of references is equal to one it can be mapped as writable to the memory space of another process. +When process is forked the memory space of child process is created based on memory space of parent process. All of +memory segments (map entries) of parent and child processes are marked as read-only and needs-copy flag is set. Amaps +are initially shared between segments (map entries) of child and parent process, but the number of references to each +shared amap is set to minimum two. The writable pages belonging to shared entries are mapped in MMU as read only. When +one of the processes accesses the segment of memory with needs-copy flag the new amap is created and anons are copied +from the original amap. The number of references of each copied anon is incremented and is set to minimum two. The +needs-copy flag of map entry is cleared and new anon based on anon from the original amap is created (data is copied +from page pointed by original anon to page from the new anon). The number of original anon references is decremented +and if number of references is equal to one it can be mapped as writable to the memory space of another process. -The memory sharing technique based on shadowing of particular pages instead of whole objects eliminates the problem of long chains of shadow objects existing in BSD VM. +The memory sharing technique based on shadowing of particular pages instead of whole objects eliminates the problem of +long chains of shadow objects existing in BSD VM. ## Memory objects in Phoenix-RTOS -Phoenix-RTOS derives the memory object architecture from BSD UVM. The structure of its memory management subsystem in the process context is presented on the following figure. +Phoenix-RTOS derives the memory object architecture from BSD UVM. The structure of its memory management subsystem in +the process context is presented on the following figure. -There are three main differences between UVM and Phoenix-RTOS memory objects. Objects are identified by oid_t and handled by external servers and data is fetched and stored using message passing. Processes are not swappable, so there is no swap server for anonymous objects. Memory objects are supported as well on non-MMU architectures, but functionality is simplified. +There are three main differences between UVM and Phoenix-RTOS memory objects. Objects are identified by oid_t and +handled by external servers and data is fetched and stored using message passing. Processes are not swappable, so there +is no swap server for anonymous objects. Memory objects are supported as well on non-MMU architectures, but +functionality is simplified. ## See also diff --git a/kernel/vm/page.md b/kernel/vm/page.md index 5c496fd2..a20ac2af 100644 --- a/kernel/vm/page.md +++ b/kernel/vm/page.md @@ -1,10 +1,15 @@ # Page allocator -The page allocator constitutes the basic layer of the memory management subsystem in MMU architectures. It is responsible for allocating the physical memory pages (page frames). In non-MMU architectures, the page allocator allocates only fake `page_t` structures used by upper layers and plays a marginal role in memory management. This section focuses on the role of a page allocator in MMU architectures. +The page allocator constitutes the basic layer of the memory management subsystem in MMU architectures. It is +responsible for allocating the physical memory pages (page frames). In non-MMU architectures, the page allocator +allocates only fake `page_t` structures used by upper layers and plays a marginal role in memory management. This +section focuses on the role of a page allocator in MMU architectures. ## Page array -The available physical memory is treated as a set of physical pages (page frames). Each physical page available is described using the `page_t` structure. The structure is defined in the HAL, but upper layers assume that some attributes are defined. The minimum set of attributes is as follows. +The available physical memory is treated as a set of physical pages (page frames). Each physical page available is +described using the `page_t` structure. The structure is defined in the HAL, but upper layers assume that some +attributes are defined. The minimum set of attributes is as follows. ````C typedef struct _page_t { @@ -16,13 +21,21 @@ The available physical memory is treated as a set of physical pages (page frames } page_t; ```` -The `addr` attribute stores the physical page address, the `flags` describe page attributes (see further sections). The `next` and `prev` pointers and `idx` are used in the page allocation algorithm to construct lists of free pages. +The `addr` attribute stores the physical page address, the `flags` describe page attributes (see further sections). The +`next` and `prev` pointers and `idx` are used in the page allocation algorithm to construct lists of free pages. -When the memory management subsystem is initialized, the `_page_init()` function creates an array of `page_t` structures (`pages[]`) using the `pmap_getPage()` call from the HAL subsystem. This call is used to discover the page frames by upper (hardware-independent) layers of the memory management subsystem. The page array is located at the beginning of the kernel heap, right after the kernel BSS segment. +When the memory management subsystem is initialized, the `_page_init()` function creates an array of `page_t` structures +(`pages[]`) using the `pmap_getPage()` call from the HAL subsystem. This call is used to discover the page frames by +upper (hardware-independent) layers of the memory management subsystem. The page array is located at the beginning of +the kernel heap, right after the kernel BSS segment. -The memory for the structure is allocated using a heap extension. This extension is performed by using the `_page_sbrk()` function, which allocates a new page from the pool using the `_page_alloc() `function and maps it into the kernel address space directly with `pmap_enter()` at the top of the heap. Pages are allocated using a regular allocation algorithm but data structures used for allocation are not fully initialized. The array creation algorithm is presented below. +The memory for the structure is allocated using a heap extension. This extension is performed by using the +`_page_sbrk()` function, which allocates a new page from the pool using the `_page_alloc()`function and maps it into the +kernel address space directly with `pmap_enter()` at the top of the heap. Pages are allocated using a regular allocation +algorithm but data structures used for allocation are not fully initialized. The array creation algorithm is presented +below. ```c for (page = (page_t *)*bss;;) { @@ -53,36 +66,71 @@ The memory for the structure is allocated using a heap extension. This extension break; } ``` -The initialization loop in each iteration discovers a new physical page using the `pmap_getPage()`. The function fills the newly allocated `page_t` structure and returns the next valid physical address in the `addr` argument. The returned page is flagged as either free or allocated using the `flags` attribute. The next two upper bits of this attribute define the page ownership: a page can belong to the kernel, application or boot loader (memory reserved by BIOS on a PC is marked in this way). The next upper bits define the page usage in the specific domain defined by ownership. For example, pages marked as allocated by the kernel may be allocated for specific purposes (stack, heap, interrupt table, page table etc.). + +The initialization loop in each iteration discovers a new physical page using the `pmap_getPage()`. The function fills +the newly allocated `page_t` structure and returns the next valid physical address in the `addr` argument. The returned +page is flagged as either free or allocated using the `flags` attribute. The next two upper bits of this attribute +define the page ownership: a page can belong to the kernel, application or boot loader (memory reserved by BIOS on a PC +is marked in this way). The next upper bits define the page usage in the specific domain defined by ownership. For +example, pages marked as allocated by the kernel may be allocated for specific purposes (stack, heap, interrupt table, +page table etc.). ### Presentation of page array during the boot process -During the kernel boot process, the `page[]` is presented on the screen using letters and periods. The letter interpretation will be presented using a sample map for a PC with 128MB of RAM. +During the kernel boot process, the `page[]` is presented on the screen using letters and periods. The letter +interpretation will be presented using a sample map for a PC with 128MB of RAM. -> - vm: HCYPPSSS[24H][22K][103H]..B[80x][16B][32509.]BBB[101574x][64B] +``` +vm: HCYPPSSS[24H][22K][103H]..B[80x][16B][32509.]BBB[101574x][64B] +``` -In this map, the first physical page is allocated to the kernel heap. The second page is used for CPU purposes (interrupt and exception table). The `Y`-marked page stores the `syspage_t` structure used for communication between the loader and the starting kernel. After this page, there are two pages used for storing structures used for paging (page directory and page table marked with `P`). The next pages are allocated for the initial kernel stack. They will be released after starting the init process, switching into its main thread stack. The next characters (in square parentheses) contain the information that next 24 pages are allocated to the kernel heap. The next 22 pages store the kernel code and data. These are followed by 103 pages allocated to the kernel heap and two free pages (marked with periods). The `B` character informs that next pages are used by the boot loader (BIOS). This page is followed by a gap (i.e. the gap after the 640 KB of address space). After the gap, there are 16 pages allocated to BIOS and 32509 free pages. At the end of the address space, there are 64 pages reserved by BIOS. +In this map, the first physical page is allocated to the kernel heap. The second page is used for CPU purposes +(interrupt and exception table). The `Y`-marked page stores the `syspage_t` structure used for communication between +the loader and the starting kernel. After this page, there are two pages used for storing structures used for paging +(page directory and page table marked with `P`). The next pages are allocated for the initial kernel stack. They will +be released after starting the init process, switching into its main thread stack. The next characters +(in square parentheses) contain the information that next 24 pages are allocated to the kernel heap. The next +22 pages store the kernel code and data. These are followed by 103 pages allocated to the kernel heap and two +free pages (marked with periods). The `B` character informs that next pages are used by the boot loader (BIOS). +This page is followed by a gap (i.e. the gap after the 640 KB of address space). After the gap, there are 16 +pages allocated to BIOS and 32509 free pages. At the end of the address space, there are 64 pages reserved by BIOS. ## Page allocation -The page allocator in the Phoenix-RTOS kernel is based on a well-known buddy algorithm. The figure below shows a graphical illustration of data structures used in this algorithm. +The page allocator in the Phoenix-RTOS kernel is based on a well-known buddy algorithm. The figure below shows a +graphical illustration of data structures used in this algorithm. -Each square corresponds to a physical page, with the assumed page size of 4096 bytes. The main structure used in the allocation is the `sizes[]` array. The `size[]` array is created on the basis of the `page[]` array during the memory management initialization. +Each square corresponds to a physical page, with the assumed page size of 4096 bytes. The main structure used in +the allocation is the `sizes[]` array. The `size[]` array is created on the basis of the `page[]` array during +the memory management initialization. -The `size[]` array contains pointers to lists of physically coherent sets of pages. The n-th entry of `sizes[]` array points to the list of sets whose size is the n-th power of 2. For example, an entry with the 0 index points to page sets whose size is 1 byte. An entry with the 12 index points to sets containing 4096 bytes of physical memory. +The `size[]` array contains pointers to lists of physically coherent sets of pages. The n-th entry of `sizes[]` +array points to the list of sets whose size is the n-th power of 2. For example, an entry with the 0 index points +to page sets whose size is 1 byte. An entry with the 12 index points to sets containing 4096 bytes of physical memory. -The initialization algorithm divides all accessible physical space into regions of maximum size. This means that during the allocation process a region should be divided into smaller regions and the obtained free regions should be added to the proper lists pointed by the `size[]` array. +The initialization algorithm divides all accessible physical space into regions of maximum size. This means that during +the allocation process a region should be divided into smaller regions and the obtained free regions should be +added to the proper lists pointed by the `size[]` array. ### Sample allocation -Let us have a look at an allocation process where only one region of 128 KB in size is available and 4096 bytes should be allocated. The allocation starts with the lookup of the first region. The starting entry of `size[]` array is calculated on the basis of the requested size (4096 bytes). In this case, the starting entry will be 12, and no list is available in this entry. The lookup is performed for the next entry and finally the 128 KB region list is found (entry 17). When the first not-empty entry is found, the algorithm proceeds to the next step, which is illustrated below. +Let us have a look at an allocation process where only one region of 128 KB in size is available and 4096 bytes +should be allocated. The allocation starts with the lookup of the first region. The starting entry of `size[]` +array is calculated on the basis of the requested size (4096 bytes). In this case, the starting entry will be 12, +and no list is available in this entry. The lookup is performed for the next entry and finally the 128 KB region +list is found (entry 17). When the first not-empty entry is found, the algorithm proceeds to the next step, which +is illustrated below. -The first page set is removed from the list and divided into two 64 KB regions. The upper 64 KB region is added to the `size[16]` entry and then split. The first 64 KB region is split into two 32 KB regions. The upper 32 KB region is returned to the `size[15]` entry. Next, the first half of the region is divided into two 16 KB regions, and finally only one page is available. This page is returned as an allocation result. The complexity of this allocation is O(log2N). The maximum number of steps which should be performed is the size of `size[]` array minus the log2(page size). The maximum cost of page allocation on a 32-bit address space is 20 steps. +The first page set is removed from the list and divided into two 64 KB regions. The upper 64 KB region is added to the +`size[16]` entry and then split. The first 64 KB region is split into two 32 KB regions. The upper 32 KB region is +returned to the `size[15]` entry. Next, the first half of the region is divided into two 16 KB regions, and finally +only one page is available. This page is returned as an allocation result. The complexity of this allocation is +O(log2N). The maximum number of steps which should be performed is the size of `size[]` array minus +the log2(page size). The maximum cost of page allocation on a 32-bit address space is 20 steps. ## Page deallocation @@ -90,13 +138,22 @@ Page deallocation is defined as the process opposite to the page allocation proc ### Sample deallocation -Let us assume that the page allocated in the previous section must be released. The first step is to analyze the neighborhood of the page based on the `pages[]` array. The array is sorted and it is assumed that the next page for the released `page_t` is the `page_t` structure, describing the physical page located right after the released page or the page located on higher physical addresses. If the next `page_t` structure describes the neighboring page, and if it is marked as free, the merging process is performed. The next page is removed from the `sizes[]` array and merged with the page which should be released. If the region created in this way is located right before the free region of the same size, the merging process is repeated. The next steps are repeated forming larger regions until there are no free neighboring regions. +Let us assume that the page allocated in the previous section must be released. The first step is to analyze the +neighborhood of the page based on the `pages[]` array. The array is sorted and it is assumed that the +next page for the released `page_t` is the `page_t` structure, describing the physical page located right +after the released page or the page located on higher physical addresses. If the next `page_t` structure describes +the neighboring page, and if it is marked as free, the merging process is performed. The next page is removed from +the `sizes[]` array and merged with the page which should be released. If the region created in this way is located +right before the free region of the same size, the merging process is repeated. The next steps are repeated forming +larger regions until there are no free neighboring regions. ## Page allocation for non-MMU architectures -In non-MMU architectures, the page_t structure is only allocated as needed by upper layers (i.e. a memory mapper). It does not correspond to a real memory segment. During the kernel initialization, a pool of page_t structures is created, assuming a given page size. The number of `page_t` entries is proportional to the size of physical memory. +In non-MMU architectures, the page_t structure is only allocated as needed by upper layers (i.e. a memory mapper). +It does not correspond to a real memory segment. During the kernel initialization, a pool of page_t structures is +created, assuming a given page size. The number of `page_t` entries is proportional to the size of physical memory. ```c void _page_init(pmap_t *pmap, void **bss, void **top) @@ -115,9 +172,13 @@ In non-MMU architectures, the page_t structure is only allocated as needed by up } ``` -The assumed page size depends on the architecture and the available memory size. For microcontrollers with a small memory size, the page size is typically 256 bytes. +The assumed page size depends on the architecture and the available memory size. For microcontrollers with a small +memory size, the page size is typically 256 bytes. -Page allocation is quite simple. It just retrieves the first `page_t` entry from the pool. In the deallocation process, a `page_t` is returned to the pool. It must be noted that the real memory allocation is performed during the memory mapping process. All processes and the kernel use the same, common memory map which stores all segments existing in the physical memory. +Page allocation is quite simple. It just retrieves the first `page_t` entry from the pool. In the deallocation process, +a `page_t` is returned to the pool. It must be noted that the real memory allocation is performed during the memory +mapping process. All processes and the kernel use the same, common memory map which stores all segments existing in +the physical memory. ## See also diff --git a/kernel/vm/zalloc.md b/kernel/vm/zalloc.md index 26428a5c..a69b4902 100644 --- a/kernel/vm/zalloc.md +++ b/kernel/vm/zalloc.md @@ -1,6 +1,9 @@ # Zone allocator -Zone allocator is used to allocate memory inside the allocated pages mapped into the address space. The main idea of this allocator is to allocate the memory area and divide it into similar chunks aligned to their size. Zone allocator is used when equal fragments of memory should be allocated dynamically with minimum processing overhead. The good use case is allocation of network buffer headers. +Zone allocator is used to allocate memory inside the allocated pages mapped into the address space. The main idea of +this allocator is to allocate the memory area and divide it into similar chunks aligned to their size. Zone allocator +is used when equal fragments of memory should be allocated dynamically with minimum processing overhead. The good use +case is allocation of network buffer headers. Each zone used for allocation is described using `vm_zone_t` header. @@ -18,7 +21,12 @@ Each zone used for allocation is described using `vm_zone_t` header. } vm_zone_t; ``` -For purposes of fine grained allocator (described in the next chapter) zones are linked using the `next` and `prev` attributes. Attribute `linkage` is used for adding zone headers into the red-black tree used by fine grained allocator for memory deallocation. Attributes `blocksz` and `blocks` define the chunk size and number of chunks in the zone. Attribute `used` stores the number of chunks already allocated. Virtual address at which page set is mapped is pointed by `vaddr`. The first page descriptor of pages set constituting the zone is pointed by `pages` attribute. Attribute `first` points the first free chunk in the zone. +For purposes of fine grained allocator (described in the next chapter) zones are linked using the `next` and `prev` +attributes. Attribute `linkage` is used for adding zone headers into the red-black tree used by fine grained allocator +for memory deallocation. Attributes `blocksz` and `blocks` define the chunk size and number of chunks in the zone. +Attribute `used` stores the number of chunks already allocated. Virtual address at which page set is mapped is pointed +by `vaddr`. The first page descriptor of pages set constituting the zone is pointed by `pages` attribute. Attribute +`first` points the first free chunk in the zone. ## Chunk allocation @@ -27,21 +35,25 @@ Functions used for chunk allocations are presented below. ```c extern int _vm_zoneCreate(vm_zone_t *zone, size_t blocksz, unsigned int blocks); ``` - -Function creates the new zone containing the `blocks` number of blocks. The size of single block is given by `blocksz` argument. During the zone creation a new page set is allocated and mapped into the kernel address space. The address of the mapping is returned in the zone header given by `zone` pointer. The final number of blocks in the zone can be greater than requested (because of the allocation with the page size granulation). The final block size can be greater than requested because block size should be aligned. +Function creates the new zone containing the `blocks` number of blocks. The size of single block is given by `blocksz` +argument. During the zone creation a new page set is allocated and mapped into the kernel address space. The address of +the mapping is returned in the zone header given by `zone` pointer. The final number of blocks in the zone can be +greater than requested (because of the allocation with the page size granulation). The final block size can be greater +than requested because block size should be aligned. ```c extern int _vm_zoneDestroy(vm_zone_t *zone); ``` -Function destroys zone given by the argument. +Function destroys zone given by the argument. ```c extern void *_vm_zalloc(vm_zone_t *zone, addr_t *addr); ``` -Function allocates bucket of memory from zone given by `zone`. The `addr` stores the physical address of allocated bucket. +Function allocates bucket of memory from zone given by `zone`. The `addr` stores the physical address of allocated +bucket. ```c extern void _vm_zfree(vm_zone_t *zone, void *vaddr); @@ -55,4 +67,3 @@ extern void _vm_zfree(vm_zone_t *zone, void *vaddr); 4. [Kernel - Memory management - Fine grained allocator](kmalloc.md) 5. [Kernel - Memory management - Memory objects](objects.md) 6. [Table of Contents](../../README.md) - diff --git a/libc/README.md b/libc/README.md index 1caecb9f..282e4230 100644 --- a/libc/README.md +++ b/libc/README.md @@ -1,6 +1,8 @@ # Standard library -Phoenix-RTOS uses its own standard C library - libphoenix. The library provides a system interface for user applications. The goal of this project is to provide IEEE Std 1003.1-2017 (POSIX) compliant and certified system interface. +Phoenix-RTOS uses its own standard C library - libphoenix. The library provides a system interface for user +applications. The goal of this project is to provide IEEE Std 1003.1-2017 (POSIX) compliant and certified system +interface. ## Source code diff --git a/libc/functions/_/_Exit.part-impl.md b/libc/functions/_/_Exit.part-impl.md index bcc988f0..5c1795bd 100644 --- a/libc/functions/_/_Exit.part-impl.md +++ b/libc/functions/_/_Exit.part-impl.md @@ -18,15 +18,20 @@ IEEE Std 1003.1-2017 ## Description -The `_Exit()` and `_exit()` functions terminate the calling process. +The `_Exit()` and `_exit()` functions terminate the calling process. -The value of status may be `0`, `EXIT_SUCCESS`, `EXIT_FAILURE`, or any other value, though only the least significant 8 bits (that is, `status & 0xff`) are available from `wait()` and `waitpid()`; the full value is available from `waitid()` and in the `siginfo_t` passed to a signal handler for `SIGCHLD`. +The value of status may be `0`, `EXIT_SUCCESS`, `EXIT_FAILURE`, or any other value, though only the least significant 8 +bits (that is, `status & 0xff`) are available from `wait()` and `waitpid()`; the full value is available from `waitid()` +and in the `siginfo_t` passed to a signal handler for `SIGCHLD`. -The functions do not call functions registered with `atexit()` nor any registered signal handlers. Open streams are not flushed, but opened file descriptors are closed. Finally, the calling process is terminated with the consequences described below. +The functions do not call functions registered with `atexit()` nor any registered signal handlers. Open streams are not +flushed, but opened file descriptors are closed. Finally, the calling process is terminated with the consequences +described below. ### Consequences of Process Termination -All of the file descriptors, directory streams, conversion descriptors, and message catalog descriptors open in the calling process are closed. +All of the file descriptors, directory streams, conversion descriptors, and message catalog descriptors open in the +calling process are closed. If the parent process of the calling process has set the action for the `SIGCHLD` signal to `SIG_IGN`: @@ -34,33 +39,46 @@ If the parent process of the calling process has set the action for the `SIGCHLD * The lifetime of the calling process ends immediately and a `SIGCHLD` signal is sent to the parent process. -* If a thread in the parent process of the calling process is blocked in `wait()`, `waitpid()`, or `waitid()`, and the parent process has no remaining child processes in the set of waited-for children, the `wait()`, `waitid()`, or `waitpid()` function fails and sets errno to `[ECHILD]`. +* If a thread in the parent process of the calling process is blocked in `wait()`, `waitpid()`, or `waitid()`, and the +parent process has no remaining child processes in the set of waited-for children, the `wait()`, `waitid()`, or +`waitpid()` function fails and sets errno to `[ECHILD]`. Otherwise: * Status information is generated. -* The calling process is transformed into a zombie process. Its status information is made available to the parent process until the process' lifetime ends. +* The calling process is transformed into a zombie process. Its status information is made available to the parent +process until the process' lifetime ends. -* The process' lifetime ends once its parent obtains the process' status information via a currently-blocked or future call to `wait()`, `waitid()` (without `WNOWAIT`), or `waitpid()`. +* The process' lifetime ends once its parent obtains the process' status information via a currently-blocked or future +call to `wait()`, `waitid()` (without `WNOWAIT`), or `waitpid()`. -* If one or more threads in the parent process of the calling process is blocked in a call to `wait()`, `waitid()`, or `waitpid()` awaiting termination of the process, one (or, if any are calling `waitid()` with `WNOWAIT`, possibly more) of these threads obtains the process' status information as specified in Status Information and becomes unblocked. +* If one or more threads in the parent process of the calling process is blocked in a call to `wait()`, `waitid()`, or +`waitpid()` awaiting termination of the process, one (or, if any are calling `waitid()` with `WNOWAIT`, possibly more) +of these threads obtains the process' status information as specified in Status Information and becomes unblocked. * A `SIGCHLD` is sent to the parent process. -Termination of a process does not directly terminate its children. The sending of a `SIGHUP` signal as described below indirectly terminates children in some circumstances. +Termination of a process does not directly terminate its children. The sending of a `SIGHUP` signal as described below +indirectly terminates children in some circumstances. -If the process is a controlling process, the `SIGHUP` signal is sent to each process in the foreground process group of the controlling terminal belonging to the calling process. +If the process is a controlling process, the `SIGHUP` signal is sent to each process in the foreground process group of +the controlling terminal belonging to the calling process. -If the process is a controlling process, the controlling terminal associated with the session is disassociated from the session, allowing it to be acquired by a new controlling process. +If the process is a controlling process, the controlling terminal associated with the session is disassociated from the +session, allowing it to be acquired by a new controlling process. -The parent process ID of all of the existing child processes and zombie processes of the calling process are set to the process ID of an `init` system process. That is, these processes are inherited by a `init` process. +The parent process ID of all of the existing child processes and zombie processes of the calling process are set to the +process ID of an `init` system process. That is, these processes are inherited by a `init` process. Memory mappings that were created in the process are unmapped before the process is destroyed. -Threads terminated by a call to `_Exit()` do not invoke their cancellation cleanup handlers or per-thread data destructors. +Threads terminated by a call to `_Exit()` do not invoke their cancellation cleanup handlers or per-thread data +destructors. -If the calling process is a trace controller process, any trace streams that were created by the calling process are shut down as described by the `posix_trace_shutdown()` function, and mapping of trace event names to trace event type identifiers of any process built for these trace streams may be deallocated. +If the calling process is a trace controller process, any trace streams that were created by the calling process are +shut down as described by the `posix_trace_shutdown()` function, and mapping of trace event names to trace event type +identifiers of any process built for these trace streams may be deallocated. ## Return value @@ -75,4 +93,4 @@ No errors are defined. ## See Also 1. [Standard library functions](../README.md) -2. [Table of Contents](../../../README.md) \ No newline at end of file +2. [Table of Contents](../../../README.md) diff --git a/libc/functions/a/abort.part-impl.md b/libc/functions/a/abort.part-impl.md index e0d30964..bade64f6 100644 --- a/libc/functions/a/abort.part-impl.md +++ b/libc/functions/a/abort.part-impl.md @@ -1,34 +1,36 @@ -# Synopsis +# Synopsis + `#include `
-` void abort(void);`
+`void abort(void);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The purpose is to generate an abnormal process abort. The `abort()` function shall cause abnormal process termination to occur, unless the signal `SIGABRT` is being caught and the signal handler does not return. -The abnormal termination processing shall include the default actions defined for `SIGABRT` and may include an attempt to effect `fclose()` on all open streams. +The purpose is to generate an abnormal process abort. The `abort()` function shall cause abnormal process termination to +occur, unless the signal `SIGABRT` is being caught and the signal handler does not return. +The abnormal termination processing shall include the default actions defined for `SIGABRT` and may include an attempt +to effect `fclose()` on all open streams. The `SIGABRT` signal shall be sent to the calling process as if by means of `raise()` with the argument `SIGABRT`. -The status made available to `wait()`, `waitid()`, or `waitpid()` by `abort()` shall be that of a process terminated by the `SIGABRT` signal. The +The status made available to `wait()`, `waitid()`, or `waitpid()` by `abort()` shall be that of a process terminated by +the `SIGABRT` signal. The `abort()` function shall override blocking or ignoring the `SIGABRT` signal. - ## Return value The `abort()` function shall not return. ## Errors - No errors are defined. - - - ## Tests Untested @@ -37,6 +39,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/a/accept.part-impl.md b/libc/functions/a/accept.part-impl.md index 54db7bd3..60d47a4a 100644 --- a/libc/functions/a/accept.part-impl.md +++ b/libc/functions/a/accept.part-impl.md @@ -1,8 +1,9 @@ -# Synopsis +# Synopsis + `#include `
-` int accept(int socket, struct sockaddr *restrict address,`
-`        socklen_t *restrict address_len);`
+`int accept(int socket, struct sockaddr *restrict address,`
+`socklen_t *restrict address_len);`
## Status @@ -15,77 +16,76 @@ IEEE Std 1003.1-2017 ## Description The `accept()` function shall extract the first connection on the queue of pending connections, create a new socket with -the same socket type protocol and address family as the specified _socket_, and allocate a new file descriptor for that socket. The -file descriptor shall be allocated as described in File Descriptor +the same socket type protocol and address family as the specified _socket_, and allocate a new file descriptor for that +socket. The file descriptor shall be allocated as described in File Descriptor Allocation. The `accept()` function takes the following arguments: -* _`socket`_ Specifies a socket that was created with `socket()`, has been bound to an _address_ with `bind()`, and has issued a successful call to `listen()`. -* _`address`_ Either a `null` pointer, or a pointer to a sockaddr structure where the address of the connecting socket shall be -returned. -* _`address_len`_ Either a `null` pointer, if _address_ is a `null` pointer, or a pointer to a `socklen_t` object which on input specifies -the length of the supplied sockaddr structure, and on output specifies the length of the stored address. +* _`socket`_ Specifies a socket that was created with `socket()`, has been bound to an _address_ with `bind()`, and has +issued a successful call to `listen()`. +* _`address`_ Either a `null` pointer, or a pointer to a sockaddr structure where the address of the connecting socket +shall be returned. +* _`address_len`_ Either a `null` pointer, if _address_ is a `null` pointer, or a pointer to a `socklen_t` object which +on input specifies the length of the supplied sockaddr structure, +and on output specifies the length of the stored address. If _address_ is not a `null` pointer, the address of the peer for the accepted connection shall be stored in the -`sockaddr` structure pointed to by _address_, and the length of this address shall be stored in the object pointed to by _`address_len`_. +`sockaddr` structure pointed to by _address_, and the length of this address shall be stored in the object pointed to +by _`address_len`_. -If the actual length of the address is greater than the length of the supplied sockaddr structure, the stored address shall be truncated. +If the actual length of the address is greater than the length of the supplied sockaddr structure, the stored address +shall be truncated. -If the protocol permits connections by unbound clients, and the peer is not bound, then the value stored in the object pointed -to by _address_ is unspecified. +If the protocol permits connections by unbound clients, and the peer is not bound, then the value stored in the object +pointed to by _address_ is unspecified. If the listen queue is empty of connection requests and `O_NONBLOCK` is not set on the file descriptor for the socket, `accept()` shall block until a connection is present. If the `listen()` queue is -empty of connection requests and `O_NONBLOCK` is set on the file descriptor for the socket, `accept()` shall fail and set -`errno` to `EAGAIN` or `EWOULDBLOCK`. - -The accepted socket cannot itself accept more connections. The original socket remains open and can accept more connections. +empty of connection requests and `O_NONBLOCK` is set on the file descriptor for the socket, `accept()` shall fail +and set `errno` to `EAGAIN` or `EWOULDBLOCK`. +The accepted socket cannot itself accept more connections. The original socket remains open +and can accept more connections. ## Return value -Upon successful completion, `accept()` shall return the non-negative file descriptor of the accepted socket. Otherwise, `-1` shall be returned, `errno` shall be set to indicate the error, and any object pointed to by _address_len_ shall remain unchanged. +Upon successful completion, `accept()` shall return the non-negative file descriptor of the accepted socket. Otherwise, +`-1` shall be returned, `errno` shall be set to indicate the error, and any object pointed to by _address_len_ +shall remain unchanged. ## Errors - The `accept()` function shall fail if: `EAGAIN` or `EWOULDBLOCK` O_NONBLOCK is set for the _socket_ file descriptor and no connections are present to be accepted. - * `EBADF` - The _socket_ argument is not a valid file descriptor. +* `EBADF` - The _socket_ argument is not a valid file descriptor. `ECONNABORTED` A connection has been aborted. - * `EINTR` - The `accept()` function was interrupted by a signal that was caught before a valid connection arrived. +* `EINTR` - The `accept()` function was interrupted by a signal that was caught before a valid connection arrived. - * `EINVAL` - The _socket_ is not accepting connections. +* `EINVAL` - The _socket_ is not accepting connections. - * `EMFILE` - All file descriptors available to the process are currently open. +* `EMFILE` - All file descriptors available to the process are currently open. - * `ENFILE` - The maximum number of file descriptors in the system are already open. +* `ENFILE` - The maximum number of file descriptors in the system are already open. - * `ENOBUFS` - No buffer space is available. +* `ENOBUFS` - No buffer space is available. - * `ENOMEM` - There was insufficient memory available to complete the operation. +* `ENOMEM` - There was insufficient memory available to complete the operation. - * `ENOTSOCK` - The _socket_ argument does not refer to a socket. +* `ENOTSOCK` - The _socket_ argument does not refer to a socket. - * `EOPNOTSUPP` - The socket type of the specified _socket_ does not support accepting connections. +* `EOPNOTSUPP` - The socket type of the specified _socket_ does not support accepting connections. The `accept()` function may fail if: - - * `EPROTO` - A protocol error has occurred; [OB XSR]  for example, the STREAMS protocol stack has not been initialized. - - - - - +* `EPROTO` - A protocol error has occurred; [OB XSR]  for example, the STREAMS protocol stack has not been initialized. ## Tests @@ -95,6 +95,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/a/acos.part-impl.md b/libc/functions/a/acos.part-impl.md index eeaf5f46..c0e665d0 100644 --- a/libc/functions/a/acos.part-impl.md +++ b/libc/functions/a/acos.part-impl.md @@ -1,28 +1,36 @@ -# Synopsis +# Synopsis + `#include `
-` double acos(double x);`
+`double acos(double x);`
-` float acosf(float x);`
+`float acosf(float x);`
-` long double acosl(long double x);`
+`long double acosl(long double x);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description -These functions shall compute the principal value of the arc cosine of their argument _x_. The value of _x_ should be in the range `[-1,1]`. +## Description -An application wishing to check for error situations should set `errno` to zero and call `feclearexcept(FE_ALL_EXCEPT)` before calling these functions. On return, if `errno` is non-zero or `fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)` is non-zero, an error has occurred. +These functions shall compute the principal value of the arc cosine of their argument _x_. The value of _x_ should +be in the range `[-1,1]`. +An application wishing to check for error situations should set `errno` to zero and call `feclearexcept(FE_ALL_EXCEPT)` +before calling these functions. On return, if `errno` is non-zero or +`fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)` is non-zero, an error has occurred. ## Return value Upon successful completion, these functions shall return the arc cosine of _x_, in the range `[0, pi]` radians. -For finite values of _x_ not in the range `[-1,1]`, a domain error shall occur, and either a `NaN` (if supported), or an implementation-defined value shall be returned. +For finite values of _x_ not in the range `[-1,1]`, a domain error shall occur, and either a `NaN` (if supported), or +an implementation-defined value shall be returned. * If _x_ is `NaN`, a `NaN` shall be returned. @@ -32,19 +40,13 @@ For finite values of _x_ not in the range `[-1,1]`, a domain error shall occur, ## Errors - These functions shall fail if: Domain Error -The _x_ argument is finite and is not in the range `[-1,1]`, or is `±Inf`. +The _x_ argument is finite and is not in the range `[-1,1]`, or is `±Inf`. If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `EDOM`. If -the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the invalid floating-point exception shall -be raised. - - - - - +the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the invalid floating-point +exception shall be raised. ## Tests @@ -54,6 +56,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/a/alarm.part-impl.md b/libc/functions/a/alarm.part-impl.md index 481c3055..206b703a 100644 --- a/libc/functions/a/alarm.part-impl.md +++ b/libc/functions/a/alarm.part-impl.md @@ -1,37 +1,40 @@ -# Synopsis +# Synopsis + `#include `
-` unsigned alarm(unsigned seconds);`
+`unsigned alarm(unsigned seconds);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The purpose is to schedule an alarm signal. The `alarm()` function shall cause the system to generate a `SIGALRM` signal for the process after the number of realtime -seconds specified by _seconds_ have elapsed. Processor scheduling delays may prevent the process from handling the signal as -soon as it is generated. +The purpose is to schedule an alarm signal. The `alarm()` function shall cause the system to generate a `SIGALRM` signal +for the process after the number of realtime +seconds specified by _seconds_ have elapsed. Processor scheduling delays may prevent the process from handling the +signal as soon as it is generated. If _seconds_ is `0`, a pending alarm request, if any, is canceled. -Alarm requests are not stacked, only one `SIGALRM` generation can be scheduled in this manner. If the `SIGALRM` signal has not yet -been generated, the call shall result in rescheduling the time at which the `SIGALRM` signal is generated. - -Interactions between `alarm()` and `setitimer()` are unspecified. +Alarm requests are not stacked, only one `SIGALRM` generation can be scheduled in this manner. If the `SIGALRM` signal +has not yet been generated, the call shall result in rescheduling the time at which the `SIGALRM` signal is generated. +Interactions between `alarm()` and `setitimer()` are unspecified. ## Return value -If there is a previous `alarm()` request with time remaining, `alarm()` shall return a non-zero value that is the number of seconds until the previous request would have generated a `SIGALRM` signal. Otherwise, `alarm()` shall return `0`. +If there is a previous `alarm()` request with time remaining, `alarm()` shall return a non-zero value that is the number +of seconds until the previous request would have generated a `SIGALRM` signal. Otherwise, `alarm()` shall return `0`. ## Errors - The `alarm()` function is always successful, and no return value is reserved to indicate an error. - ## Tests Untested @@ -40,6 +43,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/a/asctime.part-impl.md b/libc/functions/a/asctime.part-impl.md index 718a21e1..164e2272 100644 --- a/libc/functions/a/asctime.part-impl.md +++ b/libc/functions/a/asctime.part-impl.md @@ -1,26 +1,29 @@ -# Synopsis +# Synopsis + `#include `
-` char *asctime(const struct tm *timeptr);`
+`char *asctime(const struct tm *timeptr);`
-` char *asctime_r(const struct tm *restrict tm, char *restrict buf);`
+`char *asctime_r(const struct tm *restrict tm, char *restrict buf);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `asctime()` function shall convert the broken-down time in the structure pointed to by _timeptr_ into a string in the form: `Sun Sep 16 01:03:52 1973\n\0` - using the equivalent of the following algorithm: -``` +```c char *asctime(const struct tm *timeptr) { static char wday_name[7][3] = { @@ -42,11 +45,10 @@ char *asctime(const struct tm *timeptr) } ``` - However, the behavior is undefined if `timeptr->tm_wday` or `timeptr->tm_mon` are not within the normal ranges as defined in ``, or if `timeptr->tm_year` -exceeds `INT_MAX-1990,` or if the above algorithm would attempt to generate more than 26 bytes of output (including the terminating -`null`). +exceeds `INT_MAX-1990,` or if the above algorithm would attempt to generate more than 26 bytes of output (including +the terminating `null`). The tm structure is defined in the `` header. The @@ -58,23 +60,23 @@ returned in either of these objects by any of the other functions. The `asctime()` function need not be thread-safe. The `asctime_r()` function shall convert the broken-down time in the structure pointed to by _tm_ into a string (of -the same form as that returned by `asctime()`, and with the same undefined behavior when input or output is out of range) that -is placed in the user-supplied buffer pointed to by _buf_ (which shall contain at least 26 bytes) and then return _buf_. - - +the same form as that returned by `asctime()`, and with the +same undefined behavior when input or output is out of range) +that is placed in the user-supplied buffer pointed to by _buf_ (which shall contain at least 26 bytes) +and then return _buf_. ## Return value -Upon successful completion, `asctime()` shall return a pointer to the string. If the function is unsuccessful, it shall return `NULL`. +Upon successful completion, `asctime()` shall return a pointer to the string. If the function is unsuccessful, +it shall return `NULL`. -Upon successful completion, `asctime_r()` shall return a pointer to a character string containing the date and time. This string is pointed to by the argument _buf_. If the function is unsuccessful, it shall return `NULL`. +Upon successful completion, `asctime_r()` shall return a pointer to a character string containing the date and time. +This string is pointed to by the argument _buf_. If the function is unsuccessful, it shall return `NULL`. ## Errors - No errors are defined. - ## Tests Untested @@ -83,6 +85,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/a/assert.part-impl.md b/libc/functions/a/assert.part-impl.md index 73ea85e3..73ca40d0 100644 --- a/libc/functions/a/assert.part-impl.md +++ b/libc/functions/a/assert.part-impl.md @@ -1,39 +1,40 @@ -# Synopsis +# Synopsis + `#include `
-` void assert(scalar expression);`
+`void assert(scalar expression);`
## Status + Partially implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 -The purpose is to insert program diagnostics. The `assert()` macro shall insert diagnostics into programs, it shall expand to a `void` expression. When it is -executed, if _expression_ (which shall have a scalar type) is false (that is, compares equal to `0`), `assert()` -shall write information about the particular call that failed on stderr and shall call `abort()`. +## Description -The information written about the call that failed shall include the text of the argument, the name of the source file, the -source file line number, and the name of the enclosing function, the latter are, respectively, the values of the preprocessing -macros `__FILE__` and `__LINE__` and of the identifier `__func__`. +The purpose is to insert program diagnostics. The `assert()` macro shall insert diagnostics into programs, it shall +expand to a `void` expression. When it is executed, if _expression_ (which shall have a scalar type) is false (that is, +compares equal to `0`), `assert()` shall write information about the particular call that failed on stderr +and shall call `abort()`. -Forcing a definition of the name `NDEBUG`, either from the compiler command line or with the preprocessor control statement -`#define NDEBUG` ahead of the `#include ` statement, shall -stop assertions from being compiled into the program. +The information written about the call that failed shall include the text of the argument, the name of the source file, +the source file line number, and the name of the enclosing function, the latter are, respectively, the values of the +preprocessing macros `__FILE__` and `__LINE__` and of the identifier `__func__`. +Forcing a definition of the name `NDEBUG`, +either from the compiler command line or with the preprocessor control statement `#define NDEBUG` ahead of the +`#include ` statement, shall stop assertions from being compiled into the program. ## Return value The `assert()` macro shall not return a value. - ## Errors - No errors are defined. - ## Tests Untested @@ -42,6 +43,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/a/atan.part-impl.md b/libc/functions/a/atan.part-impl.md index e1ea12f8..c052dc5b 100644 --- a/libc/functions/a/atan.part-impl.md +++ b/libc/functions/a/atan.part-impl.md @@ -1,22 +1,28 @@ -# Synopsis +# Synopsis + `#include `
-` double atan(double x);`
+`double atan(double x);`
-` float atanf(float x);`
+`float atanf(float x);`
-` long double atanl(long double x);`
+`long double atanl(long double x);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description These functions shall compute the principal value of the arc tangent of their argument _x_. -An application wishing to check for error situations should set `errno` to zero and call `feclearexcept(FE_ALL_EXCEPT)` before calling these functions. On return, if `errno` is non-zero or `fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)` is non-zero, an error has occurred. - +An application wishing to check for error situations should set `errno` to zero and call `feclearexcept(FE_ALL_EXCEPT)` +before calling these functions. On return, if `errno` is non-zero or +`fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)` is non-zero, an error has occurred. ## Return value @@ -30,19 +36,20 @@ Upon successful completion, these functions shall return the arc tangent of _x_ * If _x_ is subnormal, a range error may occur and _x_ should be returned. -* If _x_ is not returned, `atan()`, `atanf()`, and `atanl()` shall return an implementation-defined value no greater in magnitude than `DBL_MIN`, `FLT_MIN`, and `LDBL_MIN`, respectively. +* If _x_ is not returned, `atan()`, `atanf()`, and `atanl()` shall return an implementation-defined value no greater in +magnitude than `DBL_MIN`, `FLT_MIN`, and `LDBL_MIN`, respectively. ## Errors - These functions may fail if: * Range Error - The value of _x_ is subnormal. - - If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the underflow floating-point exception shall be raised. + The value of _x_ is subnormal. + If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If the + integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the underflow floating-point + exception shall be raised. ## Tests @@ -52,6 +59,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/a/atan2.part-impl.md b/libc/functions/a/atan2.part-impl.md index 8272b0be..3ba5bc2b 100644 --- a/libc/functions/a/atan2.part-impl.md +++ b/libc/functions/a/atan2.part-impl.md @@ -1,16 +1,20 @@ -# Synopsis +# Synopsis + `#include `
-` double atan2(double y, double x);`
+`double atan2(double y, double x);`
-` float atan2f(float y, float x);`
+`float atan2f(float y, float x);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description These functions shall compute the principal value of the arc tangent of _y_/_x_, using the signs of both arguments to determine the quadrant of the return value. @@ -19,7 +23,6 @@ An application wishing to check for error situations should set `errno` to zero `feclearexcept(FE_ALL_EXCEPT)` before calling these functions. On return, if `errno` is non-zero or `fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)` is non-zero, an error has occurred. - ## Return value Upon successful completion, these functions shall return the arc tangent of _y_/_x_ in the range `[-PI,PI]` radians. @@ -36,7 +39,8 @@ Upon successful completion, these functions shall return the arc tangent of _y_/ * If either _x_ or _y_ is `NaN`, a `NaN` shall be returned. -* If the correct value would cause underflow, a range error may occur, and `atan()`, `atan2f()`, and `atan2l()` shall return an implementation-defined value no greater in magnitude than `DBL_MIN`, `FLT_MIN`, and `LDBL_MIN`, respectively. +* If the correct value would cause underflow, a range error may occur, and `atan()`, `atan2f()`, and `atan2l()` shall +return an implementation-defined value no greater in magnitude than `DBL_MIN`, `FLT_MIN`, and `LDBL_MIN`, respectively. * If the `IEC 60559` Floating-Point option is supported, _y_/_x_ should be returned. @@ -58,20 +62,15 @@ Upon successful completion, these functions shall return the arc tangent of _y_/ ## Errors - These functions may fail if: * Range Error - - The result underflows. - - If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the underflow floating-point exception -shall be raised. - - - + The result underflows. + If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. + If the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the underflow + floating-point exception shall be raised. ## Tests @@ -81,6 +80,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/a/atexit.part-impl.md b/libc/functions/a/atexit.part-impl.md index 2c427f98..2563db10 100644 --- a/libc/functions/a/atexit.part-impl.md +++ b/libc/functions/a/atexit.part-impl.md @@ -1,24 +1,29 @@ -# Synopsis +# Synopsis + `#include `
-` int atexit(void (*func)(void));`
+`int atexit(void (*func)(void));`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The purpose is to register a function to run at process termination. The `atexit()` function shall register the function pointed to by _func_, to be called without arguments at normal -program termination. At normal program termination, all functions registered by the `atexit()` function shall be called, in -the reverse order of their registration, except that a function is called after any previously registered functions that had -already been called at the time it was registered. Normal termination occurs either by a call to `exit()` or a return from `main()`. +The purpose is to register a function to run at process termination. The `atexit()` function shall register the function +pointed to by _func_, to be called without arguments at normal +program termination. At normal program termination, all functions registered by the `atexit()` function shall be called, +in the reverse order of their registration, except that a function is called after any previously registered functions +that had already been called at the time it was registered. Normal termination occurs either by a call to `exit()` +or a return from `main()`. At least 32 functions can be registered with `atexit()`. After a successful call to any of the exec functions, any functions previously -registered by `atexit()` shall no longer be registered. - +registered by `atexit()` shall no longer be registered. ## Return value @@ -26,10 +31,8 @@ Upon successful completion, `atexit()` shall return `0`, otherwise, it shall ret ## Errors - No errors are defined. - ## Tests Untested @@ -38,6 +41,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/a/atof.part-impl.md b/libc/functions/a/atof.part-impl.md index 776da940..0c1be045 100644 --- a/libc/functions/a/atof.part-impl.md +++ b/libc/functions/a/atof.part-impl.md @@ -1,35 +1,33 @@ -# Synopsis +# Synopsis + `#include `
-` double atof(const char *str);`
+`double atof(const char *str);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The purpose is to convert a string to a double-precision number. The call `atol(str)` shall be equivalent to: `strtod(str,(char **)NULL)`, - except that the handling of errors may differ. If the value cannot be represented, the behavior is undefined. - ## Return value The `atof()` function shall return the converted value if the value can be represented. ## Errors - No errors are defined. - - - ## Tests Untested @@ -38,6 +36,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/a/atoi.part-impl.md b/libc/functions/a/atoi.part-impl.md index 7d927b0a..307f5a1c 100644 --- a/libc/functions/a/atoi.part-impl.md +++ b/libc/functions/a/atoi.part-impl.md @@ -1,36 +1,33 @@ -# Synopsis +# Synopsis + `#include `
-` int atoi(const char *str);`
+`int atoi(const char *str);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The purpose is to convert a string to an integer. The call `atoi(str)` shall be equivalent to: `(int) strtol(str, (char **)NULL, 10)` - except that the handling of errors may differ. If the value cannot be represented, the behavior is undefined. - ## Return value The `atoi()` function shall return the converted value if the value can be represented. - ## Errors - No errors are defined. - - - ## Tests Untested @@ -39,6 +36,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/a/atol.part-impl.md b/libc/functions/a/atol.part-impl.md index f70e93c7..b5b0edfc 100644 --- a/libc/functions/a/atol.part-impl.md +++ b/libc/functions/a/atol.part-impl.md @@ -1,32 +1,34 @@ -# Synopsis +# Synopsis + `#include `
-` long atol(const char *nptr);`
+`long atol(const char *nptr);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The purpose is to convert a string to a long integer. Except as noted below, the call `atol(nptr)` shall be equivalent to: +The purpose is to convert a string to a long integer. Except as noted below, the call `atol(nptr)` +shall be equivalent to: `strtol(`_`nptr`_`, (char **)NULL, 10)` The handling of errors may differ. If the value cannot be represented, the behavior is undefined. - ## Return value This function shall return the converted value if the value can be represented. ## Errors - No errors are defined. - ## Tests Untested @@ -35,6 +37,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/b/basename.impl.md b/libc/functions/b/basename.impl.md index e37e1a63..3308e4e5 100644 --- a/libc/functions/b/basename.impl.md +++ b/libc/functions/b/basename.impl.md @@ -1,22 +1,26 @@ -###Synopsis +### Synopsis + `#include ` `char *basename(char *path);` -###Description +### Description -The `basename()` function takes the pathname pointed to by path and returns a pointer to the final component of the pathname, deleting any trailing '/' characters. +The `basename()` function takes the pathname pointed to by _path_ and returns a pointer to the final component of +the pathname, deleting any trailing '/' characters. Arguments: -path - the pathname to be stripped. +_path_ - the pathname to be stripped. + +If the string pointed to by _path_ consists entirely of the '/' character, `basename()` returns a pointer to the +string "/". If the string pointed to by _path_ is exactly "//", "/" is returned. -If the string pointed to by path consists entirely of the '/' character, `basename()` returns a pointer to the string "/". If the string pointed to by path is exactly "//", "/" is returned. +If _path_ is a null pointer or points to an empty string, `basename()` returns a pointer to the string ".". -If path is a null pointer or points to an empty string, `basename()` returns a pointer to the string ".". +### Return value -###Return value -The basename() function shall return a pointer to the final component of path. +The basename() function shall return a pointer to the final component of _path_. -###Errors +### Errors No errors are defined. diff --git a/libc/functions/b/bind.part-impl.md b/libc/functions/b/bind.part-impl.md index 6b761480..f58b61bc 100644 --- a/libc/functions/b/bind.part-impl.md +++ b/libc/functions/b/bind.part-impl.md @@ -20,11 +20,14 @@ The `bind()` function binds a name to socket `socket`. `socket` - the file descriptor of the socket. -`address` - the pointer to a sockaddr structure containing the address to be bound to the socket. The length and format of the address depend on the address family of the socket. +`address` - the pointer to a sockaddr structure containing the address to be bound to the socket. The length and format +of the address depend on the address family of the socket. `address_len` - the length of the `sockaddr` structure pointed to by the `address` argument. -The `bind()` function assigns a local socket address `address` to a socket identified by descriptor `socket` that has no local socket address assigned. Sockets created with the `socket()` function are initially unnamed; they are identified only by their address family. +The `bind()` function assigns a local socket address `address` to a socket identified by descriptor `socket` that has no +local socket address assigned. Sockets created with the `socket()` function are initially unnamed; they are identified +only by their address family. ## Return value @@ -44,9 +47,11 @@ The `bind()` function assigns a local socket address `address` to a socket ident [`EBADF`] - the socket argument is not a valid file descriptor. -[`EINPROGRESS`] - `O_NONBLOCK` is set for the file descriptor for the socket and the assignment cannot be immediately performed; the assignment is performed asynchronously. +[`EINPROGRESS`] - `O_NONBLOCK` is set for the file descriptor for the socket and the assignment cannot be immediately +performed; the assignment is performed asynchronously. -[`EINVAL`] - the socket is already bound to an address, and the protocol does not support binding to a new address; or the socket has been shut down. +[`EINVAL`] - the socket is already bound to an address, and the protocol does not support binding to a new address; or +the socket has been shut down. [`ENOBUFS`] - insufficient resources were available to complete the call. @@ -62,11 +67,13 @@ The `bind()` function assigns a local socket address `address` to a socket ident [`ELOOP`] - more than {`SYMLOOP_MAX`} symbolic links were encountered during resolution of the pathname in `address<`. -[`ENAMETOOLONG`] - the length of a pathname exceeds {`PATH_MAX`}, or pathname resolution of a symbolic link produced an intermediate result with a length that exceeds {`PATH_MAX`}. +[`ENAMETOOLONG`] - the length of a pathname exceeds {`PATH_MAX`}, or pathname resolution of a symbolic link produced an +intermediate result with a length that exceeds {`PATH_MAX`}. If the address family of the socket is `AF_UNIX`, then `bind()` fails if: -[`EACCES`] - a component of the path prefix denies search permission, or the requested name requires writing in a directory with a mode that denies write permission. +[`EACCES`] - a component of the path prefix denies search permission, or the requested name requires writing in a +directory with a mode that denies write permission. [`EDESTADDRREQ`] or [`EISDIR`] - the `address` argument is a null pointer. @@ -76,11 +83,17 @@ If the address family of the socket is `AF_UNIX`, then `bind()` fails if: [`ENAMETOOLONG`] - the length of a component of a pathname is longer than {`NAME_MAX`}. -[`ENOENT`] - a component of the path prefix of the pathname in `address` does not name an existing file or the pathname is an empty string. +[`ENOENT`] - a component of the path prefix of the pathname in `address` does not name an existing file or the pathname +is an empty string. -[`ENOENT`] or [`ENOTDIR`] - the pathname in `address` contains at least one non- / character and ends with one or more trailing / characters. If the pathname without the trailing / characters would name an existing file, an [`ENOENT`] error shall not occur. +[`ENOENT`] or [`ENOTDIR`] - the pathname in `address` contains at least one non- / character and ends with one or more +trailing / characters. If the pathname without the trailing / characters would name an existing file, +an [`ENOENT`] error shall not occur. -[`ENOTDIR`] - a component of the path prefix of the pathname in `address` names an existing file that is neither a directory nor a symbolic link to a directory, or the pathname in `address` contains at least one non- / character and ends with one or more trailing / characters and the last pathname component names an existing file that is neither a directory nor a symbolic link to a directory. +[`ENOTDIR`] - a component of the path prefix of the pathname in `address` names an existing file that is neither a +directory nor a symbolic link to a directory, or the pathname in `address` contains at least one non- / character and +ends with one or more trailing / characters and the last pathname component names an existing file that is neither a +directory nor a symbolic link to a directory. [`EROFS`] - the name would reside on a read-only file system. diff --git a/libc/functions/b/bsearch.impl.md b/libc/functions/b/bsearch.impl.md index 293cfb9e..bf97ee5b 100644 --- a/libc/functions/b/bsearch.impl.md +++ b/libc/functions/b/bsearch.impl.md @@ -1,29 +1,35 @@ -###Synopsis +# Synopsis `#include ` -`void *bsearch(const void *key, const void *base, size_t nitems, size_t size, int (*compar)(const void *, const void *));` +`void *bsearch(const void *key, const void *base, size_t nitems, size_t size, +int (*compar)(const void *, const void *));` -###Description +## Description The function searches an ascending order array (with binary search) for an element with specified value. Arguments: -key - a value to be found, -base - a pointer to the beginning of array area to be searched, -nitems - the number of array elements, -size - the number of bytes taken by each element, -compar - the comparison function. +_key_ - a value to be found, +_base_ - a pointer to the beginning of array area to be searched, +_nitems_ - the number of array elements, +_size_ - the number of bytes taken by each element, +_compar_ - the comparison function. -Function searches an array of nitems objects, the initial member of which is pointed to by base, for a member that matches the object pointed to by key. The size (in bytes) of each member of the array is specified by size. +Function searches an array of _nitems_ objects, the initial member of which is pointed to by _base_, for a +member that matches the object pointed to by _key_. The size (in bytes) of each member of the array is specified +by _size_. -The contents of the array should be in ascending sorted order according to the comparison function referenced by `compar`. The `compar` routine is expected to have two arguments which point to the key object and to an array member, in that order. It should return an integer which is less than, equal to, or greater than zero if the key object is found, respectively, to be less than, to match, or be greater than the array member. +The contents of the array should be in ascending sorted order according to the comparison function referenced by +`compar`. The `compar` routine is expected to have two arguments which point to the key object and to an array member, +in that order. It should return an integer which is less than, equal to, or greater than zero if the key object is +found, respectively, to be less than, to match, or be greater than the array member. -###Return value +### Return value The function returns a pointer to a matching member of the array, or a null pointer if no match is found. If two members compare as equal, which member is matched is unspecified. -###Errors +### Errors -No errors are defined. \ No newline at end of file +No errors are defined. diff --git a/libc/functions/c/calloc.part-impl.md b/libc/functions/c/calloc.part-impl.md index 5cbef575..71ee4a31 100644 --- a/libc/functions/c/calloc.part-impl.md +++ b/libc/functions/c/calloc.part-impl.md @@ -1,46 +1,50 @@ -# Synopsis -`#include `
+# Synopsis -` void *calloc(size_t nelem, size_t elsize);`
+`#include ` + +`void *calloc(size_t nelem, size_t elsize);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The purpose is to allocate a memory. The `calloc()` function shall allocate unused space for an array of _nelem_ elements each of whose size in bytes is +The purpose is to allocate a memory. The `calloc()` function shall allocate unused space for an array of _nelem_ +elements each of whose size in bytes is _elsize_. The space shall be initialized to all bits `0`. -The order and contiguity of storage allocated by successive calls to `calloc()` is unspecified. The pointer returned if the -allocation succeeds shall be suitably aligned so that it may be assigned to a pointer to any type of object and then used to access -such an object or an array of such objects in the space allocated (until the space is explicitly freed or reallocated). Each such -allocation shall yield a pointer to an object disjoint from any other object. The pointer returned shall point to the start (lowest -byte address) of the allocated space. If the space cannot be allocated, a `null` pointer shall be returned. If the size of the space -requested is `0`, the behavior is implementation-defined: either a `null` pointer shall be returned, or the behavior shall be as if the -size were some non-zero value, except that the behavior is undefined if the returned pointer is used to access an object. - +The order and contiguity of storage allocated by successive calls to `calloc()` is unspecified. The pointer returned if +the allocation succeeds shall be suitably aligned so that it may be assigned to a pointer to any type of object and then +used to access such an object or an array of such objects in the space allocated (until the space is explicitly freed or +reallocated). Each such allocation shall yield a pointer to an object disjoint from any other object. The pointer +returned shall point to the start (lowest byte address) of the allocated space. If the space cannot be allocated, a +`null` pointer shall be returned. If the size of the space +requested is `0`, the behavior is implementation-defined: either a `null` pointer shall be returned, or the behavior +shall be as if the size were some non-zero value, except that the behavior is undefined if the returned pointer is used +to access an object. ## Return value - -Upon successful completion with both _nelem_ and _elsize_ non-zero, `calloc()` shall return a pointer to the allocated space. If either _nelem_ or _elsize_ is `0`, then either: +Upon successful completion with both _nelem_ and _elsize_ non-zero, `calloc()` shall return a pointer to the allocated +space. If either _nelem_ or _elsize_ is `0`, then either: * A `null` pointer shall be returned and `errno` may be set to an implementation-defined value, or -* A pointer to the allocated space shall be returned. The application shall ensure that the pointer is not used to access an object. +* A pointer to the allocated space shall be returned. The application shall ensure that the pointer is not used to +access an object. Otherwise, it shall return a `null` pointer and set `errno` to indicate the error. ## Errors - The `calloc()` function shall fail if: - - * `ENOMEM` - Insufficient memory is available. - +* `ENOMEM` - Insufficient memory is available. ## Tests @@ -50,6 +54,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/c/ceil.part-impl.md b/libc/functions/c/ceil.part-impl.md index acf51053..55f70634 100644 --- a/libc/functions/c/ceil.part-impl.md +++ b/libc/functions/c/ceil.part-impl.md @@ -1,38 +1,38 @@ -# Synopsis +# Synopsis + `#include `
-` double ceil(double x);`
+`double ceil(double x);`
-` float ceilf(float x);`
+`float ceilf(float x);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description These functions shall compute the smallest integral value not less than _x_. - ## Return value The result shall have the same sign as _x_. -Upon successful completion, `ceil()` and `ceilf()` shall return the smallest integral value not less than _x_, expressed as a type double, float, or long double, respectively. +Upon successful completion, `ceil()` and `ceilf()` shall return the smallest integral value not less than _x_, expressed +as a type double, float, or long double, respectively. * If _x_ is `NaN`, a `NaN` shall be returned. * If _x_ is `±0` or `±Inf`, _x_ shall be returned. - ## Errors - No errors are defined. - - ## Tests Untested @@ -41,6 +41,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/c/chdir.part-impl.md b/libc/functions/c/chdir.part-impl.md index 533009f5..052c0a7a 100644 --- a/libc/functions/c/chdir.part-impl.md +++ b/libc/functions/c/chdir.part-impl.md @@ -1,48 +1,49 @@ -# Synopsis +# Synopsis + `#include `
-` int chdir(const char *path);`
+`int chdir(const char *path);`
## Status + Partially implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 -The purpose is to change working directory. The `chdir()` function shall cause the directory named by the pathname pointed to by the _path_ argument to become the -current working directory, that is, the starting point for path searches for pathnames not beginning with `'/'`. +## Description +The purpose is to change working directory. The `chdir()` function shall cause the directory named by the pathname +pointed to by the _path_ argument to become the current working directory, that is, the starting point for path searches +for pathnames not beginning with `'/'`. ## Return value - -Upon successful completion, `0` shall be returned. Otherwise, `-1` shall be returned, the current working directory shall remain unchanged, and `errno` shall be set to indicate the error. - +Upon successful completion, `0` shall be returned. Otherwise, `-1` shall be returned, the current working directory +shall remain unchanged, and `errno` shall be set to indicate the error. ## Errors - The `chdir()` function shall fail if: +* `EACCES` - Search permission is denied for any component of the pathname. - * `EACCES` - Search permission is denied for any component of the pathname. - - * `ELOOP` - A loop exists in symbolic links encountered during resolution of the _path_ argument. +* `ELOOP` - A loop exists in symbolic links encountered during resolution of the _path_ argument. - * `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. +* `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. - * `ENOENT` - A component of _path_ does not name an existing directory or path is an empty string. +* `ENOENT` - A component of _path_ does not name an existing directory or path is an empty string. - * `ENOTDIR` - A component of the pathname names an existing file that is neither a directory nor a symbolic link to a directory. +* `ENOTDIR` - A component of the pathname names an existing file that is neither a directory nor a symbolic link + to a directory. The `chdir()` function may fail if: +* `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the _path_ argument. - * `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the _path_ argument. - - * `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an intermediate result with alength that exceeds `PATH_MAX`. - +* `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an + intermediate result with alength that exceeds `PATH_MAX`. ## Tests @@ -52,6 +53,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/c/clearenv.part-impl.md b/libc/functions/c/clearenv.part-impl.md index 62bbbfd8..6da89812 100644 --- a/libc/functions/c/clearenv.part-impl.md +++ b/libc/functions/c/clearenv.part-impl.md @@ -1,27 +1,28 @@ -# Synopsis +# Synopsis + `#include `
`int clearenv(void);`
## Status + Partially implemented + ## Conformance -Various UNIX variants (DG/UX, HP-UX, QNX, ...) -## Description +Various UNIX variants (DG/UX, HP-UX, QNX, ...) -The `clearenv()` function clears the environment of all name-value pairs and sets the value of the external variable environ to `NULL`. After this call, new variables can be added to the environment using `putenv()` and `setenv()`. +## Description +The `clearenv()` function clears the environment of all name-value pairs and sets the value of the external variable +environ to `NULL`. After this call, new variables can be added to the environment using `putenv()` and `setenv()`. ## Return value - Upon successful completion, zero shall be returned. - ## Errors - ## Tests Tested @@ -30,6 +31,7 @@ Tested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/c/clearerr.part-impl.md b/libc/functions/c/clearerr.part-impl.md index 76b783d3..fe80b5c0 100644 --- a/libc/functions/c/clearerr.part-impl.md +++ b/libc/functions/c/clearerr.part-impl.md @@ -1,33 +1,31 @@ -# Synopsis +# Synopsis + `#include `
-` void clearerr(FILE *stream);`
+`void clearerr(FILE *stream);`
## Status + Partially implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 -The purpose is to clear indicators on a stream. The `clearerr()` function shall clear the end-of-file and error indicators for the stream to which _stream_ -points. -The `clearerr()` function shall not change the setting of `errno` if stream is valid. +## Description +The purpose is to clear indicators on a stream. The `clearerr()` function shall clear the end-of-file and error +indicators for the stream to which _stream_ points. +The `clearerr()` function shall not change the setting of `errno` if stream is valid. ## Return value The `clearerr()` function shall not return a value. - ## Errors - No errors are defined. - - - ## Tests Untested @@ -36,6 +34,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/c/close.part-impl.md b/libc/functions/c/close.part-impl.md index b06e2eae..16c6ab4f 100644 --- a/libc/functions/c/close.part-impl.md +++ b/libc/functions/c/close.part-impl.md @@ -1,88 +1,90 @@ -# Synopsis +# Synopsis + `#include `
-` int close(int fildes);`
+`int close(int fildes);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The purpose is to close a file descriptor. The `close()` function shall deallocate the file descriptor indicated by _fildes_. To deallocate means to make the -file descriptor available for return by subsequent calls to `open()` or other functions -that allocate file descriptors. All outstanding record locks owned by the process on the file associated with the file descriptor -shall be removed (that is, unlocked). +The purpose is to close a file descriptor. The `close()` function shall deallocate the file descriptor indicated by +_fildes_. To deallocate means to make the file descriptor available for return by subsequent calls to `open()` or other +functions that allocate file descriptors. All outstanding record locks owned by the process on the file associated with +the file descriptor shall be removed (that is, unlocked). If `close()` is interrupted by a signal that is to be caught, it shall return `-1` with `errno` set to `EINTR` and the state of _fildes_ is unspecified. If an `I/O` error occurred while reading from or writing to the file system during `close()`, it may return `-1` with errno set to `EIO`, if this error is returned, the state of _fildes_ is unspecified. -When all file descriptors associated with a pipe or `FIFO` special file are closed, any data remaining in the pipe or `FIFO` shall -be discarded. +When all file descriptors associated with a pipe or `FIFO` special file are closed, any data remaining in the pipe or +`FIFO` shall be discarded. When all file descriptors associated with an open file description have been closed, the open file description shall be freed. -If the link count of the file is `0`, when all file descriptors associated with the file are closed, the space occupied by the -file shall be freed and the file shall no longer be accessible. -If a `STREAMS`-based _fildes_ is closed and the calling process was previously registered to receive a SIGPOLL signal for -events associated with that `STREAM`, the calling process shall be unregistered for events associated with the `STREAM`. The last -`close()` for a `STREAM` shall cause the `STREAM` associated with _fildes_ to be dismantled. If `O_NONBLOCK` is not set and -there have been no signals posted for the `STREAM`, and if there is data on the module's write queue, `close()` shall wait for -an unspecified time (for each module and driver) for any output to drain before dismantling the `STREAM`. The time delay can be -changed via an `I_SETCLTIME` `ioctl()` request. If the `O_NONBLOCK` flag is set, or if there -are any pending signals, `close()` shall not wait for output to drain, and shall dismantle the `STREAM` immediately. +If the link count of the file is `0`, when all file descriptors associated with the file are closed, the space occupied +by the file shall be freed and the file shall no longer be accessible. +If a `STREAMS`-based _fildes_ is closed and the calling process was previously registered to receive a SIGPOLL signal +for events associated with that `STREAM`, the calling process shall be unregistered for events associated with the +`STREAM`. The last `close()` for a `STREAM` shall cause the `STREAM` associated with _fildes_ to be dismantled. +If `O_NONBLOCK` is not set and there have been no signals posted for the `STREAM`, and if there is data on the module's +write queue, `close()` shall wait for an unspecified time (for each module and driver) for any output to drain before +dismantling the `STREAM`. The time delay can be changed via an `I_SETCLTIME` `ioctl()` request. If the `O_NONBLOCK` +flag is set, or if there are any pending signals, `close()` shall not wait for output to drain, and shall dismantle the +`STREAM` immediately. If the implementation supports `STREAMS`-based pipes, and _fildes_ is associated with one end of a pipe, the last -`close()` shall cause a hangup to occur on the other end of the pipe. In addition, if the other end of the pipe has been named -by `fattach()`, then the last `close()` shall force the named end to be detached -by `fdetach()`. If the named end has no open file descriptors associated with it and -gets detached, the STREAM associated with that end shall also be dismantled. -If _fildes_ refers to the master side of a pseudo-terminal, and this is the last close, a `SIGHUP` signal shall be sent to the -controlling process, if any, for which the slave side of the pseudo-terminal is the controlling terminal. It is unspecified whether -closing the master side of the pseudo-terminal flushes all queued input and output. -If _fildes_ refers to the slave side of a `STREAMS`-based pseudo-terminal, a zero-length message may be sent to the master. - -When there is an outstanding cancelable asynchronous `I/O` operation against _fildes_ when `close()` is called, that `I/O` -operation may be canceled. An `I/O` operation that is not canceled completes as if the `close()` operation had not yet occurred. +`close()` shall cause a hangup to occur on the other end of the pipe. In addition, if the other end of the pipe has been +named by `fattach()`, then the last `close()` shall force the named end to be detached by `fdetach()`. If the named end +has no open file descriptors associated with it and gets detached, the STREAM associated with that end shall also be +dismantled. If _fildes_ refers to the master side of a pseudo-terminal, and this is the last close, a `SIGHUP` +signal shall be sent to the controlling process, if any, for which the slave side of the pseudo-terminal is the +controlling terminal. It is unspecified whether closing the master side of the pseudo-terminal flushes all queued input +and output. If _fildes_ refers to the slave side of a `STREAMS`-based pseudo-terminal, a zero-length message may be +sent to the master. + +When there is an outstanding cancelable asynchronous `I/O` operation against _fildes_ when `close()` is called, +that `I/O` operation may be canceled. An `I/O` operation that is not canceled completes as if the `close()` +operation had not yet occurred. All operations that are not canceled shall complete as if the `close()` blocked until the operations completed. The -`close()` operation itself need not block awaiting such `I/O` completion. Whether any `I/O` operation is canceled, and which `I/O` -operation may be canceled upon `close()`, is implementation-defined. +`close()` operation itself need not block awaiting such `I/O` completion. Whether any `I/O` operation is canceled, +and which `I/O` operation may be canceled upon `close()`, is implementation-defined. -If a memory mapped file or a shared memory object -remains referenced at the last close (that is, a process has it mapped), then the entire contents of the memory object shall -persist until the memory object becomes unreferenced. If this is the last close of a memory mapped file or a shared -memory object  and the close results in the memory object +If a memory mapped file or a shared memory object +remains referenced at the last close (that is, a process has it mapped), then the entire contents of the memory object +shall persist until the memory object becomes unreferenced. If this is the last close of a +memory mapped file or a shared memory object  and the close results in the memory object becoming unreferenced, and the memory object has been unlinked, then the memory object shall be removed. If _fildes_ refers to a socket, `close()` shall cause the socket to be destroyed. If the socket is in connection-mode, and the `SO_LINGER` option is set for the socket with non-zero linger time, and the socket has untransmitted data, then `close()` shall block for up to the current linger interval until all data is transmitted. - ## Return value -Upon successful completion, `0` shall be returned, otherwise, `-1` shall be returned and `errno` set to indicate the error. +Upon successful completion, `0` shall be returned, otherwise, +`-1` shall be returned and `errno` set to indicate the error. ## Errors - The `close()` function shall fail if: +* `EBADF` - The _fildes_ argument is not a open file descriptor. - * `EBADF` - The _fildes_ argument is not a open file descriptor. - - * `EINTR` - The `close()` function was interrupted by a signal. +* `EINTR` - The `close()` function was interrupted by a signal. The `close()` function may fail if: - - * `EIO` - An I/O error occurred while reading from or writing to the file system. - +* `EIO` - An I/O error occurred while reading from or writing to the file system. ## Tests @@ -92,6 +94,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/c/closedir.part-impl.md b/libc/functions/c/closedir.part-impl.md index 150b2e4c..5824b355 100644 --- a/libc/functions/c/closedir.part-impl.md +++ b/libc/functions/c/closedir.part-impl.md @@ -1,37 +1,35 @@ -# Synopsis +# Synopsis + `#include `
-` int closedir(DIR *dirp);`
+`int closedir(DIR *dirp);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `closedir()` function shall close the directory stream referred to by the argument _dirp_. Upon return, the value of _dirp_ may no longer point to an accessible object of the type `DIR`. If a file descriptor is used to implement type `DIR`, that file descriptor shall be closed. - ## Return value -Upon successful completion, `closedir()` shall return `0`, otherwise, `-1` shall be returned and `errno` set to indicate the error. +Upon successful completion, `closedir()` shall return `0`, otherwise, `-1` shall be returned and `errno` +set to indicate the error. ## Errors - The `closedir()` function may fail if: +* `EBADF` - The _dirp_ argument does not refer to an open directory stream. - * `EBADF` - The _dirp_ argument does not refer to an open directory stream. - - * `EINTR` - The `closedir()` function was interrupted by a signal. - - - - +* `EINTR` - The `closedir()` function was interrupted by a signal. ## Tests @@ -41,6 +39,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/c/closelog.md b/libc/functions/c/closelog.md index 6a87faf2..1fa1e439 100644 --- a/libc/functions/c/closelog.md +++ b/libc/functions/c/closelog.md @@ -16,33 +16,40 @@ Fully implemented. ## Compliance - ## Description All these functions operate on the log file. The `syslog()` function sends a message to the logging facility (`/dev/log`). -The `openlog()` function sets process attributes that affect subsequent calls to syslog(). +The `openlog()` function sets process attributes that affect subsequent calls to syslog(). -The `setlogmask()` function sets the log priority mask for the current process to maskpri and returns the previous mask. +The `setlogmask()` function sets the log priority mask for the current process to _maskpri_ and +returns the previous mask. The `closelog()` function closes any open file descriptors allocated by previous calls to `openlog()` or `syslog()`. -## Arguments: +## Arguments -$ident$ - a string that is written to all logs identifying the function or the situation, which generated the current log. +$ident$ - a string that is written to all logs identifying the function or the situation, which generated the current +log. -logopt - logging options, +_logopt_ - logging options, -facility - a logging facility, -maskpri - a log priority mask, +_facility_ - a logging facility, +_maskpri_ - a log priority mask, -priority - a priority of the log, -message - a message to be put to the log. +_priority_ - a priority of the log, +_message_ - a message to be put to the log. -The `syslog()` function sends a message to the logging facility (`/dev/log`). The logged message includes a message header and a message body. The message header contains a timestamp and a tag string. If logging device is not available, `syslog()` function puts the message to `stderr`. -The message body is generated from the message and arguments in the same manner as if these were arguments to `printf()`, except that the additional conversion specification `%m` is recognized; it converts no arguments, causes the output of the error message string associated with the value of `errno` on entry to `syslog()`, and may be mixed with argument specifications of the "%n$" form. If a complete conversion specification with the `m` conversion specifier character is not just `%m`, the behaviour is undefined. A trailing is also added. +The `syslog()` function sends a message to the logging facility (`/dev/log`). The logged message includes a message +header and a message body. The message header contains a timestamp and a tag string. If logging device is not available, +`syslog()` function puts the message to `stderr`. +The message body is generated from the message and arguments in the same manner as if these were arguments to +`printf()`, except that the additional conversion specification `%m` is recognized; it converts no arguments, causes +the output of the error message string associated with the value of `errno` on entry to `syslog()`, and may be mixed +with argument specifications of the "%n$" form. If a complete conversion specification with the `m` conversion specifier +character is not just `%m`, the behaviour is undefined. A trailing is also added. As a severity level one of the following values is used: `LOG_EMERG` A panic condition. @@ -55,9 +62,10 @@ As a severity level one of the following values is used: `LOG_WARNING` Warning messages. `LOG_NOTICE` Conditions that are not error conditions, but that may require special handling. `LOG_INFO` Informational messages. -`LOG_DEBUG` Messages that contain information normally of use only when debugging a program. +`LOG_DEBUG` Messages that contain information normally of use only when debugging a program. -Values of the priority argument are formed by OR'ing together a severity-level value and an optional facility value. If no facility value is specified, the current default facility value is used. +Values of the priority argument are formed by OR'ing together a severity-level value and an optional facility value. +If no facility value is specified, the current default facility value is used. The facility indicates the application or system component generating the message. Possible facility values include: @@ -65,39 +73,48 @@ The facility indicates the application or system component generating the messag `LOG_LOCAL0` Reserved for local use. `LOG_LOCAL1` Reserved for local use. `LOG_LOCAL2` Reserved for local use. -`LOG_LOCAL3` Reserved for local use. +`LOG_LOCAL3` Reserved for local use. `LOG_LOCAL4` Reserved for local use. `LOG_LOCAL5` Reserved for local use. `LOG_LOCAL6` Reserved for local use. -`LOG_LOCAL7` Reserved for local use. +`LOG_LOCAL7` Reserved for local use. -The `openlog()` function sets process attributes that affect subsequent calls to `syslog()` that is among others the path to the log file and a default facility. +The `openlog()` function sets process attributes that affect subsequent calls to `syslog()` that is among others the +path to the log file and a default facility. -The logopt argument indicates logging options. Values for logopt are constructed by a bitwise-inclusive OR of zero or more of the following: +The _logopt_ argument indicates logging options. Values for _logopt_ are constructed by a bitwise-inclusive OR +of zero or more of the following: `LOG_PID` Log the process ID with each message. This is useful for identifying specific processes. -`LOG_CONS` Write messages to the system console if they cannot be sent to the logging facility. The `syslog()` function ensures that the process does not acquire the console as a controlling terminal in the process of writing the message. -`LOG_NDELAY` Open the connection to the logging facility immediately. Normally the open is delayed until the first message is logged. This is useful for programs that need to manage the order in which file descriptors are allocated. +`LOG_CONS` Write messages to the system console if they cannot be sent to the logging facility. The `syslog()` +function ensures that the process does not acquire the console as a controlling terminal in the process of +writing the message. +`LOG_NDELAY` Open the connection to the logging facility immediately. Normally the open is delayed until the first +message is logged. This is useful for programs that need to manage the order in which file descriptors are allocated. `LOG_ODELAY` Delay open until `syslog()` is called. -`LOG_NOWAIT` Do not wait for child processes that may have been created during the course of logging the message. This option should be used by processes that enable notification of child termination using `SIGCHLD`, since `syslog()` may otherwise block waiting for a child whose exit status has already been collected. - +`LOG_NOWAIT` Do not wait for child processes that may have been created during the course of logging the message. +This option should be used by processes that enable notification of child termination using `SIGCHLD`, since `syslog()` +may otherwise block waiting for a child whose exit status has already been collected. The `closelog()` function closes any open file descriptors allocated by previous calls to `openlog()` or `syslog()`. -The `setlogmask()` function sets the log priority mask for the current process to maskpri and returns the previous mask. If the maskpri argument is `0`, the current log mask is not modified. Calls by the current process to `syslog()` with a priority not set in maskpri are rejected. The default log mask allows all priorities to be logged. A call to `openlog()` is not required prior to calling `setlogmask()`. - -Symbolic constants for use as values of the logopt, facility, priority, and maskpri arguments are defined in the <`syslog.h`> header. +The `setlogmask()` function sets the log priority mask for the current process to _maskpri_ and returns +the previous mask. If the _maskpri_ argument is `0`, the current log mask is not modified. Calls by the current +process to `syslog()` with a priority not set in _maskpri_ are rejected. The default log mask allows all priorities +to be logged. A call to `openlog()` is not required prior to calling `setlogmask()`. +Symbolic constants for use as values of the _logopt_, _facility_, _priority_, and _maskpri_ +arguments are defined in the <`syslog.h`> header. ## Return value The `closelog()`, `openlog()`, and `syslog()` functions do not return a value. -The `setlogmask()` function returns the previous log priority mask. +The `setlogmask()` function returns the previous log priority mask. ## Errors -No errors are defined. +No errors are defined. ## Implementation tasks -* \ No newline at end of file +* diff --git a/libc/functions/c/condCreate.phrtos.md b/libc/functions/c/condCreate.phrtos.md index 68028eb2..b6c3002d 100644 --- a/libc/functions/c/condCreate.phrtos.md +++ b/libc/functions/c/condCreate.phrtos.md @@ -1,30 +1,34 @@ -# Synopsis +# Synopsis + `#include ` `int condCreate(handle_t *h);` ## Status + Implemented + ## Conformance + Phoenix-RTOS specific + ## Description -The `condCreate()` function shall initialize the condition variable referenced by _h_. Upon successful initialization, the state of the -condition variable shall become initialized. +The `condCreate()` function shall initialize the condition variable referenced by _h_. Upon successful initialization, +the state of the condition variable shall become initialized. Attempting to initialize an already initialized condition variable results in undefined behavior. ## Return value -If successful, the `condCreate()` function shall return zero; otherwise, an error number shall be returned to indicate the error. - +If successful, the `condCreate()` function shall return zero; otherwise, +an error number shall be returned to indicate the error. ## Errors - The `condCreate()` function shall fail if: - * `-ENOMEM` - Insufficient memory exists to initialize the condition variable. +* `-ENOMEM` - Insufficient memory exists to initialize the condition variable. These functions shall not return an error code of `EINTR`. @@ -36,6 +40,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/c/condSignal.phrtos.md b/libc/functions/c/condSignal.phrtos.md index 0e42a2fc..f091b2c3 100644 --- a/libc/functions/c/condSignal.phrtos.md +++ b/libc/functions/c/condSignal.phrtos.md @@ -1,16 +1,20 @@ -# Synopsis +# Synopsis + `#include ` -` int condBroadcast(handle_t h);` +`int condBroadcast(handle_t h);` -` int condSignal(handle_t h);` +`int condSignal(handle_t h);` ## Status + Implemented + ## Conformance + Phoenix-RTOS specific -## Description +## Description These functions shall unblock threads blocked on a condition variable. @@ -19,16 +23,15 @@ The `condBroadcast()` function shall unblock all threads currently blocked on th The `condSignal()` function shall unblock at least one of the threads that are blocked on the specified condition variable _h_ (if any threads are blocked on _h_). -If more than one thread is blocked on a condition variable, the scheduling policy shall determine the order in which threads are -unblocked. When each thread unblocked as a result of a `condBroadcast()` or `condSignal()` returns from -its call to `condWait()`, the thread shall own the mutex with which it called -`condWait()`. The thread(s) that are unblocked shall contend for -the mutex according to the scheduling policy (if applicable), and as if each had called `mutexLock()`. +If more than one thread is blocked on a condition variable, the scheduling policy shall determine the order in which +threads are unblocked. When each thread unblocked as a result of a `condBroadcast()` or `condSignal()` returns from its +call to `condWait()`, the thread shall own the mutex with which it called `condWait()`. The thread(s) that are unblocked +shall contend for the mutex according to the scheduling policy (if applicable), and as if each had called `mutexLock()`. The `condBroadcast()` or `condSignal()` functions may be called by a thread whether or not it currently owns the mutex that threads calling `condWait()` have associated with the condition variable -during their waits; however, if predictable scheduling behavior is required, then that mutex shall be locked by the thread calling -`condBroadcast()` or `condSignal()`. +during their waits; however, if predictable scheduling behavior is required, then that mutex shall be locked by the +thread calling `condBroadcast()` or `condSignal()`. When there is no thread waiting on condition invoking `condBroadcast()` and `condSignal()` internal condition state is changed. First condWait invoked on condition exits imidately without waiting. This property is known as being @@ -38,25 +41,21 @@ condition implementation ensures that signals sent without lock can be reliably The behavior is undefined if the value specified by the cond argument to `condBroadcast()` or `condSignal()` does not refer to an initialized condition variable. - ## Return value - If successful, the `condBroadcast()` and `condSignal()` functions shall return zero; otherwise, an error number shall be returned to indicate the error. - ## Errors The `condBroadcast()` and `condSignal()` function may fail if: - * `-EINVAL` - The value _h_ does not refer to an initialised condition variable. +* `-EINVAL` - The value _h_ does not refer to an initialised condition variable. - * `-EINVAL` - Parent process for _h_ variable ceased to exist during function call +* `-EINVAL` - Parent process for _h_ variable ceased to exist during function call These functions shall not return an error code of `-EINTR`. - ## Tests Untested @@ -65,6 +64,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/c/condWait.phrtos.md b/libc/functions/c/condWait.phrtos.md index 100f9688..546b75d3 100644 --- a/libc/functions/c/condWait.phrtos.md +++ b/libc/functions/c/condWait.phrtos.md @@ -1,65 +1,76 @@ -# Synopsis +# Synopsis + `#include `
`int condWait(handle_t h, handle_t m, time_t timeout);` ## Status + Implemented + ## Conformance + Phoenix-RTOS specific ## Description -The `condWait()` function shall block on a condition variable specified by _h_ until it is signaled or _timeout_ microseconds passes. The -application shall ensure that these functions are called with mutex _m_ locked by the calling thread; otherwise, an error or undefined behavior results. +The `condWait()` function shall block on a condition variable specified by _h_ until it is signaled or _timeout_ +microseconds passes. The application shall ensure that these functions are called with mutex _m_ locked by the calling +thread; otherwise, an error or undefined behavior results. These functions atomically release mutex and cause the calling thread to block on the condition variable _h_; -atomically here means "atomically with respect to access by another thread to the mutex _m_ and then the condition variable". That -is, if another thread is able to acquire the mutex after the about-to-block thread has released it, then a subsequent call to `condSignal()` or `condBroadcast()` in that thread shall behave as if it were issued after the -about-to-block thread has blocked. +atomically here means "atomically with respect to access by another thread to the mutex _m_ and then the condition +variable". That is, if another thread is able to acquire the mutex after the about-to-block thread has released it, +then a subsequent call to `condSignal()` or `condBroadcast()` in that thread shall behave as if it were issued after +the about-to-block thread has blocked. Upon successful return, the mutex _m_ shall have been locked and shall be owned by the calling thread. -When using condition variables there is always a Boolean predicate involving shared variables associated with each condition -wait that is true if the thread should proceed. Spurious wakeups from the `condWait()` functions may occur. Since the return from `condWait()` does not imply anything about the value of this predicate, the predicate should be re-evaluated upon such return. +When using condition variables there is always a Boolean predicate involving shared variables associated with each +condition wait that is true if the thread should proceed. Spurious wakeups from the `condWait()` functions may occur. +Since the return from `condWait()` does not imply anything about the value of this predicate, the predicate should be +re-evaluated upon such return. If condition was signaled when no thread was waiting on it first `condWait()` on it will return immediately. -When a thread waits on a condition variable, having specified a particular mutex to the `condWait()` operation, a dynamic binding is formed between that mutex and condition variable that remains in -effect as long as at least one thread is blocked on the condition variable. During this time, the effect of an attempt by any -thread to wait on that condition variable using a different mutex is undefined. Once all waiting threads have been unblocked (as by -the `condBroadcast()` operation), the next wait operation on -that condition variable shall form a new dynamic binding with the mutex specified by that wait operation. Even though the dynamic -binding between condition variable and mutex may be removed or replaced between the time a thread is unblocked from a wait on the -condition variable and the time that it returns to the caller or begins cancellation cleanup, the unblocked thread shall always -re-acquire the mutex specified in the condition wait operation call from which it is returning. +When a thread waits on a condition variable, having specified a particular mutex to the `condWait()` operation, a +dynamic binding is formed between that mutex and condition variable that remains in effect as long as at least one +thread is blocked on the condition variable. During this time, the effect of an attempt by any thread to wait on that +condition variable using a different mutex is undefined. Once all waiting threads have been unblocked +(as by the `condBroadcast()` operation), the next wait operation on that condition variable shall form a new dynamic +binding with the mutex specified by that wait operation. Even though the dynamic binding between condition variable and +mutex may be removed or replaced between the time a thread is unblocked from a wait on the condition variable and the +time that it returns to the caller or begins cancellation cleanup, the unblocked thread shall always re-acquire the +mutex specified in the condition wait operation call from which it is returning. -A thread that has been unblocked because it has been canceled while blocked in a call to `condWait()` shall not consume any condition signal that may be directed concurrently at the condition variable if -there are other threads blocked on the condition variable. +A thread that has been unblocked because it has been canceled while blocked in a call to `condWait()` shall not consume +any condition signal that may be directed concurrently at the condition variable if there are other threads blocked on +the condition variable. -If a signal is delivered to a thread waiting for a condition variable, upon return from the signal handler the thread resumes -waiting for the condition variable as if it was not interrupted, or it shall return zero due to spurious wakeup. +If a signal is delivered to a thread waiting for a condition variable, upon return from the signal handler the thread +resumes waiting for the condition variable as if it was not interrupted, or it shall return zero due to spurious wakeup. The behavior is undefined if the value specified by the _h_ or mutex _m_ argument to these functions does not refer to an initialized condition variable or an initialized mutex object, respectively. -If _timeout_ is nonzero `-ETIME` is returned if condition is not signaled after waiting for _timeout_ microseconds. Zero _timeout_ waits indefinitely until condition is signalled. Note that due to internal implementation timeout is restarted when signal is received (retry on `EINTR`). +If _timeout_ is nonzero `-ETIME` is returned if condition is not signaled after waiting for _timeout_ microseconds. Zero +_timeout_ waits indefinitely until condition is signalled. Note that due to internal implementation timeout is restarted +when signal is received (retry on `EINTR`). ## Return value -Upon successful completion, a value of zero shall be returned; otherwise, an error number shall be returned to indicate the -error. - +Upon successful completion, a value of zero shall be returned; otherwise, an error number shall be returned to indicate +the error. ## Errors This function shall fall if: - * `-EINVAL` - The value _h_ does not refer to an initialised condition variable, +* `-EINVAL` - The value _h_ does not refer to an initialised condition variable, - * `-EINVAL` - Parent process for _h_ variable or mutex _m_ ceased to exist during function call +* `-EINVAL` - Parent process for _h_ variable or mutex _m_ ceased to exist during function call - * `-ETIME` - Condition was not signaled before specified timeout +* `-ETIME` - Condition was not signaled before specified timeout ## Tests @@ -70,6 +81,7 @@ Untested None ## See Also + 1. [condWait syscall](../../../kernel/syscalls/sync.md#user-content-syscalls_condwait-syscalls_phcondwait) 2. [Standard library functions](../README.md) 3. [Table of Contents](../../../README.md) diff --git a/libc/functions/c/connect.part-impl.md b/libc/functions/c/connect.part-impl.md index 783d0161..1226649f 100644 --- a/libc/functions/c/connect.part-impl.md +++ b/libc/functions/c/connect.part-impl.md @@ -1,8 +1,9 @@ -# Synopsis +# Synopsis + `#include `
-` int connect(int socket, const struct sockaddr *address,`
-`        socklen_t address_len);`
+`int connect(int socket, const struct sockaddr *address,`
+`socklen_t address_len);`
## Status @@ -14,120 +15,116 @@ IEEE Std 1003.1-2017 ## Description - -The purpose is to connect a socket. The `connect()` function shall attempt to make a connection on a connection-mode socket or to set or reset the peer address -of a connectionless-mode socket. The function takes the following arguments: +The purpose is to connect a socket. The `connect()` function shall attempt to make a connection on a connection-mode +socket or to set or reset the peer address of a connectionless-mode socket. The function takes the following arguments: * _`socket`_ - Specifies the file descriptor associated with the _socket_. -* _`address`_ - Points to a sockaddr structure containing the peer address. The length and format of the address depend on the address -family of the socket. +* _`address`_ - Points to a sockaddr structure containing the peer address. The length and format of the address depend +on the address family of the socket. * _`address_len`_ - Specifies the length of the sockaddr structure pointed to by the _address_ argument. If the socket has not already been bound to a local address, `connect()` shall bind it to an address which, unless the socket's address family is `AF_UNIX,` is an unused local address. -If the initiating socket is not connection-mode, then `connect()` shall set the socket's peer address, and no connection is -made. For `SOCK_DGRAM` sockets, the peer address identifies where all datagrams are sent on subsequent `send()` functions, and limits the remote sender for subsequent `recv()` functions. If the `sa_family` member of address is `AF_UNSPEC,` the socket's -peer address shall be reset. Note that despite no connection being made, the term `connected` is used to describe a -connectionless-mode socket for which a peer address has been set. +If the initiating socket is not connection-mode, then `connect()` shall set the socket's peer address, and no +connection is made. For `SOCK_DGRAM` sockets, the peer address identifies where all datagrams are sent +on subsequent `send()` functions, and limits the remote sender for subsequent `recv()` functions. If the `sa_family` +member of address is `AF_UNSPEC,` the socket's peer address shall be reset. Note that despite no connection being made, +the term `connected` is used to describe a connectionless-mode socket for which a peer address has been set. If the initiating socket is connection-mode, then `connect()` shall attempt to establish a connection to the address -specified by the _address_ argument. If the connection cannot be established immediately and `O_NONBLOCK` is not set for the -file descriptor for the socket, `connect()` shall block for up to an unspecified timeout interval until the connection is -established. If the timeout interval expires before the connection is established, `connect()` shall fail and the connection -attempt shall be aborted. If `connect()` is interrupted by a signal that is caught while blocked waiting to establish a -connection, `connect()` shall fail and set errno to `EINTR`, but the connection request shall not be aborted, and the -connection shall be established asynchronously. +specified by the _address_ argument. If the connection cannot be established immediately and `O_NONBLOCK` is not set for +the file descriptor for the socket, `connect()` shall block for up to an unspecified timeout interval until the +connection is established. If the timeout interval expires before the connection is established, `connect()` shall fail +and the connection attempt shall be aborted. If `connect()` is interrupted by a signal that is caught while blocked +waiting to establish a connection, `connect()` shall fail and set errno to `EINTR`, but the connection request +shall not be aborted, and the connection shall be established asynchronously. If the connection cannot be established immediately and `O_NONBLOCK` is set for the file descriptor for the socket, `connect()` shall fail and set `errno` to `EINPROGRESS`, but the connection request shall not be aborted, and the -connection shall be established asynchronously. Subsequent calls to `connect()` for the same socket, before the connection is -established, shall fail and set `errno` to `EALREADY`. +connection shall be established asynchronously. Subsequent calls to `connect()` for the same socket, before the +connection is established, shall fail and set `errno` to `EALREADY`. -When the connection has been established asynchronously, `pselect()`, `select()`, and `poll()` shall indicate that the file -descriptor for the socket is ready for writing. +When the connection has been established asynchronously, `pselect()`, `select()`, and `poll()` shall indicate that the +file descriptor for the socket is ready for writing. The socket in use may require the process to have appropriate privileges to use the `connect()` function. - ## Return value -Upon successful completion, `connect()` shall return `0`, otherwise, `-1` shall be returned and `errno` set to indicate the error. +Upon successful completion, `connect()` shall return `0`, otherwise, `-1` shall be returned and `errno` set to indicate +the error. ## Errors - The `connect()` function shall fail if: * `EADDRNOTAVAIL`- The specified address is not available from the local machine. * `EAFNOSUPPORT` - The specified address is not a valid address for the address family of the specified socket. - * `EALREADY` - A connection request is already in progress for the specified socket. +* `EALREADY` - A connection request is already in progress for the specified socket. - * `EBADF` - The _socket_ argument is not a valid file descriptor. +* `EBADF` - The _socket_ argument is not a valid file descriptor. - * `ECONNREFUSED` - The target address was not listening for connections or refused the connection request. +* `ECONNREFUSED` - The target address was not listening for connections or refused the connection request. - * `EINPROGRESS` - `O_NONBLOCK` is set for the file descriptor for the socket and the connection cannot be immediately established, the connection -shall be established asynchronously. +* `EINPROGRESS` - `O_NONBLOCK` is set for the file descriptor for the socket and the connection cannot be immediately +established, the connection shall be established asynchronously. - * `EINTR` - The attempt to establish a connection was interrupted by delivery of a signal that was caught, the connection shall be -established asynchronously. +* `EINTR` - The attempt to establish a connection was interrupted by delivery of a signal that was caught, the +connection shall be established asynchronously. - * `EISCONN` - The specified socket is connection-mode and is already connected. +* `EISCONN` - The specified socket is connection-mode and is already connected. - * `ENETUNREACH` - No route to the network is present. +* `ENETUNREACH` - No route to the network is present. - * `ENOTSOCK` - The _socket_ argument does not refer to a socket. +* `ENOTSOCK` - The _socket_ argument does not refer to a socket. - * `EPROTOTYPE` - The specified address has a different type than the socket bound to the specified peer address. +* `EPROTOTYPE` - The specified address has a different type than the socket bound to the specified peer address. - * `ETIMEDOUT` - The attempt to connect timed out before a connection was made. +* `ETIMEDOUT` - The attempt to connect timed out before a connection was made. If the address family of the socket is `AF_UNIX`, then `connect()` shall fail if: - * `EIO` - An `I/O` error occurred while reading from or writing to the file system. +* `EIO` - An `I/O` error occurred while reading from or writing to the file system. - * `ELOOP` - A loop exists in symbolic links encountered during resolution of the pathname in _address_. +* `ELOOP` - A loop exists in symbolic links encountered during resolution of the pathname in _address_. - * `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. +* `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. - * `ENOENT` - A component of the pathname does not name an existing file or the pathname is an empty string. +* `ENOENT` - A component of the pathname does not name an existing file or the pathname is an empty string. - * `ENOTDIR` - A component of the path prefix of the pathname in _address_ names an existing file that is neither a directory nor a -symbolic link to a directory, or the pathname in _address_ contains at least one non-`` character and ends with -one or more trailing `` characters and the last pathname component names an existing file that is neither a directory -nor a symbolic link to a directory. +* `ENOTDIR` - A component of the path prefix of the pathname in _address_ names an existing file that is neither a +directory nor a symbolic link to a directory, or the pathname in _address_ contains at least one non-`` character +and ends with one or more trailing `` characters and the last pathname component names an existing file that is +neither a directory nor a symbolic link to a directory. The `connect()` function may fail if: +* `EACCES` - Search permission is denied for a component of the path prefix, or write access to the named socket is +denied. - * `EACCES` - Search permission is denied for a component of the path prefix, or write access to the named socket is denied. +* `EADDRINUSE` - Attempt to establish a connection that uses addresses that are already in use. - * `EADDRINUSE` - Attempt to establish a connection that uses addresses that are already in use. +* `ECONNRESET` - Remote host reset the connection request. - * `ECONNRESET` - Remote host reset the connection request. +* `EHOSTUNREACH` - The destination host cannot be reached (probably because the host is down or a remote router cannot +reach it). - * `EHOSTUNREACH` - The destination host cannot be reached (probably because the host is down or a remote router cannot reach it). +* `EINVAL` - The _address_len_ argument is not a valid length for the address family; or invalid address family in +the sockaddr structure. - * `EINVAL` - The _address_len_ argument is not a valid length for the address family; or invalid address family in the sockaddr -structure. - - * `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the pathname in _address_. - - * `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an intermediate result with a -length that exceeds `PATH_MAX`. - - * `ENETDOWN` - The local network interface used to reach the destination is down. - - * `ENOBUFS` - No buffer space is available. - - * `EOPNOTSUPP` - The socket is listening and cannot be connected. +* `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the pathname in _address_. +* `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an +intermediate result with a length that exceeds `PATH_MAX`. +* `ENETDOWN` - The local network interface used to reach the destination is down. +* `ENOBUFS` - No buffer space is available. +* `EOPNOTSUPP` - The socket is listening and cannot be connected. ## Tests @@ -137,6 +134,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/c/copysignl.part-impl.md b/libc/functions/c/copysignl.part-impl.md index af00e1cd..af0e9e4b 100644 --- a/libc/functions/c/copysignl.part-impl.md +++ b/libc/functions/c/copysignl.part-impl.md @@ -1,38 +1,35 @@ -# Synopsis +# Synopsis + `#include `
-` double copysign(double x, double y);`
+`double copysign(double x, double y);`
-` float copysignf(float x, float y);`
+`float copysignf(float x, float y);`
-` long double copysignl(long double x, long double y);`
+`long double copysignl(long double x, long double y);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description These functions shall produce a value with the magnitude of _x_ and the sign of _y_. On implementations that represent -a signed zero but do not treat negative zero consistently in arithmetic operations, these functions regard the sign of zero as -positive. - +a signed zero but do not treat negative zero consistently in arithmetic operations, these functions regard the sign of +zero as positive. ## Return value - Upon successful completion, these functions shall return a value with the magnitude of _x_ and the sign of _y_. - ## Errors - No errors are defined. - - - ## Tests Untested @@ -41,6 +38,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/c/cos.part-impl.md b/libc/functions/c/cos.part-impl.md index 7bd92cd3..d055ec34 100644 --- a/libc/functions/c/cos.part-impl.md +++ b/libc/functions/c/cos.part-impl.md @@ -1,24 +1,29 @@ -# Synopsis +# Synopsis + `#include `
-` double cos(double x);`
+`double cos(double x);`
-` float cosf(float x);`
+`float cosf(float x);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description These functions shall compute the cosine of their argument _x_, measured in radians. -An application wishing to check for error situations should set `errno` to zero and call `feclearexcept(FE_ALL_EXCEPT)` before calling these functions. On return, if `errno` is non-zero or `fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)` is non-zero, an error has occurred. - +An application wishing to check for error situations should set `errno` to zero and call `feclearexcept(FE_ALL_EXCEPT)` +before calling these functions. On return, if `errno` is non-zero or +`fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)` is non-zero, an error has occurred. ## Return value - Upon successful completion, these functions shall return the cosine of _x_. * If _x_ is `NaN`, a `NaN` shall be returned. @@ -29,15 +34,15 @@ Upon successful completion, these functions shall return the cosine of _x_. ## Errors - These functions shall fail if: * Domain Error - - The _x_ argument is `±Inf`. - If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `EDOM`. If the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the invalid floating-point exception shall be raised. + The _x_ argument is `±Inf`. + If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `EDOM`. + If the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the invalid floating-point exception + shall be raised. ## Tests @@ -47,6 +52,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/c/cosh.part-impl.md b/libc/functions/c/cosh.part-impl.md index 52840510..c0bda305 100644 --- a/libc/functions/c/cosh.part-impl.md +++ b/libc/functions/c/cosh.part-impl.md @@ -1,28 +1,33 @@ -# Synopsis +# Synopsis + `#include `
-` double cosh(double x);`
+`double cosh(double x);`
-` float coshf(float x);`
+`float coshf(float x);`
## Status + Partially implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 +## Description These functions shall compute the hyperbolic cosine of their argument _x_. -An application wishing to check for error situations should set `errno` to zero and call `feclearexcept(FE_ALL_EXCEPT)` before calling these functions. On return, if `errno` is non-zero or `fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)` is non-zero, an error has occurred. - +An application wishing to check for error situations should set `errno` to zero and call `feclearexcept(FE_ALL_EXCEPT)` +before calling these functions. On return, if `errno` is non-zero or +`fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)` is non-zero, an error has occurred. ## Return value Upon successful completion, these functions shall return the hyperbolic cosine of _x_. -* If the correct value would cause overflow, a range error shall occur and `cosh()`, `coshf()`, and `coshl()` shall return the value of the macro `HUGE_VAL`, and `HUGE_VALF` respectively. +* If the correct value would cause overflow, a range error shall occur and `cosh()`, `coshf()`, and `coshl()` shall +return the value of the macro `HUGE_VAL`, and `HUGE_VALF` respectively. * If _x_ is `NaN`, a `NaN` shall be returned. @@ -32,16 +37,14 @@ Upon successful completion, these functions shall return the hyperbolic cosine o ## Errors - These functions shall fail if: * Range Error - The result would cause an overflow. - - If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the overflow floating-point exception shall -be raised. - + The result would cause an overflow. + If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If the + integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the overflow floating-point exception shall + be raised. ## Tests @@ -51,6 +54,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/c/creat.part-impl.md b/libc/functions/c/creat.part-impl.md index c34e2c5e..c4eca183 100644 --- a/libc/functions/c/creat.part-impl.md +++ b/libc/functions/c/creat.part-impl.md @@ -1,43 +1,39 @@ -# Synopsis +# Synopsis + `#include `
`#include `
-` int creat(const char *path, mode_t mode);`
+`int creat(const char *path, mode_t mode);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The purpose is to create a new file or rewrite an existing one. The `creat()` function shall behave as if it is implemented as follows: +The purpose is to create a new file or rewrite an existing one. The `creat()` function shall behave as if it is +implemented as follows: -``` +```c int creat(const char *path, mode_t mode) { return open(path, O_WRONLY|O_CREAT|O_TRUNC, mode); } ``` - ## Return value - Refer to [open](../o/open.part-impl.md). - - - ## Errors - Refer to [open](../o/open.part-impl.md). - - - ## Tests Untested @@ -46,6 +42,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/c/crypt.part-impl.md b/libc/functions/c/crypt.part-impl.md index 22ad0552..b7be9f61 100644 --- a/libc/functions/c/crypt.part-impl.md +++ b/libc/functions/c/crypt.part-impl.md @@ -1,21 +1,25 @@ -# Synopsis -`#include `
+# Synopsis -` char *crypt(const char *key, const char *salt); `
+`#include ` + +` char *crypt(const char *key, const char *salt); ` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `crypt()` function is a string encoding function. The algorithm is implementation-defined. The _key_ argument points to a string to be encoded. The _salt_ argument shall be a string of at least two bytes in length not including the `null` character chosen from the set: -``` +```c a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 . / @@ -27,23 +31,17 @@ The return value of `crypt()` points to static data that is overwritten by each The `crypt()` function need not be thread-safe. - ## Return value -Upon successful completion, `crypt()` shall return a pointer to the encoded string. The first two bytes of the returned value shall be those of the _salt_ argument. Otherwise, it shall return a null pointer and set `errno` to indicate the error. - +Upon successful completion, `crypt()` shall return a pointer to the encoded string. The first two bytes of the returned +value shall be those of the _salt_ argument. Otherwise, it shall return a null pointer and set `errno` to indicate the +error. ## Errors - The `crypt()` function shall fail if: - - * `ENOSYS` - The functionality is not supported on this implementation. - - - - +* `ENOSYS` - The functionality is not supported on this implementation. ## Tests @@ -53,6 +51,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/c/ctime.impl.md b/libc/functions/c/ctime.impl.md index f9a6d65c..4119dba9 100644 --- a/libc/functions/c/ctime.impl.md +++ b/libc/functions/c/ctime.impl.md @@ -1,4 +1,4 @@ -###Synopsis +### Synopsis `#include ` @@ -6,42 +6,50 @@ `char *ctime_r(const time_t *clock, char *buf);` -###Description +### Description -The `ctime()` function converts the time pointed to by clock, representing time in seconds since the Epoch, to local time in the form of a string. It is equivalent to: +The `ctime()` function converts the time pointed to by _clock_, representing time in seconds since the Epoch, to +local time in the form of a string. It is equivalent to: `asctime(localtime(clock))`. Arguments: -clock - time in seconds since the Epoch. -buf - the buffer to which the string representing local time is put. - +_clock_ - time in seconds since the Epoch. +_buf_ - the buffer to which the string representing local time is put. + The `ctime()` function returns value in an array of characters. It is not thread-safe. -The `ctime_r()` function converts the calendar time pointed to by clock to local time in exactly the same form as `ctime()` and puts the string into the 32 bytes array pointed to by buf. It returns buf. +The `ctime_r()` function converts the calendar time pointed to by _clock_ to local time in exactly the same form as +`ctime()` and puts the string into the 32 bytes array pointed to by _buf_. It returns _buf_. -Unlike `ctime()`, the `ctime_r()` function does not set `tzname`. +Unlike `ctime()`, the `ctime_r()` function does not set `tzname`. -These functions are included only for compatibility with older implementations. They have undefined behavior if the resulting string is too long, so the use of them is discouraged. Also, these functions do not support localized date and time formats. To avoid these problems, applications should use `strftime()` to generate strings from broken-down times. +These functions are included only for compatibility with older implementations. They have undefined behavior if the +resulting string is too long, so the use of them is discouraged. Also, these functions do not support localized date +and time formats. To avoid these problems, applications should use `strftime()` to generate strings from broken-down +times. Values for the broken-down time structure can be obtained by calling `gmtime()` or `localtime()`. -The `ctime_r()` function is thread-safe and returns values in a user-supplied buffer instead of possibly using a static data area that may be overwritten by each call. +The `ctime_r()` function is thread-safe and returns values in a user-supplied buffer instead of possibly using a static +data area that may be overwritten by each call. -Attempts to use `ctime()` or `ctime_r()` for times before the Epoch or for times beyond the year `9999` produce undefined results. Refer to `asctime()`. +Attempts to use `ctime()` or `ctime_r()` for times before the Epoch or for times beyond the year `9999` produce +undefined results. Refer to `asctime()`. These functions may be removed in a future version. -###Return value +### Return value The `ctime()` function returns the pointer returned by `asctime()` with that broken-down time as an argument. -Upon successful completion, `ctime_r()` returns a pointer to the string pointed to by buf. When an error is encountered, a null pointer is returned. +Upon successful completion, `ctime_r()` returns a pointer to the string pointed to by _buf_. When an error is +encountered, a null pointer is returned. -###Errors +### Errors No errors are defined. -###Implementation tasks +### Implementation tasks * Add environment parsing for setting timezone and daylight. diff --git a/libc/functions/d/difftime.part-impl.md b/libc/functions/d/difftime.part-impl.md index 29b67ca2..d3c1bdcf 100644 --- a/libc/functions/d/difftime.part-impl.md +++ b/libc/functions/d/difftime.part-impl.md @@ -1,31 +1,30 @@ -# Synopsis +# Synopsis + `#include `
-` double difftime(time_t time1, time_t time0);`
+`double difftime(time_t time1, time_t time0);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description -The `difftime()` function shall compute the difference between two calendar times (as returned by `time()`): _time1_ - _time0_. +## Description +The `difftime()` function shall compute the difference between two calendar times +(as returned by `time()`): _time1_ - _time0_. ## Return value - The `difftime()` function shall return the difference expressed in seconds as a type double. - ## Errors - No errors are defined. - - - ## Tests Untested @@ -34,6 +33,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/d/dirname.part-impl.md b/libc/functions/d/dirname.part-impl.md index 5556f7a7..9e8e35b4 100644 --- a/libc/functions/d/dirname.part-impl.md +++ b/libc/functions/d/dirname.part-impl.md @@ -1,14 +1,18 @@ -# Synopsis +# Synopsis + `#include `
` char *dirname(char *path); `
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `dirname()` function shall take a pointer to a character string that contains a pathname, and return a pointer to a string that is a pathname of the parent directory of that file. The `dirname()` function shall not perform pathname @@ -24,25 +28,18 @@ may then be overwritten by a subsequent call to `dirname()`. The `dirname()` function need not be thread-safe. - ## Return value - The `dirname()` function shall return a pointer to a string as described above. The `dirname()` function may modify the string pointed to by _path_, and may return a pointer to internal storage. The -returned pointer might be invalidated or the storage might be overwritten by a subsequent call to `dirname()`. The returned -pointer might also be invalidated if the calling thread is terminated. - +returned pointer might be invalidated or the storage might be overwritten by a subsequent call to `dirname()`. +The returned pointer might also be invalidated if the calling thread is terminated. ## Errors - No errors are defined. - - - ## Tests Untested @@ -51,6 +48,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/d/dprintf.part-impl.md b/libc/functions/d/dprintf.part-impl.md index 3cfd05b9..7f56e68a 100644 --- a/libc/functions/d/dprintf.part-impl.md +++ b/libc/functions/d/dprintf.part-impl.md @@ -1,220 +1,373 @@ -###Synopsis +# Synopsis `#include ` `int dprintf(int fildes, const char *restrict format, ...);` + `int fprintf(FILE *restrict stream, const char *restrict format, ...);` + `int printf(const char *restrict format, ...);` + `int snprintf(char *restrict s, size_t n, const char *restrict format, ...);` + `int sprintf(char *restrict s, const char *restrict format, ...);` -###Description +## Description The functions print formatted output. Arguments: -fildes - the file descriptor, -format - a character string defining output format. -s - a character table, to which the resulting formatted string will be put, -n - the size of the buffer, +* _fildes_ - the file descriptor, +* _format_ - a character string defining output format. +* _s_ - a character table, to which the resulting formatted string will be put, +* _n_ - the size of the buffer, -The `fprintf()` function places output on the named output stream. The `printf()` function places output on the standard output stream `stdout`. The `sprintf()` function places output followed by the null byte, '\0', in consecutive bytes starting at *s; it is the user's responsibility to ensure that enough space is available. +The `fprintf()` function places output on the named output stream. The `printf()` function places output on the standard +output stream `stdout`. The `sprintf()` function places output followed by the null byte, '\0', in consecutive bytes +starting at *s; it is the user's responsibility to ensure that enough space is available. -The `dprintf()` function is equivalent to the `fprintf()` function, except that `dprintf()` writes output to the file associated with the file descriptor specified by the fildes argument rather than place output on a stream. +The `dprintf()` function is equivalent to the `fprintf()` function, except that `dprintf()` writes output to the file +associated with the file descriptor specified by the _fildes_ argument rather than place output on a stream. -The `snprintf()` function is equivalent to `sprintf()`, with the addition of the n argument which states the size of the buffer referred to by s. If n is zero, nothing is written and s may be a null pointer. Otherwise, output bytes beyond the n-1st are discarded instead of being written to the array, and a null byte is written at the end of the bytes actually written into the array. +The `snprintf()` function is equivalent to `sprintf()`, with the addition of the _n_ argument which states the size +of the buffer referred to by _s_. If _n_ is zero, nothing is written and _s_ may be a null pointer. +Otherwise, output bytes beyond the _n_-1st are discarded instead of being written to the array, and a null byte is +written at the end of the bytes actually written into the array. -If copying takes place between objects that overlap as a result of a call to `sprintf()` or `snprintf()`, the results are undefined. +If copying takes place between objects that overlap as a result of a call to `sprintf()` or `snprintf()`, +the results are undefined. -Each of these functions converts, formats, and prints its arguments under control of the format. The format is a character string, beginning and ending in its initial shift state, if any. The format is composed of zero or more directives: ordinary characters, which are simply copied to the output stream, and conversion specifications, each of which results in the fetching of zero or more arguments. The results are undefined if there are insufficient arguments for the format. If the format is exhausted while arguments remain, the excess arguments are evaluated but are otherwise ignored. +Each of these functions converts, formats, and prints its arguments under control of the _format_. +The _format_ is a character string, beginning and ending in its initial shift state, if any. The _format_ is +composed of zero or more directives: ordinary characters, which are simply copied to the output stream, and conversion +specifications, each of which results in the fetching of zero or more arguments. The results are undefined if there are +insufficient arguments for the _format_. If the _format_ is exhausted while arguments remain, the excess +arguments are evaluated but are otherwise ignored. -Conversions can be applied to the nth argument after the format in the argument list, rather than to the next unused argument. In this case, the conversion specifier character `%` (see below) is replaced by the sequence `"%n$"`, where `n` is a decimal integer in the range `[1,{NL_ARGMAX}]`, giving the position of the argument in the argument list. This feature provides for the definition of format strings that select arguments in an order appropriate to specific languages. +Conversions can be applied to the nth argument after the format in the argument list, rather than to the next unused +argument. In this case, the conversion specifier character `%` (see below) is replaced by the sequence `"%n$"`, where +`n` is a decimal integer in the range `[1,{NL_ARGMAX}]`, giving the position of the argument in the argument list. This +feature provides for the definition of format strings that select arguments in an order appropriate to specific +languages. -The format can contain either numbered argument conversion specifications (that is, `"%n$"` and `"*m$"`), or unnumbered argument conversion specifications (that is, `%` and `*` ), but not both. The only exception to this is that `%%` can be mixed with the `"%n$"` form. The results of mixing numbered and unnumbered argument specifications in a format string are undefined. When numbered argument specifications are used, specifying the Nth argument requires that all the leading arguments, from the first to the `(N-1)`th, are specified in the format string. +The format can contain either numbered argument conversion specifications (that is, `"%n$"` and `"*m$"`), or unnumbered +argument conversion specifications (that is, `%` and `*` ), but not both. The only exception to this is that `%%` can be +mixed with the `"%n$"` form. The results of mixing numbered and unnumbered argument specifications in a format string +are undefined. When numbered argument specifications are used, specifying the Nth argument requires that all the leading +arguments, from the first to the `(N-1)`th, are specified in the format string. -In format strings containing the `"%n$"` form of conversion specification, numbered arguments in the argument list can be referenced from the format string as many times as required. +In format strings containing the `"%n$"` form of conversion specification, numbered arguments in the argument list can +be referenced from the format string as many times as required. -In format strings containing the `%` form of conversion specification, each conversion specification uses the first unused argument in the argument list. +In format strings containing the `%` form of conversion specification, each conversion specification uses the first +unused argument in the argument list. -All forms of the `fprintf()` functions allow for the insertion of a language-dependent radix character in the output string. The radix character is defined in the current locale (category `LC_NUMERIC`). In the POSIX locale, or in a locale where the radix character is not defined, the radix character defaults to a ( `'.'` ). +All forms of the `fprintf()` functions allow for the insertion of a language-dependent radix character in the output +string. The radix character is defined in the current locale (category `LC_NUMERIC`). In the POSIX locale, or in a +locale where the radix character is not defined, the radix character defaults to a ( `'.'` ). -Each conversion specification is introduced by the `'%'` character or by the character sequence `"%n$"`, after which the following appear in sequence: +Each conversion specification is introduced by the `'%'` character or by the character sequence `"%n$"`, after which the +following appear in sequence: - * Zero or more flags (in any order), which modify the meaning of the conversion specification. +* Zero or more flags (in any order), which modify the meaning of the conversion specification. - * An optional minimum field width. If the converted value has fewer bytes than the field width, it is padded with characters by default on the left; it shall be padded on the right if the left-adjustment flag ( `'-'` ), described below, is given to the field width. The field width takes the form of an ( `'*'` ), described below, or a decimal integer. +* An optional minimum field width. If the converted value has fewer bytes than the field width, it is padded with +characters by default on the left; it shall be padded on the right if the left-adjustment flag ( `'-'` ), described +below, is given to the field width. The field width takes the form of an ( `'*'` ), described below, or a decimal +integer. - * An optional precision that gives the minimum number of digits to appear for the `d`, `i`, `o`, `u`, `x`, and `X` conversion specifiers; the number of digits to appear after the radix character for the `a`, `A`, `e`, `E`, `f`, and `F` conversion specifiers; the maximum number of significant digits for the `g` and `G` conversion specifiers; or the maximum number of bytes to be printed from a string in the `s` and `S` conversion specifiers. The precision takes the form of a ( `'.'` ) followed either by an ( `'*'` ), described below, or an optional decimal digit string, where a null digit string is treated as zero. If a precision appears with any other conversion specifier, the behavior is undefined. +* An optional precision that gives the minimum number of digits to appear for the `d`, `i`, `o`, `u`, `x`, and `X` +conversion specifiers; the number of digits to appear after the radix character for the `a`, `A`, `e`, `E`, `f`, and `F` +conversion specifiers; the maximum number of significant digits for the `g` and `G` conversion specifiers; or the +maximum number of bytes to be printed from a string in the `s` and `S` conversion specifiers. The precision takes the +form of a ( `'.'` ) followed either by an ( `'*'` ), described below, or an optional decimal digit string, where a null +digit string is treated as zero. If a precision appears with any other conversion specifier, the behavior is undefined. - * An optional length modifier that specifies the size of the argument. +* An optional length modifier that specifies the size of the argument. - * A conversion specifier character that indicates the type of conversion to be applied. +* A conversion specifier character that indicates the type of conversion to be applied. -A field width, or precision, or both, may be indicated by an ( `'*'` ). In this case an argument of type `int` supplies the field width or precision. Applications ensure that arguments specifying field width, or precision, or both appear in that order before the argument, if any, to be converted. A negative field width is taken as a `'-'` flag followed by a positive field width. A negative precision is taken as if the precision were omitted. In format strings containing the `"%n$"` form of a conversion specification, a field width or precision may be indicated by the sequence `"*m$"`, where `m` is a decimal integer in the range `[1,{NL_ARGMAX}]` giving the position in the argument list (after the format argument) of an integer argument containing the field width or precision, for example: +A field width, or precision, or both, may be indicated by an ( `'*'` ). In this case an argument of type +`int` supplies the field width or precision. Applications ensure that arguments specifying field width, or precision, +or both appear in that order before the argument, if any, to be converted. A negative field width is taken as a `'-'` +flag followed by a positive field width. A negative precision is taken as if the precision were omitted. In format +strings containing the `"%n$"` form of a conversion specification, a field width or precision may be indicated by the +sequence `"*m$"`, where `m` is a decimal integer in the range `[1,{NL_ARGMAX}]` giving the position in the argument list +(after the format argument) of an integer argument containing the field width or precision, for example: `printf("%1$d:%2$.*3$d:%4$.*3$d\n", hour, min, precision, sec);` The flag characters and their meanings are: - * `'` (The apostrophe) The integer portion of the result of a decimal conversion ( `%i`, `%d`, `%u`, `%f`, `%F`, `%g`, or `%G` ) are formatted with thousands' grouping characters. For other conversions the behavior is undefined. The non-monetary grouping character is used. - - * `-` The result of the conversion is left-justified within the field. The conversion is right-justified if this flag is not specified. - - * `+` The result of a signed conversion always begins with a sign ( `'+'` or `'-'` ). The conversion begins with a sign only when a negative value is converted if this flag is not specified. - - * ` ` (space) If the first character of a signed conversion is not a sign or if a signed conversion results in no characters, a is prefixed to the result. This means that if the and `'+'` flags both appear, the flag are ignored. - - * `#` Specifies that the value is to be converted to an alternative form. For `o` conversion, it increases the precision, if and only if necessary, to force the first digit of the result to be a zero (if the value and precision are both `0`, a single `0` is printed). For `x` or `X` conversion specifiers, a non-zero result has `0x` (or `0X`) prefixed to it. For `a`, `A`, `e`, `E`, `f`, `F`, `g`, and `G` conversion specifiers, the result always contains a radix character, even if no digits follow the radix character. Without this flag, a radix character appears in the result of these conversions only if a digit follows it. For `g` and `G` conversion specifiers, trailing zeros are not - removed from the result as they normally are. For other conversion specifiers, the behavior is undefined. - - * `0` For `d`, `i`, `o`, `u`, `x`, `X`, `a`, `A`, `e`, `E`, `f`, `F`, `g`, and `G` conversion specifiers, leading zeros (following any indication of sign or base) are used to pad to the field width rather than performing space padding, except when converting an infinity or `NaN`. If the `'0'` and `'-'` flags both appear, the `'0'` flag is ignored. For `d`, `i`, `o`, `u`, `x`, and `X` conversion specifiers, if a precision is specified, the `'0'` flag is ignored. If the `'0'` and flags both appear, the grouping characters are inserted before zero padding. For other conversions, the behavior is undefined. - -The length modifiers and their meanings are: - - * `hh` Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `signed char` or `unsigned char` argument (the argument will have been promoted according to the integer promotions, but its value is converted to `signed char` or `unsigned char` before printing); or that a following `n` conversion specifier applies to a pointer to a `signed char` argument. - - * `h` Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `short` or `unsigned short` argument (the argument will have been promoted according to the integer promotions, but its value is converted to `short` or `unsigned short` before printing); or that a following `n` conversion specifier applies to a pointer to a `short` argument. - - * `l` (`ell`) Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `long` or `unsigned long` argument; that a following `n` conversion specifier applies to a pointer to a `long` argument; that a following `c` conversion specifier applies to a `wint_t` argument; that a following s conversion specifier applies to a pointer to a `wchar_t` argument; or has no effect on a following `a`, `A`, `e`, `E`, `f`, `F`, `g`, or `G` conversion specifier. - - * `ll` (`ell`-`ell`) Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `long long` or `unsigned long long` argument; or that a following `n` conversion specifier applies to a pointer to a `long long` argument. - - * `j` Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to an `intmax_t` or `uintmax_t` argument; or that a following `n` conversion specifier applies to a pointer to an `intmax_t` argument. +* `'` (The apostrophe) The integer portion of the result of a decimal conversion ( `%i`, `%d`, `%u`, `%f`, `%F`, `%g`, +or `%G` ) are formatted with thousands' grouping characters. For other conversions the behavior is undefined. The +non-monetary grouping character is used. - * `z` Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `size_t` or the corresponding `signed integer` type argument; or that a following `n` conversion specifier applies to a pointer to a `signed integer` type corresponding to a `size_t` argument. +* `-` The result of the conversion is left-justified within the field. The conversion is right-justified if this flag is +not specified. - * `t` Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `ptrdiff_t` or the corresponding `unsigned` type argument; or that a following `n` conversion specifier applies to a pointer to a `ptrdiff_t` argument. +* `+` The result of a signed conversion always begins with a sign ( `'+'` or `'-'` ). The conversion begins with a sign +only when a negative value is converted if this flag is not specified. - * `L` Specifies that a following `a`, `A`, `e`, `E`, `f`, `F`, `g`, or `G` conversion specifier applies to a `long double` argument. - -If a length modifier appears with any conversion specifier other than as specified above, the behavior is undefined. - -The conversion specifiers and their meanings are: +* `'space'` If the first character of a signed conversion is not a sign or if a signed conversion results in no +characters, a `'space'` is prefixed to the result. This means that if the `'space'` and `'+'` flags both appear, the +`'space'` flag are ignored. - * `d`, `i` The `int` argument is converted to a `signed` decimal in the style `"[-]dddd"`. The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it is expanded with leading zeros. The default precision is `1`. The result of converting zero with an explicit precision of zero is no characters. +* `#` Specifies that the value is to be converted to an alternative form. For `o` conversion, it increases the +precision, if and only if necessary, to force the first digit of the result to be a zero (if the value and precision are +both `0`, a single `0` is printed). For `x` or `X` conversion specifiers, a non-zero result has `0x` (or `0X`) prefixed +to it. For `a`, `A`, `e`, `E`, `f`, `F`, `g`, and `G` conversion specifiers, the result always contains a radix +character, even if no digits follow the radix character. Without this flag, a radix character appears in the result of +these conversions only if a digit follows it. For `g` and `G` conversion specifiers, trailing zeros are not removed +from the result as they normally are. For other conversion specifiers, the behavior is undefined. - * `o` The `unsigned` argument is converted to `unsigned` octal format in the style `"dddd"`. The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it is expanded with leading zeros. The default precision is `1`. The result of converting zero with an explicit precision of zero is no characters. +* `0` For `d`, `i`, `o`, `u`, `x`, `X`, `a`, `A`, `e`, `E`, `f`, `F`, `g`, and `G` conversion specifiers, leading zeros +(following any indication of sign or base) are used to pad to the field width rather than performing space padding, +except when converting an infinity or `NaN`. If the `'0'` and `'-'` flags both appear, the `'0'` flag is ignored. For +`d`, `i`, `o`, `u`, `x`, and `X` conversion specifiers, if a precision is specified, the `'0'` flag is ignored. If the +`'0'` and `'` flags both appear, the grouping characters are inserted before zero padding. For other +conversions, the behavior is undefined. - * `u` The `unsigned` argument is converted to `unsigned` decimal format in the style `"dddd"`. The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it is expanded with leading zeros. The default precision is `1`. The result of converting zero with an explicit precision of zero is no characters. - - * `x` The `unsigned` argument is converted to `unsigned` hexadecimal format in the style `"dddd"`; the letters `"abcdef"` are used. The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it is expanded with leading zeros. The default precision is `1`. The result of converting zero with an explicit precision of zero are no characters. +The length modifiers and their meanings are: - * `X` Equivalent to the `x` conversion specifier, except that letters `"ABCDEF"` are used instead of `"abcdef"`. - - * `f`, `F` The `double` argument is converted to decimal notation in the style `"[-]ddd.ddd"`, where the number of digits after the radix character is equal to the precision specification. If the precision is missing, it is taken as `6`; if the precision is explicitly zero and no `'#'` flag is present, no radix character appears. If a radix character appears, at least one digit appears before it. The low-order digit is rounded. - A `double` argument representing an infinity is converted in one of the styles `"[-]inf"` or `"[-]infinity"`; which style is implementation-defined. A `double` argument representing a `NaN` is converted in one of the styles `"[-]nan(n-char-sequence)"` or `"[-]nan"`; which style, and the meaning of any `n-char`-sequence, is implementation-defined. The F conversion specifier produces `"INF"`, `"INFINITY"`, or `"NAN"` instead of `"inf"`, `"infinity"`, or `"nan"`, respectively. +* `hh` Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `signed char` or +`unsigned char` argument (the argument will have been promoted according to the integer promotions, but its value is +converted to `signed char` or `unsigned char` before printing); or that a following `n` conversion specifier applies to +a pointer to a `signed char` argument. - * `e`, `E` The `double` argument is converted in the style `"[-]d.dddedd"`, where there is one digit before the radix character (which is non-zero if the argument is non-zero) and the number of digits after it is equal to the precision; if the precision is missing, it is taken as `6`; if the precision is zero and no `'#'` flag is present, no radix character appears. The low-order digit is rounded in an implementation-defined manner. The E conversion specifier produces a number with 'E' instead of 'e' introducing the exponent. The exponent always contains at least two digits. If the value is zero, the exponent is zero. - A `double` argument representing an infinity or `NaN` is converted in the style of an `f` or `F` conversion specifier. - - * `g`, `G` The `double` argument representing a floating-point number is converted in the style `f` or `e` (or in the style `F` or `E` in the case of a `G` conversion specifier), depending on the value converted and the precision. Let `P` equal the precision if non-zero, `6` if the precision is omitted, or `1` if the precision is zero. Then, if a conversion with style `E` would have an exponent of `X`: +* `h` Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `short` or +`unsigned short` argument (the argument will have been promoted according to the integer promotions, but its value is +converted to `short` or `unsigned short` before printing); or that a following `n` conversion specifier applies to a +pointer to a `short` argument. - * If `P > X>=-4`, the conversion is with style `f` (or `F` ) and precision `P -( X+1)`. +* `l` (`ell`) Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `long` or +`unsigned long` argument; that a following `n` conversion specifier applies to a pointer to a `long` argument; that a +following `c` conversion specifier applies to a `wint_t` argument; that a following s conversion specifier applies to a +pointer to a `wchar_t` argument; or has no effect on a following `a`, `A`, `e`, `E`, `f`, `F`, `g`, or `G` +conversion specifier. - * Otherwise, the conversion is with style `e` (or `E` ) and precision `P -1`. +* `ll` (`ell`-`ell`) Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `long +long` or `unsigned long long` argument; or that a following `n` conversion specifier applies to a pointer to a +`long long` argument. - Finally, unless the `'#'` flag is used, any trailing zeros are removed from the fractional portion of the result and the decimal-point character is removed if there is no fractional portion remaining. +* `j` Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to an `intmax_t` or +`uintmax_t` argument; or that a following `n` conversion specifier applies to a pointer to an `intmax_t` argument. - A `double` argument representing an infinity or `NaN` is converted in the style of an `f` or `F` conversion specifier. +* `z` Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `size_t` or the +corresponding `signed integer` type argument; or that a following `n` conversion specifier applies to a pointer to a +`signed integer` type corresponding to a `size_t` argument. - * `a`, `A` A `double` argument representing a floating-point number is converted in the style `"[-]0xh.hhhhpd"`, where there is one hexadecimal digit (which is non-zero if the argument is a normalized floating-point number and is otherwise unspecified) before the decimal-point character and the number of hexadecimal digits after it is equal to the precision; if the precision is missing and `FLT_RADIX` is a power of `2`, then the precision is sufficient for an exact representation of the value; if the precision is missing and `FLT_RADIX` is not a power of `2`, then the precision is sufficient to distinguish values of type `double`, except that trailing zeros may be omitted; if the precision is zero and the `'#'` flag is not specified, no decimal-point character shall appear. The letters `"abcdef"` are used for `a` conversion and the letters `"ABCDEF"` for `A` conversion. The `A` conversion specifier produces a number with `'X'` and `'P'` instead of `'x'` and `'p'`. The exponent always contains at least one digit, and only as many more digits as necessary to represent the decimal exponent of `2`. If the value is zero, the exponent is zero. +* `t` Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `ptrdiff_t` or the +corresponding `unsigned` type argument; or that a following `n` conversion specifier applies to a pointer to a +`ptrdiff_t` argument. - A `double` argument representing an infinity or `NaN` is converted in the style of an `f` or `F` conversion specifier. +* `L` Specifies that a following `a`, `A`, `e`, `E`, `f`, `F`, `g`, or `G` conversion specifier applies to a +`long double` argument. - * `c` The int argument is converted to an `unsigned char`, and the resulting byte is written. +If a length modifier appears with any conversion specifier other than as specified above, the behavior is undefined. - If an `l` (`ell`) qualifier is present, the `wint_t` argument is converted as if by an `ls` conversion specification with no precision and an argument that points to a two-element array of type `wchar_t`, the first element of which contains the `wint_t` argument to the ls conversion specification and the second element contains a null wide character. +The conversion specifiers and their meanings are: - * `s` The argument is a pointer to an array of `char`. Bytes from the array are written up to (but not including) any terminating null byte. If the precision is specified, no more than that many bytes is written. If the precision is not specified or is greater than the size of the array, the application ensures that the array contains a null byte. +* `d`, `i` The `int` argument is converted to a `signed` decimal in the style `"[-]dddd"`. The precision specifies the +minimum number of digits to appear; if the value being converted can be represented in fewer digits, it is expanded with +leading zeros. The default precision is `1`. The result of converting zero with an explicit precision of zero is no +characters. + +* `o` The `unsigned` argument is converted to `unsigned` octal format in the style `"dddd"`. The precision specifies the +minimum number of digits to appear; if the value being converted can be represented in fewer digits, it is expanded with +leading zeros. The default precision is `1`. The result of converting zero with an explicit precision of zero is no +characters. + +* `u` The `unsigned` argument is converted to `unsigned` decimal format in the style `"dddd"`. The precision specifies +the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it is expanded +with leading zeros. The default precision is `1`. The result of converting zero with an explicit precision of zero is +no characters. + +* `x` The `unsigned` argument is converted to `unsigned` hexadecimal format in the style `"dddd"`; the letters +`"abcdef"` are used. The precision specifies the minimum number of digits to appear; if the value being converted can be +represented in fewer digits, it is expanded with leading zeros. The default precision is `1`. The result of converting +zero with an explicit precision of zero are no characters. + +* `X` Equivalent to the `x` conversion specifier, except that letters `"ABCDEF"` are used instead of `"abcdef"`. + +* `f`, `F` The `double` argument is converted to decimal notation in the style `"[-]ddd.ddd"`, where the number of +digits after the radix character is equal to the precision specification. If the precision is missing, it is taken as +`6`; if the precision is explicitly zero and no `'#'` flag is present, no radix character appears. If a radix character +appears, at least one digit appears before it. The low-order digit is rounded. + A `double` argument representing an infinity is converted in one of the styles `"[-]inf"` or `"[-]infinity"`; + which style is implementation-defined. A `double` argument representing a `NaN` is converted in one of the styles + `"[-]nan(n-char-sequence)"` or `"[-]nan"`; which style, and the meaning of any `n-char`-sequence, is + implementation-defined. The F conversion specifier produces `"INF"`, `"INFINITY"`, or `"NAN"` instead of `"inf"`, + `"infinity"`, or `"nan"`, respectively. + +* `e`, `E` The `double` argument is converted in the style `"[-]d.dddedd"`, where there is one digit before the radix +character (which is non-zero if the argument is non-zero) and the number of digits after it is equal to the precision; +if the precision is missing, it is taken as `6`; if the precision is zero and no `'#'` flag is present, no radix +character appears. The low-order digit is rounded in an implementation-defined manner. The E conversion specifier +produces a number with 'E' instead of 'e' introducing the exponent. The exponent always contains at least two digits. +If the value is zero, the exponent is zero. + A `double` argument representing an infinity or `NaN` is converted in the style of an `f` or `F` + conversion specifier. + +* `g`, `G` The `double` argument representing a floating-point number is converted in the style `f` or `e` +(or in the style `F` or `E` in the case of a `G` conversion specifier), depending on the value converted and the +precision. Let `P` equal the precision if non-zero, `6` if the precision is omitted, or `1` if the precision is zero. +Then, if a conversion with style `E` would have an exponent of `X`: + + * If `P > X>=-4`, the conversion is with style `f` (or `F` ) and precision `P -( X+1)`. + + * Otherwise, the conversion is with style `e` (or `E` ) and precision `P -1`. + + Finally, unless the `'#'` flag is used, any trailing zeros are removed from the fractional portion of the result and + the decimal-point character is removed if there is no fractional portion remaining. + + A `double` argument representing an infinity or `NaN` is converted in the style of an `f` or `F` conversion + specifier. + +* `a`, `A` A `double` argument representing a floating-point number is converted in the style `"[-]0xh.hhhhpd"`, where +there is one hexadecimal digit (which is non-zero if the argument is a normalized floating-point number and is otherwise +unspecified) before the decimal-point character and the number of hexadecimal digits after it is equal to the precision; +if the precision is missing and `FLT_RADIX` is a power of `2`, then the precision is sufficient for an exact +representation of the value; if the precision is missing and `FLT_RADIX` is not a power of `2`, then the precision is +sufficient to distinguish values of type `double`, except that trailing zeros may be omitted; if the precision is zero +and the `'#'` flag is not specified, no decimal-point character shall appear. The letters `"abcdef"` are used for `a` +conversion and the letters `"ABCDEF"` for `A` conversion. The `A` conversion specifier produces a number with `'X'` and +`'P'` instead of `'x'` and `'p'`. The exponent always contains at least one digit, and only as many more digits as +necessary to represent the decimal exponent of `2`. If the value is zero, the exponent is zero. + + A `double` argument representing an infinity or `NaN` is converted in the style of an `f` or `F` conversion + specifier. + +* `c` The int argument is converted to an `unsigned char`, and the resulting byte is written. + + If an `l` (`ell`) qualifier is present, the `wint_t` argument is converted as if by an `ls` conversion + specification with no precision and an argument that points to a two-element array of type `wchar_t`, the first + element of which contains the `wint_t` argument to the ls conversion specification and the second element + contains a null wide character. + +* `s` The argument is a pointer to an array of `char`. Bytes from the array are written up to (but not including) any +terminating null byte. If the precision is specified, no more than that many bytes is written. If the precision is not +specified or is greater than the size of the array, the application ensures that the array contains a null byte. If an `l` (`ell`) qualifier is present, the argument is a pointer to an array of type `wchar_t`. Wide characters from the array are converted to characters (each as if by a call to the `wcrtomb()` function, with the conversion state described by an `mbstate_t` object initialized to zero before the first wide character is converted) up to and including a terminating null wide character. The resulting characters are written up to (but not including) the terminating null character (byte). If no precision is specified, the application ensures that the array contains a null wide character. If a precision is specified, no more than that many characters (bytes) are written (including shift sequences, if any), and the array contains a null wide character if, to equal the character sequence length given by the precision, the function would need to access a wide character one past the end of the array. In no case a partial character is written. - * `p` The argument is a pointer to `void`. The value of the pointer is converted to a sequence of printable characters, in an implementation-defined manner. +* `p` The argument is a pointer to `void`. The value of the pointer is converted to a sequence of printable characters, +in an implementation-defined manner. - * `n` The argument is a pointer to an `integer` into which is written the number of bytes written to the output so far by this call to one of the `fprintf()` functions. No argument is converted. +* `n` The argument is a pointer to an `integer` into which is written the number of bytes written to the output so far +by this call to one of the `fprintf()` functions. No argument is converted. - * `C` Equivalent to `lc`. +* `C` Equivalent to `lc`. - * `S` Equivalent to `ls`. - - * `%` Print a `'%'` character; no argument is converted. The complete conversion specification is `%%`. +* `S` Equivalent to `ls`. -If a conversion specification does not match one of the above forms, the behavior is undefined. If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined. +* `%` Print a `'%'` character; no argument is converted. The complete conversion specification is `%%`. -In no case a nonexistent or small field width causes truncation of a field; if the result of a conversion is wider than the field width, the field is expanded to contain the conversion result. Characters generated by `fprintf()` and `printf()` are printed as if `fputc()` had been called. +If a conversion specification does not match one of the above forms, the behavior is undefined. If any argument is not +the correct type for the corresponding conversion specification, the behavior is undefined. -For the `a` and `A` conversion specifiers, if `FLT_RADIX` is a power of `2`, the value is correctly rounded to a hexadecimal floating number with the given precision. +In no case a nonexistent or small field width causes truncation of a field; if the result of a conversion is wider than +the field width, the field is expanded to contain the conversion result. Characters generated by `fprintf()` and +`printf()` are printed as if `fputc()` had been called. -For `a` and `A` conversions, if `FLT_RADIX` is not a power of `2` and the result is not exactly representable in the given precision, the result should be one of the two adjacent numbers in hexadecimal floating style with the given precision, with the extra stipulation that the error should have a correct sign for the current rounding direction. +For the `a` and `A` conversion specifiers, if `FLT_RADIX` is a power of `2`, the value is correctly rounded to a +hexadecimal floating number with the given precision. -For the `e`, `E`, `f`, `F`, `g`, and `G` conversion specifiers, if the number of significant decimal digits is at most `DECIMAL_DIG`, then the result should be correctly rounded. If the number of significant decimal digits is more than `DECIMAL_DIG` but the source value is exactly representable with `DECIMAL_DIG` digits, then the result should be an exact representation with trailing zeros. Otherwise, the source value is bounded by two adjacent decimal strings `L` < `U`, both having `DECIMAL_DIG` significant digits; the value of the resultant decimal string `D` should satisfy `L <= D <= U`, with the extra stipulation that the error should have a correct sign for the current rounding direction. +For `a` and `A` conversions, if `FLT_RADIX` is not a power of `2` and the result is not exactly representable in the +given precision, the result should be one of the two adjacent numbers in hexadecimal floating style with the given +precision, with the extra stipulation that the error should have a correct sign for the current rounding direction. + +For the `e`, `E`, `f`, `F`, `g`, and `G` conversion specifiers, if the number of significant decimal digits is at most +`DECIMAL_DIG`, then the result should be correctly rounded. If the number of significant decimal digits is more than +`DECIMAL_DIG` but the source value is exactly representable with `DECIMAL_DIG` digits, then the result should be an +exact representation with trailing zeros. Otherwise, the source value is bounded by two adjacent decimal +strings `L` < `U`, both having `DECIMAL_DIG` significant digits; the value of the resultant decimal string `D` should +satisfy `L <= D <= U`, with the extra stipulation that the error should have a correct sign for +the current rounding direction. The last data modification and last file status change timestamps of the file is marked for update: - * Between the call to a successful execution of `fprintf()` or `printf()` and the next successful completion of a call to `fflush()` or `fclose()` on the same stream or a call to `exit()` or `abort()`. +* Between the call to a successful execution of `fprintf()` or `printf()` and the next successful completion of a call +to `fflush()` or `fclose()` on the same stream or a call to `exit()` or `abort()`. - * Upon successful completion of a call to `dprintf()`. +* Upon successful completion of a call to `dprintf()`. -###Return value +### Return value On success: - * the `dprintf()`, `fprintf()`, and `printf()` functions return the number of bytes transmitted. +* the `dprintf()`, `fprintf()`, and `printf()` functions return the number of bytes transmitted. + +* the `sprintf()` function returns the number of bytes written to _s_, excluding the terminating null byte. - * the `sprintf()` function returns the number of bytes written to s, excluding the terminating null byte. - - * the `snprintf()` function returns the number of bytes that would be written to s had n been sufficiently large excluding the terminating null byte. +* the `snprintf()` function returns the number of bytes that would be written to _s_ had _n_ been sufficiently +large excluding the terminating null byte. -On output error these functions return `-1` and set `errno` to indicate the error. +On output error these functions return `-1` and set `errno` to indicate the error. -If the value of n is zero on a call to `snprintf()`, nothing is written, the number of bytes that would have been written had n been sufficiently large excluding the terminating null is returned, and s may be a null pointer. +If the value of _n_ is zero on a call to `snprintf()`, nothing is written, the number of bytes that would have been +written had _n_ been sufficiently large excluding the terminating null is returned, +and _s_ may be a null pointer. -###Errors +### Errors The conditions under which `dprintf()`, `fprintf()`, and `printf()` fail are as follows: -[`EAGAIN`] - The `O_NONBLOCK` flag is set for the file descriptor underlying stream and the thread would be delayed in the write operation. +[`EAGAIN`] - The `O_NONBLOCK` flag is set for the file descriptor underlying stream and the thread would be delayed in +the write operation. [`EBADF`] - The file descriptor underlying stream is not a valid file descriptor open for writing. -[`EFBIG`] - An attempt was made to write to a file that exceeds the maximum file size or - - An attempt was made to write to a file that exceeds the file size limit of the process or - - The file is a regular file and an attempt was made to write at or beyond the offset maximum. -[`EINTR`] - The write operation was terminated due to the receipt of a signal, and no data was transferred. -[`EIO`] - A physical I/O error has occurred, or the process is a member of a background process group attempting to write to its controlling terminal, `TOSTOP` is set, the calling thread is not blocking `SIGTTOU`, the process is not ignoring `SIGTTOU`, and the process group of the process is orphaned. This error may also be returned under implementation-defined conditions. -[`ENOSPC`] - There was no free space remaining on the device containing the file. -[`EPIPE`] - An attempt is made to write to a pipe or FIFO that is not open for reading by any process. A `SIGPIPE` signal shall also be sent to the thread. -[`ENOMEM`] - Insufficient storage space is available. -[`ENXIO`] - A request was made of a nonexistent device, or the request was outside the capabilities of the device. +[`EFBIG`] - An attempt was made to write to a file that exceeds the maximum file size or + - An attempt was made to write to a file that exceeds the file size limit of the process or + - The file is a regular file and an attempt was made to write at or beyond the offset maximum. +[`EINTR`] - The write operation was terminated due to the receipt of a signal, and no data was transferred. +[`EIO`] - A physical I/O error has occurred, or the process is a member of a background process group attempting to +write to its controlling terminal, `TOSTOP` is set, the calling thread is not blocking `SIGTTOU`, the process is not +ignoring `SIGTTOU`, and the process group of the process is orphaned. This error may also be returned under +implementation-defined conditions. +[`ENOSPC`] - There was no free space remaining on the device containing the file. +[`EPIPE`] - An attempt is made to write to a pipe or FIFO that is not open for reading by any process. A `SIGPIPE` +signal shall also be sent to the thread. +[`ENOMEM`] - Insufficient storage space is available. +[`ENXIO`] - A request was made of a nonexistent device, or the request was outside the capabilities of the device. [`EILSEQ`] - A wide-character code that does not correspond to a valid character has been detected. -[`EOVERFLOW`] - The value to be returned or the value of n is greater than {`INT_MAX`}. +[`EOVERFLOW`] - The value to be returned or the value of _n_ is greater than {`INT_MAX`}. The `dprintf()`, `fprintf()`, and `printf()` functions fail if: [`ENOMEM`] - Insufficient storage space is available. - -###Examples +### Examples The following example prints a series of wide characters. Suppose that `"L`@`"` expands to three bytes: -`wchar_t wz [3] = L"@@"; // Zero-terminated ` -`wchar_t wn [3] = L"@@@"; // Unterminated ` +`wchar_t wz [3] = L"@@"; // Zero-terminated` + +`wchar_t wn [3] = L"@@@"; // Unterminated` + +`fprintf (stdout,"%ls", wz); // Outputs 6 bytes` + +`fprintf (stdout,"%ls", wn); // Undefined because wn has no terminator` + +`fprintf (stdout,"%4ls", wz); // Outputs 3 bytes` + +`fprintf (stdout,"%4ls", wn); // Outputs 3 bytes; no terminator needed` + +`fprintf (stdout,"%9ls", wz); // Outputs 6 bytes` + +`fprintf (stdout,"%9ls", wn); // Outputs 9 bytes; no terminator needed` +`fprintf (stdout,"%10ls", wz); // Outputs 6 bytes` -`fprintf (stdout,"%ls", wz); // Outputs 6 bytes ` -`fprintf (stdout,"%ls", wn); // Undefined because wn has no terminator ` -`fprintf (stdout,"%4ls", wz); // Outputs 3 bytes ` -`fprintf (stdout,"%4ls", wn); // Outputs 3 bytes; no terminator needed ` -`fprintf (stdout,"%9ls", wz); // Outputs 6 bytes ` -`fprintf (stdout,"%9ls", wn); // Outputs 9 bytes; no terminator needed ` -`fprintf (stdout,"%10ls", wz); // Outputs 6 bytes ` -`fprintf (stdout,"%10ls", wn); // Undefined because wn has no terminator ` +`fprintf (stdout,"%10ls", wn); // Undefined because wn has no terminator` -In the last line of the example, after processing three characters, nine bytes have been output. The fourth character must then be examined to determine whether it converts to one byte or more. If it converts to more than one byte, the output is only nine bytes. Since there is no fourth character in the array, the behavior is undefined. +In the last line of the example, after processing three characters, nine bytes have been output. The fourth character +must then be examined to determine whether it converts to one byte or more. If it converts to more than one byte, the +output is only nine bytes. Since there is no fourth character in the array, the behavior is undefined. -###Implementation tasks +### Implementation tasks * implement wide characters, * implement error detection diff --git a/libc/functions/d/dup.part-impl.md b/libc/functions/d/dup.part-impl.md index 31774b75..fca04986 100644 --- a/libc/functions/d/dup.part-impl.md +++ b/libc/functions/d/dup.part-impl.md @@ -1,23 +1,27 @@ -# Synopsis -`#include `
+# Synopsis -` int dup(int fildes);`
+`#include ` -` int dup2(int fildes, int fildes2);`
+`int dup(int fildes);` + +`int dup2(int fildes, int fildes2);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The `dup()` function provides an alternative interface to the service provided by `fcntl()` using the `F_DUPFD` command. The call `dup(fildes)` shall be equivalent +The `dup()` function provides an alternative interface to the service provided by `fcntl()` using the `F_DUPFD` command. +The call `dup(fildes)` shall be equivalent to: `fcntl(fildes, F_DUPFD, 0);` - The `dup2()` function shall cause the file descriptor _fildes2_ to refer to the same open file description as the file descriptor _fildes_ and to share any locks, and shall return _fildes2_ . If _fildes2_ is already a valid open file descriptor, it shall be closed first, unless _fildes_ is equal to _fildes2_ in which case `dup2()` shall return @@ -26,45 +30,34 @@ changing the open file description to which _fildes2_ refers. If _fildes_ is no shall return `-1` and shall not close _fildes2_ . If _fildes2_ is less than `0` or greater than or equal to `OPEN_MAX`, `dup2()` shall return `-1` with errno set to `EBADF`. -Upon successful completion, if _fildes_ is not equal to _fildes2_ , the `FD_CLOEXEC` flag associated with _fildes2_ +Upon successful completion, if _fildes_ is not equal to _fildes2_ , the `FD_CLOEXEC` flag associated with _fildes2_ shall be cleared. If _fildes_ is equal to _fildes2_ , the `FD_CLOEXEC` flag associated with _fildes2_ shall not be changed. -If _fildes_ refers to a typed memory object, the result of the `dup2()` function is unspecified. - +If _fildes_ refers to a typed memory object, the result of the `dup2()` function is unspecified. ## Return value - -Upon successful completion a non-negative integer, namely the file descriptor, shall be returned; otherwise, `-1` shall be -returned and errno set to indicate the error. - +Upon successful completion a non-negative integer, namely the file descriptor, shall be returned; otherwise, `-1` shall +be returned and errno set to indicate the error. ## Errors - The `dup()` function shall fail if: +* `EBADF` - The _fildes_ argument is not a valid open file descriptor. - * `EBADF` - The _fildes_ argument is not a valid open file descriptor. - - * `EMFILE` - All file descriptors available to the process are currently open. +* `EMFILE` - All file descriptors available to the process are currently open. The `dup2()` function shall fail if: +* `EBADF` - The _fildes_ argument is not a valid open file descriptor or the argument _fildes2_ is negative or greater + than or equal to `OPEN_MAX`. - * `EBADF` - The _fildes_ argument is not a valid open file descriptor or the argument _fildes2_ is negative or greater than or -equal to `OPEN_MAX`. - - * `EINTR` - The `dup2()` function was interrupted by a signal. +* `EINTR` - The `dup2()` function was interrupted by a signal. The `dup2()` function may fail if: - - * `EIO` - An I/O error occurred while attempting to close _fildes2_ . - - - - +* `EIO` - An I/O error occurred while attempting to close _fildes2_ . ## Tests @@ -74,6 +67,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/e/execl.part-impl.md b/libc/functions/e/execl.part-impl.md index 677c1126..8092d5c7 100644 --- a/libc/functions/e/execl.part-impl.md +++ b/libc/functions/e/execl.part-impl.md @@ -1,61 +1,65 @@ -# Synopsis -`#include `
+# Synopsis -` extern char **environ;`
+`#include ` -` int execl(const char *path, const char *arg0, ... /*, (char *)0 */);`
+`extern char **environ;` + +`int execl(const char *path, const char *arg0, ... /*, (char *)0 */);` -` int execle(const char *path, const char *arg0, (char *)0, char *const envp[]/*);`
+`int execle(const char *path, const char *arg0, (char *)0, char *const envp[]/*);` -` int execlp(const char *file, const char *arg0, ... /*, (char *)0 */);`
+`int execlp(const char *file, const char *arg0, ... /*, (char *)0 */);` -` int execv(const char *path, char *const argv[]);`
+`int execv(const char *path, char *const argv[]);` -` int execve(const char *path, char *const argv[], char *const envp[]);`
+`int execve(const char *path, char *const argv[], char *const envp[]);` -` int execvp(const char *file, char *const argv[]);`
+`int execvp(const char *file, char *const argv[]);` -` int fexecve(int fd, char *const argv[], char *const envp[]);`
+`int fexecve(int fd, char *const argv[], char *const envp[]);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `exec` family of functions shall replace the current process image with a new process image. The new image shall be -constructed from a regular, executable file called the new process image file. There shall be no return from a successful -`exec`, because the calling process image is overlaid by the new process image. +constructed from a regular, executable file called the new process image file. There shall be no return from a +successful `exec`, because the calling process image is overlaid by the new process image. The `fexecve()` function shall be equivalent to the `execve()` function except that the file to be executed is determined by the file descriptor `fd` instead of a pathname. The file offset of `fd` is ignored. -When a C-language program is executed as a result of a call to one of the `exec` family of functions, it shall be entered -as a C-language function call as follows: +When a C-language program is executed as a result of a call to one of the `exec` family of functions, it shall be +entered as a C-language function call as follows: `int main (int argc, char *argv[]);` - where _argc_ is the argument count and _argv_ is an array of character pointers to the arguments themselves. In addition, the following variable, which must be declared by the user if it is to be used directly: `extern char **environ;` - is initialized as a pointer to an array of character pointers to the environment strings. The _argv_ and _environ_ -arrays are each terminated by a `null` pointer. The `null` pointer terminating the _argv_ array is not counted in _argc_. +arrays are each terminated by a `null` pointer. The `null` pointer terminating the _argv_ array is not +counted in _argc_. Applications can change the entire environment in a single operation by assigning the _environ_ variable to point to an -array of character pointers to the new environment strings. After assigning a new value to `environ`, applications should not -rely on the new environment strings remaining part of the environment, as a call to `getenv()`, `putenv()`, `setenv()`, `unsetenv()`, or any function that is dependent on an environment variable may, on noticing +array of character pointers to the new environment strings. After assigning a new value to `environ`, applications +should not rely on the new environment strings remaining part of the environment, as a call to `getenv()`, `putenv()`, +`setenv()`, `unsetenv()`, or any function that is dependent on an environment variable may, on noticing that _environ_ has changed, copy the environment strings to a new array and assign _environ_ to point to it. Any application that directly modifies the pointers to which the _environ_ variable points has undefined behavior. Conforming multi-threaded applications shall not use the _environ_ variable to access or modify any environment variable -while any other thread is concurrently modifying any environment variable. A call to any function dependent on any environment -variable shall be considered a use of the _environ_ variable to access that environment variable. +while any other thread is concurrently modifying any environment variable. A call to any function dependent on any +environment variable shall be considered a use of the _environ_ variable to access that environment variable. The arguments specified by a program with one of the `exec` functions shall be passed on to the new process image in the corresponding `main()` arguments. @@ -63,28 +67,31 @@ corresponding `main()` arguments. The argument _path_ points to a pathname that identifies the new process image file. The argument file is used to construct a pathname that identifies the new process image file. If the file argument -contains a `` character, the file argument shall be used as the pathname for this file. Otherwise, the path -prefix for this file is obtained by a search of the directories passed as the environment variable `PATH` (see `XBD` Environment Variables). If this environment variable is not present, the results of -the search are implementation-defined. +contains a ``/`` character, the file argument shall be used as the pathname for this file. Otherwise, the path +prefix for this file is obtained by a search of the directories passed as the environment variable `PATH` (see `XBD` +Environment Variables). If this environment variable is not present, the results of the search are +implementation-defined. -There are two distinct ways in which the contents of the process image file may cause the execution to fail, distinguished by -the setting of `errno` to either `ENOEXEC` or `EINVAL` (see the `ERRORS` section). In the cases where the other members of the -`exec` family of functions would fail and set `errno` to `ENOEXEC`, the `execlp()` and `execvp()` functions -shall execute a command interpreter and the environment of the executed command shall be as if the process invoked the sh utility using `execl()` as follows: +There are two distinct ways in which the contents of the process image file may cause the execution to fail, +distinguished by the setting of `errno` to either `ENOEXEC` or `EINVAL` (see the `ERRORS` section). In the cases where +the other members of the `exec` family of functions would fail and set `errno` to `ENOEXEC`, the `execlp()` and +`execvp()` functions shall execute a command interpreter and the environment of the executed command shall be as if the +process invoked the sh utility using `execl()` as follows: `execl(, arg0, file, arg1, ..., (char *)0);` - where `` is an unspecified pathname for the `sh` utility, file is the process image file, and for `execvp()`, where _arg0_, _arg1_, and so on correspond to the values passed to `execvp()` in _argv[0]_, _argv[1]_, and so on. -The arguments represented by _arg0_,... are pointers to `null`-terminated character strings. These strings shall constitute -the argument list available to the new process image. The list is terminated by a `null` pointer. The argument _arg0_ should -point to a filename string that is associated with the process being started by one of the `exec` functions. +The arguments represented by _arg0_,... are pointers to `null`-terminated character strings. These strings shall +constitute the argument list available to the new process image. The list is terminated by a `null` pointer. The +argument _arg0_ should point to a filename string that is associated with the process being started by one of the `exec` +functions. -The argument _argv_ is an array of character pointers to `null`-terminated strings. The application shall ensure that the -last member of this array is a `null` pointer. These strings shall constitute the argument list available to the new process image. +The argument _argv_ is an array of character pointers to `null`-terminated strings. The application shall ensure that +the last member of this array is a `null` pointer. These strings shall constitute the argument list available to +the new process image. The value in _argv[0]_ should point to a filename string that is associated with the process being started by one of the `exec` functions. @@ -98,17 +105,16 @@ the environment for the new process image shall be taken from the external varia The number of bytes available for the new process' combined argument and environment lists is ``ARG_MAX``. It is implementation-defined whether `null` terminators, pointers, and/or any alignment bytes are included in this total. -File descriptors open in the calling process image shall remain open in the new process image, except for those whose close-on- -`exec` flag `FD_CLOEXEC` is set. For those file descriptors that remain open, all attributes of the open file description remain -unchanged. For any file descriptor that is closed for this reason, file locks are removed as a result of the close as described in -`close()`. Locks that are not removed by closing of file descriptors remain -unchanged. +File descriptors open in the calling process image shall remain open in the new process image, except for those whose +close-on- `exec` flag `FD_CLOEXEC` is set. For those file descriptors that remain open, all attributes of the open file +description remain unchanged. For any file descriptor that is closed for this reason, file locks are removed as a result +of the close as described in `close()`. Locks that are not removed by closing of file descriptors remain unchanged. -If file descriptor `0`, `1`, or `2` would otherwise be closed after a successful call to one of the `exec` family of functions, -implementations may open an unspecified file for the file descriptor in the new process image. If a standard utility or a -conforming application is executed with file descriptor `0` not open for reading or with file descriptor `1` or `2` not open for writing, -the environment in which the utility or application is executed shall be deemed non-conforming, and consequently the utility or -application might not behave as described in this standard. +If file descriptor `0`, `1`, or `2` would otherwise be closed after a successful call to one of the `exec` family of +functions, implementations may open an unspecified file for the file descriptor in the new process image. If a standard +utility or a conforming application is executed with file descriptor `0` not open for reading or with file descriptor +`1` or `2` not open for writing, the environment in which the utility or application is executed shall be deemed +non-conforming, and consequently the utility or application might not behave as described in this standard. Directory streams open in the calling process image shall be closed in the new process image. @@ -120,301 +126,203 @@ For the new process image, the equivalent of: `setlocale(LC_ALL, "C")` - shall be executed at start-up. -Signals set to the default action `(SIG_DFL)` in the calling process image shall be set to the default action in the new process -image. Except for `SIGCHLD`, signals set to be ignored `(SIG_IGN)` by the calling process image shall be set to be ignored by the new -process image. Signals set to be caught by the calling process image shall be set to the default action in the new process image -(see ``). +Signals set to the default action `(SIG_DFL)` in the calling process image shall be set to the default action in the new +process image. Except for `SIGCHLD`, signals set to be ignored `(SIG_IGN)` by the calling process image shall be set to +be ignored by the new process image. Signals set to be caught by the calling process image shall be set to the default +action in the new process image (see ``). -If the `SIGCHLD` signal is set to be ignored by the calling process image, it is unspecified whether the `SIGCHLD` signal is set to -be ignored or to the default action in the new process image. +If the `SIGCHLD` signal is set to be ignored by the calling process image, it is unspecified whether the `SIGCHLD` +signal is set to be ignored or to the default action in the new process image. After a successful call to any of the `exec` functions, alternate signal stacks are not preserved and the `SA_ONSTACK` -flag shall be cleared for all signals. -After a successful call to any of the `exec` functions, any functions previously registered by the `atexit()` or ``pthread_atfork()`` functions -are no longer registered. -If the `ST_NOSUID` bit is set for the file system containing the new process image file, then the effective user ID, effective group -ID, saved set-user-ID, and saved set-group-ID are unchanged in the new process image. Otherwise, if the set-user-ID mode bit of the new process image file is set, the effective user ID of the new -process image shall be set to the user ID of the new process image file. Similarly, if the set-group-ID mode bit of the new process -image file is set, the effective group ID of the new process image shall be set to the group ID of the new process image file. The -real user ID, real group ID, and supplementary group IDs of the new process image shall remain the same as those of the calling -process image. The effective user ID and effective group ID of the new process image shall be saved (as the saved set-user-ID and -the saved set-group-ID) for use by `setuid()`. -Any shared memory segments attached to the calling process image shall not be attached to the new process image. +flag shall be cleared for all signals. +After a successful call to any of the `exec` functions, any functions previously registered by the `atexit()` or +``pthread_atfork()`` functions are no longer registered. +If the `ST_NOSUID` bit is set for the file system containing the new process image file, then the effective user ID, +effective group ID, saved set-user-ID, and saved set-group-ID are unchanged in the new process image. Otherwise, if the +set-user-ID mode bit of the new process image file is set, the effective user ID of the new process image shall be set +to the user ID of the new process image file. Similarly, if the set-group-ID mode bit of the new process image file is +set, the effective group ID of the new process image shall be set to the group ID of the new process image file. +The real user ID, real group ID, and supplementary group IDs of the new process image shall remain the same as those of +the calling process image. The effective user ID and effective group ID of the new process image shall be saved (as the +saved set-user-ID and the saved set-group-ID) for use by `setuid()`. +Any shared memory segments attached to the calling process image shall not be attached to the new process image. Any named semaphores open in the calling process shall be closed as if by appropriate calls to ``sem_close()``. -Any blocks of typed memory that were mapped in the calling process are unmapped, as if `munmap()` was implicitly called to unmap them. -Memory locks established by the calling process via calls to `mlockall()` or `mlock()` shall be removed. If locked pages in the address space of the calling process are also -mapped into the address spaces of other processes and are locked by those processes, the locks established by the other processes -shall be unaffected by the call by this process to the `exec` function. If the `exec` function fails, the effect on -memory locks is unspecified. +Any blocks of typed memory that were mapped in the calling process are unmapped, as if `munmap()` was implicitly called +to unmap them. Memory locks established by the calling process via calls to `mlockall()` or `mlock()` shall be removed. +If locked pages in the address space of the calling process are also mapped into the address spaces of other processes +and are locked by those processes, the locks established by the other processes shall be unaffected by the call by this +process to the `exec` function. If the `exec` function fails, the effect on +memory locks is unspecified. Memory mappings created in the process are unmapped before the address space is rebuilt for the new process image. When the calling process image does not use the `SCHED_FIFO,` `SCHED_RR,` or `SCHED_SPORADIC`  scheduling policies, the scheduling policy and parameters of the new process image and the initial thread in that new process image are implementation-defined. -When the calling process image uses the `SCHED_FIFO,` `SCHED_RR,` or `SCHED_SPORADIC` scheduling policies, the process policy and -scheduling parameter settings shall not be changed by a call to an `exec` function. The initial thread in the new process image shall inherit the process scheduling policy and -parameters. It shall have the default system contention scope, but shall inherit its allocation domain from the calling process -image. -Per-process timers created by the calling process shall be deleted before replacing the current process image with the new -process image. -All open message queue descriptors in the calling process shall be closed, as described in ``mq_close()``. -Any outstanding asynchronous I/O operations may be canceled. Those asynchronous I/O operations that are not canceled shall -complete as if the `exec` function had not yet occurred, but any associated signal notifications shall be suppressed. It is -unspecified whether the `exec` function itself blocks awaiting such I/O completion. In no event, however, shall the new -process image created by the `exec` function be affected by the presence of outstanding asynchronous I/O operations at the -time the `exec` function is called. Whether any I/O is canceled, and which I/O may be canceled upon `exec`, is -implementation-defined. -The new process image shall inherit the CPU-time clock of the calling process image. This inheritance means that the process -CPU-time clock of the process being exec-ed shall not be reinitialized or altered as a result of the `exec` function -other than to reflect the time spent by the process executing the `exec` function itself. -The initial value of the CPU-time clock of the initial thread of the new process image shall be set to zero. -If the calling process is being traced, the new process image shall continue to be traced into the same trace stream as the -original process image, but the new process image shall not inherit the mapping of trace event names to trace event type -identifiers that was defined by calls to the ``posix_trace_eventid_open()`` or the ``posix_trace_trid_eventid_open()`` functions in the calling process +When the calling process image uses the `SCHED_FIFO,` `SCHED_RR,` or `SCHED_SPORADIC` scheduling policies, the process +policy and scheduling parameter settings shall not be changed by a call to an `exec` function. The initial thread in the +new process image shall inherit the process scheduling policy and parameters. It shall have the default system +contention scope, but shall inherit its allocation domain from the calling process image. - -If the calling process is a trace controller process, any trace streams that were created by the calling process shall be shut -down as described in the ``posix_trace_shutdown()`` function. -The thread ID of the initial thread in the new process image is unspecified. +Per-process timers created by the calling process shall be deleted before replacing the current process image with the +new process image. +All open message queue descriptors in the calling process shall be closed, as described in ``mq_close()``. +Any outstanding asynchronous I/O operations may be canceled. Those asynchronous I/O operations that are not canceled +shall complete as if the `exec` function had not yet occurred, but any associated signal notifications shall +be suppressed. It is unspecified whether the `exec` function itself blocks awaiting such I/O completion. In no event, +however, shall the new process image created by the `exec` function be affected by the presence of outstanding +asynchronous I/O operations at the time the `exec` function is called. Whether any I/O is canceled, and which I/O may be +canceled upon `exec`, is implementation-defined. +The new process image shall inherit the CPU-time clock of the calling process image. This inheritance means that the +process CPU-time clock of the process being exec-ed shall not be reinitialized or altered as a result of the `exec` +function other than to reflect the time spent by the process executing the `exec` function itself. +The initial value of the CPU-time clock of the initial thread of the new process image shall be set to zero. +If the calling process is being traced, the new process image shall continue to be traced into the same trace stream as +the original process image, but the new process image shall not inherit the mapping of trace event names to trace event +type identifiers that was defined by calls to the ``posix_trace_eventid_open()`` or the +``posix_trace_trid_eventid_open()`` functions in the calling process image. + +If the calling process is a trace controller process, any trace streams that were created by the calling process shall +be shut down as described in the ``posix_trace_shutdown()`` function. The thread ID of the initial thread in the new +process image is unspecified. The size and location of the stack on which the initial thread in the new process image runs is unspecified. -The initial thread in the new process image shall have its cancellation type set to `PTHREAD_CANCEL_DEFERRED` and its cancellation -state set to `PTHREAD_CANCEL_ENABLED`. +The initial thread in the new process image shall have its cancellation type set to `PTHREAD_CANCEL_DEFERRED` and its +cancellation state set to `PTHREAD_CANCEL_ENABLED`. -The initial thread in the new process image shall have all thread-specific data values set to `null` and all thread-specific data -keys shall be removed by the call to `exec` without running destructors. +The initial thread in the new process image shall have all thread-specific data values set to `null` and all +thread-specific data keys shall be removed by the call to `exec` without running destructors. The initial thread in the new process image shall be joinable, as if created with the detachstate attribute set to `PTHREAD_CREATE_JOINABLE`. The new process shall inherit at least the following attributes from the calling process image: +* Nice value (see `nice()`) - -* Nice value (see `nice()`) - - - - - -* semadj values (see `semop()`) - - - - +* semadj values (see `semop()`) * Process ID - - - - * Parent process ID - - - - * Process group ID - - - - * Session membership - - - - * Real user ID - - - - * Real group ID - - - - * Supplementary group IDs - - - - * Time left until an alarm clock signal (see `alarm()`) - - - - * Current working directory - - - - * Root directory - - - - * File mode creation mask (see `umask()`) - - - - -* File size limit (see `getrlimit()` and `setrlimit()`) - - - - +* File size limit (see `getrlimit()` and `setrlimit()`) * Process signal mask (see `pthread_sigmask()`) - - - - * Pending signal (see `sigpending()`) - - - - * `tms_utime,` `tms_stime,` `tms_cutime,` and `tms_cstime` (see `times()`) - - - -* Resource limits - - - - +* Resource limits * Controlling terminal - - - - -* Interval timers - - - +* Interval timers The initial thread of the new process shall inherit at least the following attributes from the calling thread: - - * Signal mask (see `sigprocmask()` and `pthread_sigmask()`) - - - - * Pending signals (see `sigpending()`) +All other process attributes defined in this volume of `POSIX.1-2017` shall be inherited in the new process image from +the old process image. All other thread attributes defined in this volume of `POSIX.1-2017` shall be inherited in the +initial thread in the new process image from the calling thread in the old process image. The inheritance of process or +thread attributes not defined by this volume of `POSIX.1-2017` is implementation-defined. - - -All other process attributes defined in this volume of `POSIX.1-2017` shall be inherited in the new process image from the old -process image. All other thread attributes defined in this volume of `POSIX.1-2017` shall be inherited in the initial thread in the -new process image from the calling thread in the old process image. The inheritance of process or thread attributes not defined by -this volume of `POSIX.1-2017` is implementation-defined. - -A call to any `exec` function from a process with more than one thread shall result in all threads being terminated and the -new executable image being loaded and executed. No destructor functions or cleanup handlers shall be called. +A call to any `exec` function from a process with more than one thread shall result in all threads being terminated and +the new executable image being loaded and executed. No destructor functions or cleanup handlers shall be called. Upon successful completion, the `exec` functions shall mark for update the last data access timestamp of the file. If an -`exec` function failed but was able to locate the process image file, whether the last data access timestamp is marked for -update is unspecified. Should the `exec` function succeed, the process image file shall be considered to have been opened with -`open()`. The corresponding `close()` shall be -considered to occur at a time after this open, but before process termination or successful completion of a subsequent call to one -of the `exec` functions, `posix_spawn()`, or `posix_spawnp()`. The _argv[]_ and _envp[]_ arrays of pointers and the strings -to which those arrays point shall not be modified by a call to one of the `exec` functions, except as a consequence of -replacing the process image. - -The saved resource limits in the new process image are set to be a copy of the process' corresponding hard and soft limits. +`exec` function failed but was able to locate the process image file, whether the last data access timestamp is marked +for update is unspecified. Should the `exec` function succeed, the process image file shall be considered to have been +opened with `open()`. The corresponding `close()` shall be considered to occur at a time after this open, but before +process termination or successful completion of a subsequent call to one of the `exec` functions, `posix_spawn()`, or +`posix_spawnp()`. The _argv[]_ and _envp[]_ arrays of pointers and the strings to which those arrays point shall not be +modified by a call to one of the `exec` functions, except as a consequence of replacing the process image. +The saved resource limits in the new process image are set to be a copy of the process' corresponding hard and soft +limits. ## Return value - -If one of the `exec` functions returns to the calling process image, an error has occurred; the return value shall be `-1`, -and `errno` shall be set to indicate the error. - +If one of the `exec` functions returns to the calling process image, an error has occurred; the return value shall be +`-1`, and `errno` shall be set to indicate the error. ## Errors - The `exec` functions shall fail if: +* `E2BIG` - The number of bytes used by the new process image's argument list and environment list is greater than the +system-imposed limit of `ARG_MAX` bytes. - * `E2BIG` - The number of bytes used by the new process image's argument list and environment list is greater than the system-imposed limit -of `ARG_MAX` bytes. - - * `EACCES` - The new process image file is not a regular file and the implementation does not support execution of files of its type. +* `EACCES` - The new process image file is not a regular file and the implementation does not support execution of files +of its type. - * `EINVAL` - The new process image file has appropriate privileges and has a recognized executable binary format, but the system does not -support execution of a file with this format. +* `EINVAL` - The new process image file has appropriate privileges and has a recognized executable binary format, but +the system does not support execution of a file with this format. The `exec` functions, except for `fexecve()`, shall fail if: +* `EACCES` - Search permission is denied for a directory listed in the new process image file's _path_ prefix, or the +new process image file denies execution permission. - * `EACCES` - Search permission is denied for a directory listed in the new process image file's _path_ prefix, or the new process image file -denies execution permission. +* `ELOOP` - A loop exists in symbolic links encountered during resolution of the _path_ or file argument. - * `ELOOP` - A loop exists in symbolic links encountered during resolution of the _path_ or file argument. -`ENAMETOOLONG` +* `ENAMETOOLONG` -The length of a component of a pathname is longer than `NAME_MAX`. -The length of a component of a pathname is longer than `NAME_MAX`. +* `ENOENT` - A component of _path_ or file does not name an existing file or _path_ or file is an empty string. - * `ENOENT` - A component of _path_ or file does not name an existing file or _path_ or file is an empty string. - - * `ENOTDIR` - A component of the new process image file's _path_ prefix names an existing file that is neither a directory nor a symbolic link -to a directory, or the new process image file's pathname contains at least one non- character and ends with one or -more trailing characters and the last pathname component names an existing file that is neither a directory nor a -symbolic link to a directory. +* `ENOTDIR` - A component of the new process image file's _path_ prefix names an existing file that is neither a +directory nor a symbolic link to a directory, or the new process image file's pathname contains at least one non- `/` +character and ends with one or more trailing `/` characters and the last pathname component names an existing file that +is neither a directory nor a symbolic link to a directory. The `exec` functions, except for `execlp()` and `execvp()`, shall fail if: - - * `ENOEXEC` - The new process image file has the appropriate access permission but has an unrecognized format. +* `ENOEXEC` - The new process image file has the appropriate access permission but has an unrecognized format. The `fexecve()` function shall fail if: - - * `EBADF` - The `fd` argument is not a valid file descriptor open for executing. +* `EBADF` - The `fd` argument is not a valid file descriptor open for executing. The `exec` functions may fail if: - - * `ENOMEM` - The new process image requires more memory than is allowed by the hardware or system-imposed memory management -constraints. +* `ENOMEM` - The new process image requires more memory than is allowed by the hardware or system-imposed memory +management constraints. The `exec` functions, except for `fexecve()`, may fail if: +* `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the _path_ or file argument. - * `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the _path_ or file argument. - - * `ENAMETOOLONG` - The length of the _path_ argument or the length of the pathname constructed from the file argument exceeds `PATH_MAX`, -or pathname resolution of a symbolic link produced an intermediate result with a length that exceeds `PATH_MAX`. - - * `ETXTBSY` - The new process image file is a pure procedure (shared text) file that is currently open for writing by some process. - - - +* `ENAMETOOLONG` - The length of the _path_ argument or the length of the pathname constructed from the file argument +exceeds +`PATH_MAX`, or pathname resolution of a symbolic link produced an intermediate result with a length that exceeds +`PATH_MAX`. +* `ETXTBSY` - The new process image file is a pure procedure (shared text) file that is currently open for writing by +some process. ## Tests @@ -424,6 +332,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/e/exit.part-impl.md b/libc/functions/e/exit.part-impl.md index 16e45e6f..ccc01809 100644 --- a/libc/functions/e/exit.part-impl.md +++ b/libc/functions/e/exit.part-impl.md @@ -1,44 +1,45 @@ -# Synopsis +# Synopsis + `#include `
-` void exit(int status);`
+`void exit(int status);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description -The value of _status_ may be 0, `EXIT_SUCCESS,` `EXIT_FAILURE,`  or any other value, though only the least significant 8 bits -(that is, `(_status_ & 0377)`) shall be available from `wait()` and `waitpid()`. The full value shall be available from `waitid()` and in the `siginfo_t` passed to a signal handler for `SIGCHLD`. -The `exit()` function shall first call all functions registered by `atexit()`, -in the reverse order of their registration, except that a function is called after any previously registered functions that had -already been called at the time it was registered. Each function is called as many times as it was registered. If, during the call -to any such function, a call to the `longjmp()` function is made that would terminate -the call to the registered function, the behavior is undefined. +The value of _status_ may be 0, `EXIT_SUCCESS,` `EXIT_FAILURE,`  or any other value, though only the least significant +8 bits (that is, `(_status_ & 0377)`) shall be available from `wait()` and `waitpid()`. The full value shall be +available from `waitid()` and in the `siginfo_t` passed to a signal handler for `SIGCHLD`. -If a function registered by a call to `atexit()` fails to return, the remaining -registered functions shall not be called and the rest of the `exit()` processing shall not be completed. If `exit()` is -called more than once, the behavior is undefined. +The `exit()` function shall first call all functions registered by `atexit()`, in the reverse order of their +registration, except that a function is called after any previously registered functions that had already been called at +the time it was registered. Each function is called as many times as it was registered. If, during the call to any such +function, a call to the `longjmp()` function is made that would terminate the call to the registered function, the +behavior is undefined. -The `exit()` function shall then flush all open streams with unwritten buffered data and close all open streams. Finally, -the process shall be terminated  with the same consequences as described in Consequences of Process Termination. +If a function registered by a call to `atexit()` fails to return, the remaining registered functions shall not be called +and the rest of the `exit()` processing shall not be completed. If `exit()` is called more than once, the behavior is +undefined. +The `exit()` function shall then flush all open streams with unwritten buffered data and close all open streams. +Finally, the process shall be terminated  with the same consequences as described in Consequences of Process +Termination. ## Return value - The `exit()` function does not return. - ## Errors - No errors are defined. - - - ## Tests Untested @@ -47,6 +48,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/e/exp.part-impl.md b/libc/functions/e/exp.part-impl.md index 182d192f..1fd93bd8 100644 --- a/libc/functions/e/exp.part-impl.md +++ b/libc/functions/e/exp.part-impl.md @@ -1,18 +1,22 @@ -# Synopsis -`#include `
+# Synopsis -` double exp(double x);`
+`#include -` float expf(float x);`
+`double exp(double x); -` long double expl(long double x);`
+`float expf(float x); + +`long double expl(long double x); ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description These functions shall compute the base `e` exponential of _x_. @@ -20,52 +24,42 @@ An application wishing to check for error situations should set `errno` to zero `feclearexcept(FE_ALL_EXCEPT)` before calling these functions. On return, if `errno` is non-zero or `fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)` is non-zero, an error has occurred. - ## Return value - Upon successful completion, these functions shall return the exponential value of _x_. -If the correct value would cause overflow, a range error shall occur and `exp()`, `expf()`, and `expl()` shall -return the value of the macro `HUGE_VAL`, `HUGE_VALF`, and `HUGE_VALL`, respectively. +* If the correct value would cause overflow, a range error shall occur and `exp()`, `expf()`, and `expl()` shall return +the value of the macro `HUGE_VAL`, `HUGE_VALF`, and `HUGE_VALL`, respectively. -If the correct value would cause underflow,  and is not representable, a range error may occur, and `exp()`, `expf()`, and `expl()` shall return  `0.0`, or  (if the IEC 60559 Floating-Point option is not supported) an +* If the correct value would cause underflow,  and is not representable, a range error may occur, and `exp()`, +`expf()`, and `expl()` shall return  `0.0`, or  (if the IEC 60559 Floating-Point option is not supported) an implementation-defined value no greater in magnitude than `DBL_MIN`, `FLT_MIN`, and `LDBL_MIN`, respectively. -If -_x_ is `NaN`, a `NaN` shall be returned. - -If _x_ is `±0`, `1` shall be returned. - -If _x_ is `-Inf`, `+0` shall be returned. - -If _x_ is `+Inf`, _x_ shall be returned. -If the correct value would cause underflow, and is representable, a range error may occur and the correct value shall be returned. - +* If _x_ is `NaN`, a `NaN` shall be returned. +* If _x_ is `±0`, `1` shall be returned. +* If _x_ is `-Inf`, `+0` shall be returned. +* If _x_ is `+Inf`, _x_ shall be returned. +* If the correct value would cause underflow, and is representable, a range error may occur and the correct value shall +be returned. ## Errors - These functions shall fail if: - * Range Error - The result overflows.
- If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If -the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the overflow floating-point exception shall -be raised. +* Range Error - The result overflows. + If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If +the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the overflow floating-point exception +shall be raised. These functions may fail if: - * Range Error - The result underflows.
+* Range Error - The result underflows. + If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the underflow floating-point exception shall be raised. - - - - - ## Tests Untested @@ -74,6 +68,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fabs.part-impl.md b/libc/functions/f/fabs.part-impl.md index aeac013f..90c65650 100644 --- a/libc/functions/f/fabs.part-impl.md +++ b/libc/functions/f/fabs.part-impl.md @@ -1,42 +1,37 @@ -# Synopsis -`#include `
+# Synopsis -` double fabs(double x);`
+`#include ` -` float fabsf(float x);`
+`double fabs(double x);` -` long double fabsl(long double x);`
+`float fabsf(float x);` + +`long double fabsl(long double x);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description These functions shall compute the absolute value of their argument _x_. - ## Return value - Upon successful completion, these functions shall return the absolute value of _x_. -If -_x_ is `NaN`, a `NaN` shall be returned. - -If _x_ is `±0`, `+0` shall be returned. - -If _x_ is `±Inf`, `+Inf` shall be returned. +* If _x_ is `NaN`, a `NaN` shall be returned. +* If _x_ is `±0`, `+0` shall be returned. +* If _x_ is `±Inf`, `+Inf` shall be returned. ## Errors - No errors are defined. - - - ## Tests Untested @@ -45,6 +40,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fchdir.not-impl.md b/libc/functions/f/fchdir.not-impl.md index 5483b2bb..97a08a4c 100644 --- a/libc/functions/f/fchdir.not-impl.md +++ b/libc/functions/f/fchdir.not-impl.md @@ -1,50 +1,45 @@ -# Synopsis +# Synopsis + `#include ` -` int fchdir(int fildes);` +`int fchdir(int fildes);` ## Status + Declared, not implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 -The `fchdir()` function shall be equivalent to `chdir()` except that the directory that is to be the new current working directory is specified by the file descriptor _fildes_. +## Description -A conforming application can obtain a file descriptor for a file of type directory using `open()`, provided that the file status flags and access modes do not contain `O_WRONLY` or -`O_RDWR`. +The `fchdir()` function shall be equivalent to `chdir()` except that the directory that is to be the new current working +directory is specified by the file descriptor _fildes_. +A conforming application can obtain a file descriptor for a file of type directory using `open()`, provided that the +file status flags and access modes do not contain `O_WRONLY` or `O_RDWR`. ## Return value - Upon successful completion, `fchdir()` shall return 0. Otherwise, it shall return -1 and set `errno` to indicate the error. On failure the current working directory shall remain unchanged. - ## Errors - The `fchdir()` function shall fail if: +* `EACCES` - Search permission is denied for the directory referenced by _fildes_. - * `EACCES` - Search permission is denied for the directory referenced by _fildes_. - - * `EBADF` - The _fildes_ argument is not an open file descriptor. +* `EBADF` - The _fildes_ argument is not an open file descriptor. - * `ENOTDIR` - The open file descriptor _fildes_ does not refer to a directory. +* `ENOTDIR` - The open file descriptor _fildes_ does not refer to a directory. The `fchdir()` may fail if: +* `EINTR` - A signal was caught during the execution of `fchdir()`. - * `EINTR` - A signal was caught during the execution of `fchdir()`. - - * `EIO` - An I/O error occurred while reading from or writing to the file system. - - - - +* `EIO` - An I/O error occurred while reading from or writing to the file system. ## Tests @@ -54,6 +49,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fchown.not-impl.md b/libc/functions/f/fchown.not-impl.md index 20527e56..a5ed7551 100644 --- a/libc/functions/f/fchown.not-impl.md +++ b/libc/functions/f/fchown.not-impl.md @@ -1,52 +1,46 @@ -# Synopsis -`#include ` +# Synopsis -` int fchown(int fildes, uid_t owner, gid_t group);` +`#include ` +`int fchown(int fildes, uid_t owner, gid_t group);` ## Status + Declared, not implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `fchown()` function shall be equivalent to `chown()` except that the file whose _owner_ and _group_ are changed is specified by the file descriptor _fildes_. - ## Return value - Upon successful completion, `fchown()` shall return 0. Otherwise, it shall return -1 and set `errno` to indicate the error. - ## Errors - The `fchown()` function shall fail if: +* `EBADF` - The _fildes_ argument is not an open file descriptor. - * `EBADF` - The _fildes_ argument is not an open file descriptor. - - * `EPERM` - The effective user ID does not match the owner of the file or the process does not have appropriate privileges and -`_POSIX_CHOWN_RESTRICTED` indicates that such privilege is required. +* `EPERM` - The effective user ID does not match the owner of the file or the process does not have appropriate + privileges and `_POSIX_CHOWN_RESTRICTED` indicates that such privilege is required. - * `EROFS` - The file referred to by _fildes_ resides on a read-only file system. +* `EROFS` - The file referred to by _fildes_ resides on a read-only file system. The `fchown()` function may fail if: +* `EINVAL` - The owner or group ID is not a value supported by the implementation. The _fildes_ argument refers to a + pipe or socket or an `fattach()`-ed STREAM and the implementation disallows execution of `fchown()` on a pipe. - * `EINVAL` - The owner or group ID is not a value supported by the implementation. The _fildes_ argument refers to a pipe or socket or an `fattach()`-ed STREAM and the implementation disallows execution of `fchown()` on a pipe. - - * `EIO` - A physical I/O error has occurred. - - * `EINTR` - The `fchown()` function was interrupted by a signal which was caught. - - - +* `EIO` - A physical I/O error has occurred. +* `EINTR` - The `fchown()` function was interrupted by a signal which was caught. ## Tests @@ -56,6 +50,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fclose.part-impl.md b/libc/functions/f/fclose.part-impl.md index eb118e65..70a579e8 100644 --- a/libc/functions/f/fclose.part-impl.md +++ b/libc/functions/f/fclose.part-impl.md @@ -1,76 +1,77 @@ -# Synopsis -`#include `
+# Synopsis -` int fclose(FILE *stream);`
+`#include ` + +`int fclose(FILE *stream);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `fclose()` function shall cause the stream pointed to by _stream_ to be flushed and the associated file to be -closed. Any unwritten buffered data for the stream shall be written to the file. Any unread buffered data shall be discarded. +closed. Any unwritten buffered data for the stream shall be written to the file. Any unread buffered data shall be +discarded. + +Whether or not the call succeeds, the _stream_ shall be disassociated from the file and any buffer set by the `setbuf()` +or `setvbuf()` function shall be disassociated from the stream. If the associated buffer was automatically allocated, +it shall be deallocated. -Whether or not the call succeeds, the _stream_ shall be disassociated from the file and any buffer set by the `setbuf()` or `setvbuf()` function shall be -disassociated from the stream. If the associated buffer was automatically allocated, it shall be deallocated. -If -the file is not already at `EOF`, and the file is one capable of seeking, the file offset of the underlying open file description -shall be set to the file position of the _stream_ if the _stream_ is the active handle to the underlying file description. +If the file is not already at `EOF`, and the file is one capable of seeking, the file offset of the underlying open file +description shall be set to the file position of the _stream_ if the _stream_ is the active handle to the underlying +file description. The `fclose()` function shall mark for update the last data modification and last file status change timestamps of the -underlying file, if the _stream_ was writable, and if buffered data remains that has not yet been written to the file. The -`fclose()` function shall perform the equivalent of a `close()` on the file -descriptor that is associated with the stream pointed to by _stream_. -After the call to `fclose()`, any use of stream results in undefined behavior. +underlying file, if the _stream_ was writable, and if buffered data remains that has not yet been written to the file. +The `fclose()` function shall perform the equivalent of a `close()` on the file descriptor that is associated with the +stream pointed to by _stream_. +After the call to `fclose()`, any use of stream results in undefined behavior. ## Return value - Upon successful completion, `fclose()` shall return `0`; otherwise, it shall return `EOF`  and set -`errno` to indicate the error. - +`errno` to indicate the error. ## Errors - The `fclose()` function shall fail if: +* `EAGAIN` - The `O_NONBLOCK` flag is set for the file descriptor underlying _stream_ and the thread would be delayed +in the write operation. - * `EAGAIN` - The `O_NONBLOCK` flag is set for the file descriptor underlying _stream_ and the thread would be delayed in the write operation. - +* `EBADF` - The file descriptor underlying _stream_ is not valid. - * `EBADF` - The file descriptor underlying _stream_ is not valid. +* `EFBIG` - An attempt was made to write a file that exceeds the maximum file size. - * `EFBIG` - An attempt was made to write a file that exceeds the maximum file size. +* `EFBIG` - An attempt was made to write a file that exceeds the file size limit of the process. - * `EFBIG` - An attempt was made to write a file that exceeds the file size limit of the process. +* `EFBIG` - The file is a regular file and an attempt was made to write at or beyond the offset maximum associated with +the corresponding _stream_. - * `EFBIG` - The file is a regular file and an attempt was made to write at or beyond the offset maximum associated with the corresponding -_stream_. +* `EINTR` - The `fclose()` function was interrupted by a signal. - * `EINTR` - The `fclose()` function was interrupted by a signal. +* `EIO` - The process is a member of a background process group attempting to write to its controlling terminal, +`TOSTOP` is set, the calling thread is not blocking `SIGTTOU`, the process is not ignoring `SIGTTOU`, and the process +group of the process is orphaned. This error may also be returned under implementation-defined conditions. - * `EIO` - The process is a member of a background process group attempting to write to its controlling terminal, `TOSTOP` is set, the calling -thread is not blocking `SIGTTOU`, the process is not ignoring `SIGTTOU`, and the process group of the process is orphaned. This error -may also be returned under implementation-defined conditions. +* `ENOMEM` - The underlying _stream_ was created by `open_memstream()` or `open_wmemstream()` and insufficient memory +is available. - * `ENOMEM` - The underlying _stream_ was created by `open_memstream()` or `open_wmemstream()` and insufficient memory is available. +* `ENOSPC` - There was no free space remaining on the device containing the file or in the buffer used by the +`fmemopen()` function. - * `ENOSPC` - There was no free space remaining on the device containing the file or in the buffer used by the `fmemopen()` function. - - * `EPIPE` - An attempt is made to write to a pipe or FIFO that is not open for reading by any process. A `SIGPIPE` signal shall also be sent to the -thread. +* `EPIPE` - An attempt is made to write to a pipe or FIFO that is not open for reading by any process. A `SIGPIPE` +signal shall also be sent to the thread. The `fclose()` function may fail if: - * `ENXIO` - A request was made of a nonexistent device, or the request was outside the capabilities of the device. - - - - +* `ENXIO` - A request was made of a nonexistent device, or the request was outside the capabilities of the device. ## Tests @@ -80,6 +81,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fcntl.part-impl.md b/libc/functions/f/fcntl.part-impl.md index ffd4f83f..7e2e9fbd 100644 --- a/libc/functions/f/fcntl.part-impl.md +++ b/libc/functions/f/fcntl.part-impl.md @@ -1,14 +1,18 @@ -# Synopsis +# Synopsis + `#include `
-` int fcntl(int fildes, int cmd, ...);`
+`int fcntl(int fildes, int cmd, ...);`
## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `fcntl()` function shall perform the operations described below on open files. The _fildes_ argument is a file descriptor. @@ -16,144 +20,144 @@ descriptor. The available values for _cmd_ are defined in `` and are as follows: - * `F_DUPFD` -Return a new file descriptor which shall be allocated as described in File -Descriptor Allocation, except that it shall be the lowest numbered available file descriptor greater than or equal to the -third argument, arg, taken as an integer of type int. The new file descriptor shall refer to the same open file -description as the original file descriptor, and shall share any locks. The `FD_CLOEXEC` flag associated with the new file descriptor +* `F_DUPFD` Return a new file descriptor which shall be allocated as described in File. Descriptor Allocation, +except that it shall be the lowest numbered available file descriptor greater than or equal to the third argument, +arg, taken as an integer of type int. The new file descriptor shall refer to the same open file description as the +original file descriptor, and shall share any locks. The `FD_CLOEXEC` flag associated with the new file descriptor shall be cleared to keep the file open across calls to one of the exec functions. - * `F_DUPFD_CLOEXEC` - Like `F_DUPFD,` but the `FD_CLOEXEC` flag associated with the new file descriptor shall be set. - - * `F_GETFD ` - Get the file descriptor flags defined in `` that are associated with -the file descriptor _fildes_. File descriptor flags are associated with a single file descriptor and do not affect other file -descriptors that refer to the same file. - - * `F_SETFD ` - Set the file descriptor flags defined in ``, that are associated -with _fildes_, to the third argument, arg, taken as type int. If the `FD_CLOEXEC` flag in the third argument is `0`, -the file descriptor shall remain open across the exec functions; otherwise, the file -descriptor shall be closed upon successful execution of one of the exec functions. - - * `F_GETFL ` - Get the file status flags and file access modes, defined in ``, for -the file description associated with _fildes_. The file access modes can be extracted from the return value using the mask -`O_ACCMODE,` which is defined in ``. File status flags and file access -modes are associated with the file description and do not affect other file descriptors that refer to the same file with different -open file descriptions. The flags returned may include non-standard file status flags which the application did not set, provided -that these additional flags do not alter the behavior of a conforming application. - - * `F_SETFL ` - Set the file status flags, defined in ``, for the file description -associated with _fildes_ from the corresponding bits in the third argument, arg, taken as type int. Bits -corresponding to the file access mode and the file creation flags, as defined in ``, that are set in arg shall be ignored. If any bits in arg other -than those mentioned here are changed by the application, the result is unspecified. If _fildes_ does not support non-blocking -operations, it is unspecified whether the `O_NONBLOCK` flag will be ignored. - - * `F_GETOWN ` - If _fildes_ refers to a socket, get the process ID or process group ID specified to receive `SIGURG` signals when -out-of-band data is available. Positive values shall indicate a process ID; negative values, other than `-1`, shall indicate a -process group ID; the value zero shall indicate that no `SIGURG` signals are to be sent. If _fildes_ does not refer to a socket, -the results are unspecified. - - * `F_SETOWN ` - If _fildes_ refers to a socket, set the process ID or process group ID specified to receive `SIGURG` signals when -out-of-band data is available, using the value of the third argument, arg, taken as type int. Positive values shall -indicate a process ID; negative values, other than `-1`, shall indicate a process group ID. The value zero shall indicate that no -`SIGURG` signals are to be sent. Each time a `SIGURG` signal is sent to the specified process or process group, permission checks equivalent to those performed by `kill()` shall be performed, as if `kill()` were called by a process with the same real user ID, effective user ID, and privileges that the process calling `fcntl()` has at the time of the call. If the `kill()` call would fail, no signal shall be sent. These permission checks may also be performed by the `fcntl()` call. If the process -specified by arg later terminates, or the process group specified by arg later becomes empty, while still being -specified to receive `SIGURG` signals when out-of-band data is available from _fildes_, then no signals shall be sent to any -subsequently created process that has the same process ID or process group ID, regardless of permission. It is unspecified whether -this is achieved by the equivalent of a `fcntl(_fildes_, F_SETOWN, 0)` call at the time the process terminates or is -waited for or the process group becomes empty, or by other means. If _fildes_ does not refer to a socket, the results are -unspecified. +* `F_DUPFD_CLOEXEC` Like `F_DUPFD,` but the `FD_CLOEXEC` flag associated with the new file descriptor shall be set. + +* `F_GETFD` - Get the file descriptor flags defined in `` that are associated with the file descriptor +_fildes_. File descriptor flags are associated with a single file descriptor and do not affect other file descriptors +that refer to the same file. + +* `F_SETFD` - Set the file descriptor flags defined in ``, that are associated with _fildes_, to the third +argument, arg, taken as type int. If the `FD_CLOEXEC` flag in the third argument is `0`, the file descriptor shall +remain open across the exec functions; otherwise, the file descriptor shall be closed upon successful execution of +one of the exec functions. + +* `F_GETFL` - Get the file status flags and file access modes, defined in ``, for the file description +associated with _fildes_. The file access modes can be extracted from the return value using the mask `O_ACCMODE,` +which is defined in ``. File status flags and file access modes are associated with the file description +and do not affect other file descriptors that refer to the same file with different open file descriptions. The flags +returned may include non-standard file status flags which the application did not set, provided that these additional +flags do not alter the behavior of a conforming application. + +* `F_SETFL` - Set the file status flags, defined in ``, for the file description associated with _fildes_ +from the corresponding bits in the third argument, arg, taken as type int. Bits corresponding to the file access mode +and the file creation flags, as defined in ``, that are set in arg shall be ignored. If any bits in arg other +than those mentioned here are changed by the application, the result is unspecified. If _fildes_ does not support +non-blocking operations, it is unspecified whether the `O_NONBLOCK` flag will be ignored. + +* `F_GETOWN` - If _fildes_ refers to a socket, get the process ID or process group ID specified to receive `SIGURG` +signals when out-of-band data is available. Positive values shall indicate a process ID; negative values, other than +`-1`, shall indicate a process group ID; the value zero shall indicate that no `SIGURG` signals are to be sent. If +_fildes_ does not refer to a socket, the results are unspecified. + +* `F_SETOWN` - If _fildes_ refers to a socket, set the process ID or process group ID specified to receive `SIGURG` +signals when out-of-band data is available, using the value of the third argument, arg, taken as type int. Positive +values shall indicate a process ID; negative values, other than `-1`, shall indicate a process group ID. The value +zero shall indicate that no `SIGURG` signals are to be sent. Each time a `SIGURG` signal is sent to the specified +process or process group, permission checks equivalent to those performed by `kill()` shall be performed, as if `kill()` +were called by a process with the same real user ID, effective user ID, and privileges that the process calling +`fcntl()` has at the time of the call. If the `kill()` call would fail, no signal shall be sent. These permission checks +may also be performed by the `fcntl()` call. If the processspecified by arg later terminates, or the process group +specified by arg later becomes empty, while still being specified to receive `SIGURG` signals when out-of-band data is +available from _fildes_, then no signals shall be sent to any subsequently created process that has the same process ID +or process group ID, regardless of permission. It is unspecified whether this is achieved by the equivalent of a +`fcntl(_fildes_, F_SETOWN, 0)` call at the time the process terminates or is waited for or the process group becomes +empty, or by other means. If _fildes_ does not refer to a socket, the results are unspecified. The following values for _cmd_ are available for advisory record locking. Record locking shall be supported for regular files, and may be supported for other files. - * `F_GETLK ` - Get any lock which blocks the lock description pointed to by the third argument, arg, taken as a pointer to type -struct flock, defined in ``. The information retrieved shall -overwrite the information passed to `fcntl()` in the structure flock. If no lock is found that would prevent this lock -from being created, then the structure shall be left unchanged except for the lock type which shall be set to `F_UNLCK`. +* `F_GETLK` - Get any lock which blocks the lock description pointed to by the third argument, arg, taken as a pointer +to type struct flock, defined in ``. The information retrieved shall overwrite the information passed to +`fcntl()` in the structure flock. If no lock is found that would prevent this lock from being created, then the +structure shall be left unchanged except for the lock type which shall be set to `F_UNLCK`. - * `F_SETLK ` - Set or clear a file segment lock according to the lock description pointed to by the third argument, _arg_, taken as a -pointer to type struct flock, defined in ``. `F_SETLK` can -establish shared (or read) locks `(F_RDLCK)` or exclusive (or write) locks `(F_WRLCK),` as well as to remove either type of lock -`(F_UNLCK)`. `F_RDLCK,` `F_WRLCK,` and `F_UNLCK` are defined in ``. If a shared -or exclusive lock cannot be set, `fcntl()` shall return immediately with a return value of `-1`. +* `F_SETLK` - Set or clear a file segment lock according to the lock description pointed to by the third argument, +_arg_, taken as a pointer to type struct flock, defined in ``. `F_SETLK` can establish shared (or read) locks +`(F_RDLCK)` or exclusive (or write) locks `(F_WRLCK),` as well as to remove either type of lock `(F_UNLCK)`. `F_RDLCK,` +`F_WRLCK,` and `F_UNLCK` are defined in ``. If a shared or exclusive lock cannot be set, `fcntl()` shall return +immediately with a return value of `-1`. - * `F_SETLKW ` - This command shall be equivalent to `F_SETLK` except that if a shared or exclusive lock is blocked by other locks, the thread -shall wait until the request can be satisfied. If a signal that is to be caught is received while `fcntl()` is waiting for a -region, `fcntl()` shall be interrupted. Upon return from the signal handler, `fcntl()` shall return `-1` with `errno` -set to `EINTR`, and the lock operation shall not be done. +* `F_SETLKW` - This command shall be equivalent to `F_SETLK` except that if a shared or exclusive lock is blocked by +other locks, the thread shall wait until the request can be satisfied. If a signal that is to be caught is received +while `fcntl()` is waiting for a region, `fcntl()` shall be interrupted. Upon return from the signal handler, `fcntl()` +shall return `-1` with `errno` set to `EINTR`, and the lock operation shall not be done. Additional implementation-defined values for _cmd_ may be defined in ``. Their names shall start with `F_`. -When a shared lock is set on a segment of a file, other processes shall be able to set shared locks on that segment or a portion -of it. A shared lock prevents any other process from setting an exclusive lock on any portion of the protected area. A request for -a shared lock shall fail if the file descriptor was not opened with read access. +When a shared lock is set on a segment of a file, other processes shall be able to set shared locks on that segment +or a portion of it. A shared lock prevents any other process from setting an exclusive lock on any portion of the +protected area. A request for a shared lock shall fail if the file descriptor was not opened with read access. An exclusive lock shall prevent any other process from setting a shared lock or an exclusive lock on any portion of the protected area. A request for an exclusive lock shall fail if the file descriptor was not opened with write access. -The structure flock describes the type `l_type`, starting offset `l_whence`, relative offset -`l_start`, size `l_len` and process ID `l_pid` of the segment of the file to be affected. - -The value of `l_whence` is `SEEK_SET,` `SEEK_CUR,` or `SEEK_END,` to indicate that the relative offset `l_start` bytes shall -be measured from the start of the file, current position, or end of the file, respectively. The value of `l_len` is the number -of consecutive bytes to be locked. The value of `l_len` may be negative (where the definition of `off_t` permits negative -values of `l_len)`. The `l_pid` field is only used with `F_GETLK` to return the process ID of the process holding a -blocking lock. After a successful `F_GETLK` request, when a blocking lock is found, the values returned in the flock structure -shall be as follows: - - * `l_type` - type of blocking lock found. - * `l_whence ` - `SEEK_SET`. - * `l_start ` - Start of the blocking lock. - * `l_len ` - Length of the blocking lock. - * `l_pid ` - Process ID of the process that holds the blocking lock. - -If the command is `F_SETLKW` and the process must wait for another process to release a lock, then the range of bytes to be locked -shall be determined before the `fcntl()` function blocks. If the file size or file descriptor seek offset change while `fcntl()` is blocked, this shall not affect the range of bytes locked. - -If `l_len` is positive, the area affected shall start at `l_start` and end at `(l_start+l_len-1)`. If -`l_len` is negative, the area affected shall start at `(l_start+l_len)` and end at `(l_start-1)`. Locks may -start and extend beyond the current end of a file, but shall not extend before the beginning of the file. A lock shall be set to -extend to the largest possible value of the file offset for that file by setting `l_len` to `0`. If such a lock also has +The structure flock describes the type `l_type`, starting offset `l_whence`, relative offset `l_start`, size `l_len` +and process ID `l_pid` of the segment of the file to be affected. + +The value of `l_whence` is `SEEK_SET,` `SEEK_CUR,` or `SEEK_END,` to indicate that the relative offset `l_start` bytes +shall be measured from the start of the file, current position, or end of the file, respectively. The value of `l_len` +is the number of consecutive bytes to be locked. The value of `l_len` may be negative where the definition of `off_t` +permits negative values of `l_len)`. The `l_pid` field is only used with `F_GETLK` to return the process ID of the +process holding a blocking lock. After a successful `F_GETLK` request, when a blocking lock is found, the values +returned in the flock structure shall be as follows: + +* `l_type` - type of blocking lock found. +* `l_whence` - `SEEK_SET`. +* `l_start` - Start of the blocking lock. +* `l_len` - Length of the blocking lock. +* `l_pid` - Process ID of the process that holds the blocking lock. + +If the command is `F_SETLKW` and the process must wait for another process to release a lock, then the range of bytes +to be locked shall be determined before the `fcntl()` function blocks. If the file size or file descriptor seek offset +change while `fcntl()` is blocked, this shall not affect the range of bytes locked. + +If `l_len` is positive, the area affected shall start at `l_start` and end at `(l_start+l_len-1)`. If `l_len` is +negative, the area affected shall start at `(l_start+l_len)` and end at `(l_start-1)`. Locks may start and extend +beyond the current end of a file, but shall not extend before the beginning of the file. A lock shall be set to extend +to the largest possible value of the file offset for that file by setting `l_len` to `0`. If such a lock also has `l_start` set to `0` and `l_whence` is set to `SEEK_SET,` the whole file shall be locked. -There shall be at most one type of lock set for each byte in the file. Before a successful return from an `F_SETLK` or an `F_SETLKW` -request when the calling process has previously existing locks on bytes in the region specified by the request, the previous lock -type for each byte in the specified region shall be replaced by the new lock type. As specified above under the descriptions of -shared locks and exclusive locks, an `F_SETLK` or an `F_SETLKW` request (respectively) shall fail or block when another process has -existing locks on bytes in the specified region and the type of any of those locks conflicts with the type specified in the -request. - -All locks associated with a file for a given process shall be removed when a file descriptor for that file is closed by that -process or the process holding that file descriptor terminates. Locks are not inherited by a child process. +There shall be at most one type of lock set for each byte in the file. Before a successful return from an `F_SETLK` or +an `F_SETLKW` request when the calling process has previously existing locks on bytes in the region specified by the +request, the previous lock type for each byte in the specified region shall be replaced by the new lock type. +As specified above under the descriptions of shared locks and exclusive locks, an `F_SETLK` or an `F_SETLKW` request +(respectively) shall fail or block when another process has existing locks on bytes in the specified region and the +type of any of those locks conflicts with the type specified in the request. -A potential for deadlock occurs if a process controlling a locked region is put to sleep by attempting to lock the locked region -of another process. If the system detects that sleeping until a locked region is unlocked would cause a deadlock, `fcntl()` -shall fail with an `EDEADLK` error. +All locks associated with a file for a given process shall be removed when a file descriptor for that file is closed by +that process or the process holding that file descriptor terminates. Locks are not inherited by a child process. -An unlock `(F_UNLCK)` request in which `l_len` is non-zero and the offset of the last byte of the requested segment is the -maximum value for an object of type `off_t,` when the process has an existing lock in which `l_len` is `0` and which -includes the last byte of the requested segment, shall be treated as a request to unlock from the start of the requested segment -with an `l_len` equal to `0`. Otherwise, an unlock `(F_UNLCK)` request shall attempt to unlock only the requested segment. +A potential for deadlock occurs if a process controlling a locked region is put to sleep by attempting to lock the +locked region of another process. If the system detects that sleeping until a locked region is unlocked would cause a +deadlock, `fcntl()` shall fail with an `EDEADLK` error. -When the file descriptor _fildes_ refers to a shared memory object, the behavior of `fcntl()` shall be the same as for a -regular file except the effect of the following values for the argument _cmd_ shall be unspecified: `F_SETFL,` `F_GETLK,` `F_SETLK,` -and `F_SETLKW`. +An unlock `(F_UNLCK)` request in which `l_len` is non-zero and the offset of the last byte of the requested segment is +the maximum value for an object of type `off_t,` when the process has an existing lock in which `l_len` is `0` and which +includes the last byte of the requested segment, shall be treated as a request to unlock from the start of the requested +segment with an `l_len` equal to `0`. Otherwise, an unlock `(F_UNLCK)` request shall attempt to unlock only the +requested segment. -If _fildes_ refers to a typed memory object, the result of the `fcntl()` function is unspecified. +When the file descriptor _fildes_ refers to a shared memory object, the behavior of `fcntl()` shall be the same as for +a regular file except the effect of the following values for the argument _cmd_ shall be unspecified: `F_SETFL,` +`F_GETLK,` `F_SETLK,` and `F_SETLKW`. +If _fildes_ refers to a typed memory object, the result of the `fcntl()` function is unspecified. ## Return value - Upon successful completion, the value returned shall depend on _cmd_ as follows: * `F_DUPFD` - A new file descriptor. * `F_DUPFD_CLOEXEC` - A new file descriptor. -* `F_GETFD` - Value of flags defined in ``. The return value shall not be -negative. +* `F_GETFD` - Value of flags defined in ``. The return value shall not be negative. * `F_SETFD` - Value other than `-1`. @@ -173,57 +177,51 @@ negative. Otherwise, `-1` shall be returned and `errno` set to indicate the error. - ## Errors - The `fcntl()` function shall fail if: `EACCES` or `EAGAIN` -The _cmd_ argument is `F_SETLK`. The type of lock (`l_type`) is a shared (`F_RDLCK`) or exclusive (`F_WRLCK`) lock and the -segment of a file to be locked is already exclusive-locked by another process, or the type is an exclusive lock and some portion of -the segment of a file to be locked is already shared-locked or exclusive-locked by another process. +The _cmd_ argument is `F_SETLK`. The type of lock (`l_type`) is a shared (`F_RDLCK`) or exclusive (`F_WRLCK`) lock and +the segment of a file to be locked is already exclusive-locked by another process, or the type is an exclusive lock and +some portion of the segment of a file to be locked is already shared-locked or exclusive-locked by another process. - * `EBADF` - The _fildes_ argument is not a valid open file descriptor, or the argument _cmd_ is `F_SETLK` or `F_SETLKW`, the type of -lock, `l_type`, is a shared lock (`F_RDLCK`), and _fildes_ is not a valid file descriptor open for reading, or the type of -lock, `l_type`, is an exclusive lock (`F_WRLCK`), and _fildes_ is not a valid file descriptor open for writing. +* `EBADF` - The _fildes_ argument is not a valid open file descriptor, or the argument _cmd_ is `F_SETLK` or `F_SETLKW`, +the type of lock, `l_type`, is a shared lock (`F_RDLCK`), and _fildes_ is not a valid file descriptor open for reading, +or the type of lock, `l_type`, is an exclusive lock (`F_WRLCK`), and _fildes_ is not a valid file descriptor open for +writing. - * `EINTR` - The _cmd_ argument is `F_SETLKW` and the function was interrupted by a signal. +* `EINTR` - The _cmd_ argument is `F_SETLKW` and the function was interrupted by a signal. - * `EINVAL` - The _cmd_ argument is invalid, or the _cmd_ argument is `F_DUPFD` or `F_DUPFD_CLOEXEC` and arg is negative or -greater than or equal to `OPEN_MAX`, or the _cmd_ argument is `F_GETLK`, `F_SETLK`, or `F_SETLKW` and the data pointed to by -arg is not valid, or _fildes_ refers to a file that does not support locking. +* `EINVAL` - The _cmd_ argument is invalid, or the _cmd_ argument is `F_DUPFD` or `F_DUPFD_CLOEXEC` and arg is negative +or greater than or equal to `OPEN_MAX`, or the _cmd_ argument is `F_GETLK`, `F_SETLK`, or `F_SETLKW` and the data +pointed to by arg is not valid, or _fildes_ refers to a file that does not support locking. - * `EMFILE` - The argument _cmd_ is `F_DUPFD` or `F_DUPFD_CLOEXEC` and all file descriptors available to the process are currently open, or -no file descriptors greater than or equal to arg are available. +* `EMFILE` - The argument _cmd_ is `F_DUPFD` or `F_DUPFD_CLOEXEC` and all file descriptors available to the process are +currently open, or no file descriptors greater than or equal to arg are available. - * `ENOLCK` - The argument _cmd_ is `F_SETLK` or `F_SETLKW` and satisfying the lock or unlock request would result in the number of locked -regions in the system exceeding a system-imposed limit. +* `ENOLCK` - The argument _cmd_ is `F_SETLK` or `F_SETLKW` and satisfying the lock or unlock request would result in the +number of locked regions in the system exceeding a system-imposed limit. - * `EOVERFLOW` - One of the values to be returned cannot be represented correctly. +* `EOVERFLOW` - One of the values to be returned cannot be represented correctly. - * `EOVERFLOW` - The _cmd_ argument is `F_GETLK`, `F_SETLK`, or `F_SETLKW` and the smallest or, if `l_len` is non-zero, the largest offset -of any byte in the requested segment cannot be represented correctly in an object of type off_t. +* `EOVERFLOW` - The _cmd_ argument is `F_GETLK`, `F_SETLK`, or `F_SETLKW` and the smallest or, if `l_len` is non-zero, +the largest offset of any byte in the requested segment cannot be represented correctly in an object of type off_t. - * `ESRCH` - The _cmd_ argument is `F_SETOWN` and no process or process group can be found corresponding to that specified by -_arg_. - - -The `fcntl()` function may fail if: - - - * `EDEADLK` - The _cmd_ argument is `F_SETLKW`, the lock is blocked by a lock from another process, and putting the calling process to -sleep to wait for that lock to become free would cause a deadlock. - - * `EINVAL` - The _cmd_ argument is `F_SETOWN` and the value of the argument is not valid as a process or process group identifier. - - * `EPERM` - The _cmd_ argument is `F_SETOWN` and the calling process does not have permission to send a `SIGURG` signal to any process +* `ESRCH` - The _cmd_ argument is `F_SETOWN` and no process or process group can be found corresponding to that specified by _arg_. +The `fcntl()` function may fail if: +* `EDEADLK` - The _cmd_ argument is `F_SETLKW`, the lock is blocked by a lock from another process, and putting the +calling process to sleep to wait for that lock to become free would cause a deadlock. +* `EINVAL` - The _cmd_ argument is `F_SETOWN` and the value of the argument is not valid as a process or process group +identifier. +* `EPERM` - The _cmd_ argument is `F_SETOWN` and the calling process does not have permission to send a `SIGURG` signal +to any process specified by _arg_. ## Tests @@ -233,6 +231,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fdopen.part-impl.md b/libc/functions/f/fdopen.part-impl.md index 6df6b976..defd762f 100644 --- a/libc/functions/f/fdopen.part-impl.md +++ b/libc/functions/f/fdopen.part-impl.md @@ -1,14 +1,18 @@ -# Synopsis -`#include `
+# Synopsis -` FILE *fdopen(int fildes, const char *mode); `
+`#include ` + +` FILE *fdopen(int fildes, const char *mode); ` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `fdopen()` function shall associate a stream with a file descriptor. @@ -21,51 +25,44 @@ The _mode_ argument is a character string having one of the following values: * `w+` or `wb+` or `w+b` - Open a file for update (reading and writing). * `a+` or `ab+` or `a+b` - Open a file for update (reading and writing) at end-of-file. -The meaning of these flags is exactly as specified in `fopen()`, except that modes -beginning with w shall not cause truncation of the file. +The meaning of these flags is exactly as specified in `fopen()`, except that modes beginning with w shall not cause +truncation of the file. Additional values for the _mode_ argument may be supported by an implementation. -The application shall ensure that the mode of the stream as expressed by the _mode_ argument is allowed by the file access -mode of the open file description to which _fildes_ refers. The file position indicator associated with the new stream is set -to the position indicated by the file offset associated with the file descriptor. +The application shall ensure that the mode of the stream as expressed by the _mode_ argument is allowed by the file +access mode of the open file description to which _fildes_ refers. The file position indicator associated with the new +stream is set to the position indicated by the file offset associated with the file descriptor. The error and end-of-file indicators for the stream shall be cleared. The `fdopen()` function may cause the last data access timestamp of the underlying file to be marked for update. -If _fildes_ refers to a shared memory object, the result of the `fdopen()` function is unspecified. +If _fildes_ refers to a shared memory object, the result of the `fdopen()` function is unspecified. -If _fildes_ refers to a typed memory object, the result of the `fdopen()` function is unspecified. +If _fildes_ refers to a typed memory object, the result of the `fdopen()` function is unspecified. The `fdopen()` function shall preserve the offset maximum previously set for the open file description corresponding to _fildes_. - ## Return value -Upon successful completion, `fdopen()` shall return a pointer to a stream, otherwise, a `null` pointer shall be returned and `errno` set to indicate the error. +Upon successful completion, `fdopen()` shall return a pointer to a stream, otherwise, a `null` pointer shall be returned +and `errno` set to indicate the error. ## Errors - The `fdopen()` function shall fail if: - - * `EMFILE` - `STREAM_MAX` streams are currently open in the calling process. +* `EMFILE` - `STREAM_MAX` streams are currently open in the calling process. The `fdopen()` function may fail if: +* `EBADF` - The _fildes_ argument is not a valid file descriptor. - * `EBADF` - The _fildes_ argument is not a valid file descriptor. - - * `EINVAL` - The _mode_ argument is not a valid mode. - - * `EMFILE` - `FOPEN_MAX` streams are currently open in the calling process. - - * `ENOMEM` - Insufficient space to allocate a buffer. - - +* `EINVAL` - The _mode_ argument is not a valid mode. +* `EMFILE` - `FOPEN_MAX` streams are currently open in the calling process. +* `ENOMEM` - Insufficient space to allocate a buffer. ## Tests @@ -75,6 +72,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fdopendir.tb-impl.md b/libc/functions/f/fdopendir.tb-impl.md index a4c21c9f..3244eade 100644 --- a/libc/functions/f/fdopendir.tb-impl.md +++ b/libc/functions/f/fdopendir.tb-impl.md @@ -1,4 +1,4 @@ -###Synopsis +# Synopsis `#include ` @@ -6,45 +6,53 @@ `DIR *opendir(const char *dirname);` -###Description +## Description The functions open the directory associated with a file descriptor or a name. Arguments: -fd - the file descriptor. -dirname - the name of the directory to open. +_fd_ - the file descriptor. +_dirname_ - the name of the directory to open. -Upon successful return from `fdopendir()`, the file descriptor is under the control of the system, and if any attempt is made to close the file descriptor, or to modify the state of the associated description, other than by means of `closedir()`, `readdir()`, `readdir_r()`, `rewinddir()`, or `seekdir()`, the behavior is undefined. Upon calling `closedir()` the file descriptor is closed. +Upon successful return from `fdopendir()`, the file descriptor is under the control of the system, and if any attempt is +made to close the file descriptor, or to modify the state of the associated description, other than by means of +`closedir()`, `readdir()`, `readdir_r()`, `rewinddir()`, or `seekdir()`, the behavior is undefined. Upon calling +`closedir()` the file descriptor is closed. The `FD_CLOEXEC` flag is set on the file descriptor by a successful call to `fdopendir()`. -The `opendir()` function opens a directory stream corresponding to the directory named by the dirname argument. The directory stream is positioned at the first entry. +The `opendir()` function opens a directory stream corresponding to the directory named by the _dirname_ argument. The +directory stream is positioned at the first entry. -###Return value +## Return value -Upon successful completion, `fdopendir()` and `opendir()` return a pointer to an object of type `DIR`. Otherwise, these functions return a null pointer and set `errno` to indicate the error. +Upon successful completion, `fdopendir()` and `opendir()` return a pointer to an object of type `DIR`. Otherwise, these +functions return a null pointer and set `errno` to indicate the error. -###Errors +### Errors For `fdopendir()`: - -[`EBADF`] The fd argument is not a valid file descriptor open for reading. -[`ENOTDIR`] The descriptor fd is not associated with a directory. + +[`EBADF`] The _fd_ argument is not a valid file descriptor open for reading. +[`ENOTDIR`] The descriptor _fd_ is not associated with a directory. For the `opendir()` function: -[`EACCES`] Search permission is denied for the component of the path prefix of dirname or read permission is denied for dirname. -[`ELOOP`] A loop exists in symbolic links encountered during resolution of the dirname argument. +[`EACCES`] Search permission is denied for the component of the path prefix of _dirname_ or read permission is denied for +_dirname_. +[`ELOOP`] A loop exists in symbolic links encountered during resolution of the _dirname_ argument. [`ENAMETOOLONG`] The length of a component of a pathname is longer than {`NAME_MAX`}. -[`ENOENT`] A component of dirname does not name an existing directory or dirname is an empty string. -[`ENOTDIR`] A component of dirname names an existing file that is neither a directory nor a symbolic link to a directory. -[`ELOOP`] More than {`SYMLOOP_MAX`} symbolic links were encountered during resolution of the dirname argument. +[`ENOENT`] A component of _dirname_ does not name an existing directory or _dirname_ is an empty string. +[`ENOTDIR`] A component of _dirname_ names an existing file that is neither a directory nor a symbolic link to a +directory. +[`ELOOP`] More than {`SYMLOOP_MAX`} symbolic links were encountered during resolution of the _dirname_ argument. [`EMFILE`] All file descriptors available to the process are currently open. -[`ENAMETOOLONG`] The length of a pathname exceeds {`PATH_MAX`}, or pathname resolution of a symbolic link produced an intermediate result with a length that exceeds {`PATH_MAX`}. -[`ENFILE`] Too many files are currently open in the system. - -###Implementation tasks +[`ENAMETOOLONG`] The length of a pathname exceeds {`PATH_MAX`}, or pathname resolution of a symbolic link produced an +intermediate result with a length that exceeds {`PATH_MAX`}. +[`ENFILE`] Too many files are currently open in the system. + +### Implementation tasks - * Implement `fdopendir()` function - * Implement error detection as described above. \ No newline at end of file +* Implement `fdopendir()` function +* Implement error detection as described above. diff --git a/libc/functions/f/fegetround.tb-impl.md b/libc/functions/f/fegetround.tb-impl.md index 3edfb390..f96916e0 100644 --- a/libc/functions/f/fegetround.tb-impl.md +++ b/libc/functions/f/fegetround.tb-impl.md @@ -1,4 +1,4 @@ -###Synopsis +# Synopsis `#include ` @@ -6,34 +6,39 @@ `int fesetround(int round);` -###Description +## Description `fegetround()`, `fesetround()` - get and set current rounding direction. Arguments: -round - the rounding direction to be set. +_round_ - the rounding direction to be set. The `fegetround()` function gets the current rounding direction. -The `fesetround()` function establishes the rounding direction (in the program's floating-point environment) represented by its argument round. If the argument is not equal to the value of a rounding direction macro, the rounding direction is not changed. Recognized values of the argument are given by macros in the following list, defined in `fenv.h` as integer constants: +The `fesetround()` function establishes the rounding direction (in the program's floating-point environment) represented +by its argument _round_. If the argument is not equal to the value of a rounding direction macro, the +rounding direction is not changed. Recognized values of the argument are given by macros in the following list, +defined in `fenv.h` as integer constants: `FE_DOWNWARD` Round down to the next lower integer. `FE_UPWARD` Round up to the next greater integer. `FE_TONEAREST` Round up or down toward whichever integer is nearest. `FE_TOWARDZERO` Round positive values downward and negative values upward. -###Return value +## Return value -The `fegetround()` function returns the value of the rounding direction macro representing the current rounding direction or `-1` if there is no such rounding direction macro or the current rounding direction is not determinable. +The `fegetround()` function returns the value of the rounding direction macro representing the current rounding +direction or `-1` if there is no such rounding direction macro or the current rounding direction is not determinable. -The `fesetround()` function returns a zero value if and only if the requested rounding direction was established, otherwise it returns `-1`. +The `fesetround()` function returns a zero value if and only if the requested rounding direction was established, +otherwise it returns `-1`. -###Errors +### Errors No errors are defined. -###Implementation tasks +### Implementation tasks - * Implement `fenv.h`. - * Implement `fegetround()`. - * Implement `fesetround()`. \ No newline at end of file +* Implement `fenv.h`. +* Implement `fegetround()`. +* Implement `fesetround()`. diff --git a/libc/functions/f/feof.impl.md b/libc/functions/f/feof.impl.md index cd894351..063852ce 100644 --- a/libc/functions/f/feof.impl.md +++ b/libc/functions/f/feof.impl.md @@ -1,32 +1,31 @@ -# Synopsis -`#include `
+# Synopsis -`int feof(FILE *stream);`
+`#include ` + +`int feof(FILE *stream);` ## Status + Implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `feof()` function shall test the end-of-file indicator for the stream pointed to by _stream_. The `feof()` function shall not change the setting of errno if stream is valid. - ## Return value - The `feof()` function shall return non-zero if and only if the end-of-file indicator is set for stream. - ## Errors - No errors are defined. - ## Tests Tested in [test-libc](https://github.com/phoenix-rtos/phoenix-rtos-tests/tree/master/libc). @@ -35,6 +34,7 @@ Tested in [test-libc](https://github.com/phoenix-rtos/phoenix-rtos-tests/tree/ma None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/ferror.impl.md b/libc/functions/f/ferror.impl.md index e79136f4..95b46473 100644 --- a/libc/functions/f/ferror.impl.md +++ b/libc/functions/f/ferror.impl.md @@ -1,32 +1,31 @@ -# Synopsis -`#include `
+# Synopsis -`int ferror(FILE *stream);`
+`#include ` + +`int ferror(FILE *stream);` ## Status + Implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `ferror()` function shall test the error indicator for the stream pointed to by _stream_. The `ferror()` function shall not change the setting of errno if stream is valid. - ## Return value - The `ferror()` function shall return non-zero if and only if the error indicator is set for stream. - ## Errors - No errors are defined. - ## Tests Tested in [test-libc](https://github.com/phoenix-rtos/phoenix-rtos-tests/tree/master/libc). @@ -35,6 +34,7 @@ Tested in [test-libc](https://github.com/phoenix-rtos/phoenix-rtos-tests/tree/ma None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fexecve.part-impl.md b/libc/functions/f/fexecve.part-impl.md index 917a9bac..9709855c 100644 --- a/libc/functions/f/fexecve.part-impl.md +++ b/libc/functions/f/fexecve.part-impl.md @@ -1,10 +1,11 @@ -###Synopsis +# Synopsis + `#include ` `int execvpe(const char *file, char *const argv[], char *const envp[]);` -###Description +## Description -###Return value +## Return value -###Errors \ No newline at end of file +## Errors diff --git a/libc/functions/f/fflush.part-impl.md b/libc/functions/f/fflush.part-impl.md index 13381cdf..1cfef107 100644 --- a/libc/functions/f/fflush.part-impl.md +++ b/libc/functions/f/fflush.part-impl.md @@ -1,67 +1,71 @@ -# Synopsis -`#include `
+# Synopsis -` int fflush(FILE *stream);`
+`#include ` + +`int fflush(FILE *stream);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description +If _stream_ points to an output stream or an update stream in which the most recent operation was not input, `fflush()` +shall cause any unwritten data for that stream to be written to the file,  and the last data modification and last +file status change timestamps of the underlying file shall be marked for update. -If _stream_ points to an output stream or an update stream in which the most recent operation was not input, -`fflush()` shall cause any unwritten data for that stream to be written to the file,  and the last -data modification and last file status change timestamps of the underlying file shall be marked for update. +For a stream open for reading with an underlying file description, if the file is not already at `EOF`, and the file is +one capable of seeking, the file offset of the underlying open file description shall be set to the file position of +the stream, and any characters pushed back onto the stream by `ungetc()` or `ungetwc()` that have not subsequently been +read from the stream shall be discarded (without further changing the file offset). -For a stream open for reading with an underlying file description, if the file is not already at `EOF`, and the file is one -capable of seeking, the file offset of the underlying open file description shall be set to the file position of the stream, and -any characters pushed back onto the stream by `ungetc()` or `ungetwc()` that have not subsequently been read from the stream shall be discarded (without -further changing the file offset). If _stream_ is a `null` pointer, `fflush()` shall perform this flushing action on all streams for which the behavior is defined above. - ## Return value - -Upon successful completion, `fflush()` shall return `0`. Otherwise, it shall set the error indicator for the stream, return `EOF`, and set `errno` to indicate the error. - +Upon successful completion, `fflush()` shall return `0`. Otherwise, it shall set the error indicator for the stream, +return `EOF`, and set `errno` to indicate the error. ## Errors - The `fflush()` function shall fail if: +* `EAGAIN` - The `O_NONBLOCK` flag is set for the file descriptor underlying _stream_ and the thread would be delayed in +the write operation. - * `EAGAIN` - The `O_NONBLOCK` flag is set for the file descriptor underlying _stream_ and the thread would be delayed in the write operation. +* `EBADF` - The file descriptor underlying _stream_ is not valid. +* `EFBIG` - An attempt was made to write a file that exceeds the maximum file size. - * `EBADF` - The file descriptor underlying _stream_ is not valid. +* `EFBIG` - An attempt was made to write a file that exceeds the file size limit of the process. - * `EFBIG` - An attempt was made to write a file that exceeds the maximum file size. +* `EFBIG` - The file is a regular file and an attempt was made to write at or beyond the offset maximum associated with +the corresponding +_stream_. - * `EFBIG` - An attempt was made to write a file that exceeds the file size limit of the process. +* `EINTR` - The `fflush()` function was interrupted by a signal. - * `EFBIG` - The file is a regular file and an attempt was made to write at or beyond the offset maximum associated with the corresponding -_stream_. +* `EIO` - The process is a member of a background process group attempting to write to its controlling terminal, +`TOSTOP` is set, the calling thread is not blocking `SIGTTOU`, the process is not ignoring `SIGTTOU`, and the process +group of the process is orphaned. This error may also be returned under implementation-defined conditions. - * `EINTR` - The `fflush()` function was interrupted by a signal. +* `ENOMEM` - The underlying _stream_ was created by `open_memstream()` or `open_wmemstream()` and insufficient memory is +available. - * `EIO` - The process is a member of a background process group attempting to write to its controlling terminal, `TOSTOP` is set, the calling -thread is not blocking `SIGTTOU`, the process is not ignoring `SIGTTOU`, and the process group of the process is orphaned. This error -may also be returned under implementation-defined conditions. +* `ENOSPC` - There was no free space remaining on the device containing the file or in the buffer used by the +`fmemopen()` function. - * `ENOMEM` - The underlying _stream_ was created by `open_memstream()` or `open_wmemstream()` and insufficient memory is available. - - * `ENOSPC` - There was no free space remaining on the device containing the file or in the buffer used by the `fmemopen()` function. - - * `EPIPE` - An attempt is made to write to a pipe or FIFO that is not open for reading by any process. A `SIGPIPE` signal shall also be sent to the -thread. +* `EPIPE` - An attempt is made to write to a pipe or FIFO that is not open for reading by any process. A `SIGPIPE` +signal shall also be sent to the thread. The `fflush()` function may fail if: - * `ENXIO` - A request was made of a nonexistent device, or the request was outside the capabilities of the device. +* `ENXIO` - A request was made of a nonexistent device, or the request was outside the capabilities of the device. ## Tests @@ -71,6 +75,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fgetc.part-impl.md b/libc/functions/f/fgetc.part-impl.md index 9982f80c..d22d59ca 100644 --- a/libc/functions/f/fgetc.part-impl.md +++ b/libc/functions/f/fgetc.part-impl.md @@ -1,59 +1,61 @@ -# Synopsis -`#include `
+# Synopsis -` int fgetc(FILE *stream);`
+`#include ` + +`int fgetc(FILE *stream);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description If the end-of-file indicator for the input stream pointed to by _stream_ is not set and a next byte is present, the -`fgetc()` function shall obtain the next byte as an unsigned char converted to an int, from the input stream -pointed to by _stream_, and advance the associated file position indicator for the stream (if defined). Since `fgetc()` -operates on bytes, reading a character consisting of multiple bytes (or "a multi-byte character") may require multiple calls to -`fgetc()`. -The -`fgetc()` function may mark the last data access timestamp of the file associated with _stream_ for update. The last data -access timestamp shall be marked for update by the first successful execution of `fgetc()`, `fgets()`, `fread()`, `fscanf()`, `getc()`, `getchar()`, `getdelim()`, `getline()`, `gets()`, or `scanf()` using _stream_ that returns data not supplied by a prior call to `ungetc()`. +`fgetc()` function shall obtain the next byte as an unsigned char converted to an int, from the input stream pointed +to by _stream_, and advance the associated file position indicator for the stream (if defined). Since `fgetc()` +operates on bytes, reading a character consisting of multiple bytes (or "a multi-byte character") may require multiple +calls to `fgetc()`. +The `fgetc()` function may mark the last data access timestamp of the file associated with _stream_ for update. The +last data access timestamp shall be marked for update by the first successful execution of `fgetc()`, `fgets()`, +`fread()`, `fscanf()`, `getc()`, `getchar()`, `getdelim()`, `getline()`, `gets()`, or `scanf()` using _stream_ that +returns data not supplied by a prior call to `ungetc()`. ## Return value -Upon successful completion, `fgetc()` shall return the next byte from the input stream pointed to by _stream_. If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end-of-file indicator for the stream shall be set and `fgetc()` shall return `EOF`. If a read error occurs, the error indicator for the stream shall be set, `fgetc()` shall return `EOF` and shall set `errno` to indicate the error. - - +Upon successful completion, `fgetc()` shall return the next byte from the input stream pointed to by _stream_. +If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end-of-file indicator +for the stream shall be set and `fgetc()` shall return `EOF`. If a read error occurs, the error indicator for the +stream shall be set, `fgetc()` shall return `EOF` and shall set `errno` to indicate the error. ## Errors - The `fgetc()` function shall fail if data needs to be read and: - * `EAGAIN` - The `O_NONBLOCK` flag is set for the file descriptor underlying _stream_ and the thread would be delayed in the `fgetc()` -operation. +* `EAGAIN` - The `O_NONBLOCK` flag is set for the file descriptor underlying _stream_ and the thread would be delayed + in the `fgetc()` +operation. - * `EBADF` - The file descriptor underlying _stream_ is not a valid file descriptor open for reading. +* `EBADF` - The file descriptor underlying _stream_ is not a valid file descriptor open for reading. - * `EINTR` - The read operation was terminated due to the receipt of a signal, and no data was transferred. +* `EINTR` - The read operation was terminated due to the receipt of a signal, and no data was transferred. - * `EIO` - A physical `I/O` error has occurred, or the process is in a background process group attempting to read from its controlling terminal, -and either the calling thread is blocking `SIGTTIN` or the process is ignoring `SIGTTIN` or the process group of the process is -orphaned. This error may also be generated for implementation-defined reasons. +* `EIO` - A physical `I/O` error has occurred, or the process is in a background process group attempting to read from + its controlling terminal, and either the calling thread is blocking `SIGTTIN` or the process is ignoring `SIGTTIN` or + the process group of the process is orphaned. This error may also be generated for implementation-defined reasons. - * `EOVERFLOW` - The file is a regular file and an attempt was made to read at or beyond the offset maximum associated with the corresponding -stream. +* `EOVERFLOW` - The file is a regular file and an attempt was made to read at or beyond the offset maximum associated + with the corresponding stream. The `fgetc()` function may fail if: - * `ENOMEM` - Insufficient storage space is available. - - * `ENXIO` - A request was made of a nonexistent device, or the request was outside the capabilities of the device. - - - +* `ENOMEM` - Insufficient storage space is available. +* `ENXIO` - A request was made of a nonexistent device, or the request was outside the capabilities of the device. ## Tests @@ -63,6 +65,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fgets.part-impl.md b/libc/functions/f/fgets.part-impl.md index b3533b92..54ce7fcd 100644 --- a/libc/functions/f/fgets.part-impl.md +++ b/libc/functions/f/fgets.part-impl.md @@ -1,29 +1,34 @@ -# Synopsis -`#include `
+# Synopsis -` char *fgets(char *restrict s, int n, FILE *restrict stream);`
+`#include ` + +`char *fgets(char *restrict s, int n, FILE *restrict stream);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The `fgets()` function shall read bytes from _stream_ into the array pointed to by _s_ until `n-1` bytes are -read, or a `` is read and transferred to _s_, or an end-of-file condition is encountered. A `null` byte shall be -written immediately after the last byte read into the array. If the end-of-file condition is encountered before any bytes are read, -the contents of the array pointed to by _s_ shall not be changed. -The -`fgets()` function may mark the last data access timestamp of the file associated with _stream_ for update. The last data -access timestamp shall be marked for update by the first successful execution of `fgetc()`, `fgets()`, `fread()`, `fscanf()`, `getc()`, `getchar()`, `getdelim()`, `getline()`, `gets()`, or `scanf()` using _stream_ that returns data not supplied by a prior call to `ungetc()`. +The `fgets()` function shall read bytes from _stream_ into the array pointed to by _s_ until `n-1` bytes are read, or a +`` is read and transferred to _s_, or an end-of-file condition is encountered. A `null` byte shall be written +immediately after the last byte read into the array. If the end-of-file condition is encountered before any bytes are +read, the contents of the array pointed to by _s_ shall not be changed. +The `fgets()` function may mark the last data access timestamp of the file associated with _stream_ for update. The last +data access timestamp shall be marked for update by the first successful execution of `fgetc()`, `fgets()`, `fread()`, +`fscanf()`, `getc()`, `getchar()`, `getdelim()`, `getline()`, `gets()`, or `scanf()` using _stream_ that returns data +not supplied by a prior call to `ungetc()`. ## Return value - -Upon successful completion, fgets() shall return _s_. If the stream is at end-of-file, the end-of-file indicator for the stream shall be set and `fgets()` shall return a `null` pointer. If a read error occurs, the error indicator for the stream shall be set, `fgets()` shall return a `null` pointer and shall set `errno` to indicate the error. - +Upon successful completion, fgets() shall return _s_. If the stream is at end-of-file, the end-of-file indicator for the +stream shall be set and `fgets()` shall return a `null` pointer. If a read error occurs, the error indicator for the +stream shall be set, `fgets()` shall return a `null` pointer and shall set `errno` to indicate the error. ## Errors @@ -37,6 +42,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fileno.part-impl.md b/libc/functions/f/fileno.part-impl.md index 9902ffdd..6f4a6282 100644 --- a/libc/functions/f/fileno.part-impl.md +++ b/libc/functions/f/fileno.part-impl.md @@ -1,40 +1,35 @@ -# Synopsis -`#include `
+# Synopsis -` int fileno(FILE *stream); `
+`#include ` + +` int fileno(FILE *stream); ` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `fileno()` function maps a stream pointer to a file descriptor associated with the stream pointed to by _stream_. - ## Return value - -Upon successful completion, `fileno()` shall return the integer value of the file descriptor associated with _stream_. Otherwise, the value `-1` shall be returned and `errno` set to indicate the error. - +Upon successful completion, `fileno()` shall return the integer value of the file descriptor associated with _stream_. +Otherwise, the value `-1` shall be returned and `errno` set to indicate the error. ## Errors - The `fileno()` function shall fail if: - - * `EBADF` - The stream is not associated with a file. +* `EBADF` - The stream is not associated with a file. The `fileno()` function may fail if: - - * `EBADF` - The file descriptor underlying stream is not a valid file descriptor. - - - - +* `EBADF` - The file descriptor underlying stream is not a valid file descriptor. ## Tests @@ -44,6 +39,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/floor.part-impl.md b/libc/functions/f/floor.part-impl.md index 1dab3d58..8c0cad32 100644 --- a/libc/functions/f/floor.part-impl.md +++ b/libc/functions/f/floor.part-impl.md @@ -1,41 +1,39 @@ -# Synopsis -`#include `
+# Synopsis -` double floor(double x);`
+`#include ` -` float floorf(float x);`
+`double floor(double x);` -` long double floorl(long double x);`
+`float floorf(float x);` + +`long double floorl(long double x);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description These functions shall compute the largest integral value not greater than _x_. - ## Return value - The result shall have the same sign as _x_. -Upon successful completion, these functions shall return the largest integral value not greater than _x_, expressed as a double, float, or long double, as appropriate for the return type of the function. - -If _x_ is `NaN`, a `NaN` shall be returned. - -If _x_ is `±0` or `±Inf`, _x_ shall be returned. +Upon successful completion, these functions shall return the largest integral value not greater than _x_, expressed as a +double, float, or long double, as appropriate for the return type of the function. +* If _x_ is `NaN`, a `NaN` shall be returned. +* If _x_ is `±0` or `±Inf`, _x_ shall be returned. ## Errors - No errors are defined. - - ## Tests Untested @@ -44,6 +42,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fmod.part-impl.md b/libc/functions/f/fmod.part-impl.md index b749210a..a59bdb8d 100644 --- a/libc/functions/f/fmod.part-impl.md +++ b/libc/functions/f/fmod.part-impl.md @@ -1,64 +1,62 @@ -# Synopsis -`#include `
+# Synopsis -` double fmod(double x, double y);`
+`#include ` -` float fmodf(float x, float y);`
+`double fmod(double x, double y);` -` long double fmodl(long double x, long double y);`
+`float fmodf(float x, float y);` + +`long double fmodl(long double x, long double y);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description These functions shall return the floating-point remainder of the division of _x_ by _y_. -An application wishing to check for error situations should set `errno` to zero and call -`feclearexcept(FE_ALL_EXCEPT)` before calling these functions. On return, if `errno` is non-zero or +An application wishing to check for error situations should set `errno` to zero and call `feclearexcept(FE_ALL_EXCEPT)` +before calling these functions. On return, if `errno` is non-zero or `fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)` is non-zero, an error has occurred. - ## Return value +These functions shall return the value `(x-i*y)`, for some integer `i` such that, if _y_ is non-zero, the result has the +same sign as _x_ and magnitude less than the magnitude of _y_. -These functions shall return the value `(x-i*y)`, for some integer `i` such that, if _y_ is non-zero, the result has the same sign as _x_ and magnitude less than the magnitude of _y_. - -If the correct value would cause underflow and is not representable,a range error may occur, and `fmod()`, `modf()`, and `fmodl()` shall return `0.0`, or (if the `IEC 60559` Floating-Point option is not supported) an implementation-defined value no greater in magnitude than `DBL_MIN`, `FLT_MIN`, and `LDBL_MIN`, respectively. - -If _x_ or _y_ is `NaN`, a `NaN` shall be returned, and none of the conditions below shall be considered. - -If _y_ is zero, a domain error shall occur, and a `NaN` shall be returned. - -If _x_ is infinite, a domain error shall occur, and a `NaN` shall be returned. - -If _x_ is `±0` and _y_ is not zero, `±0` shall be returned. - -If _x_ is not infinite and _y_ is `±Inf`, _x_ shall be returned. - -If the correct value would cause underflow, and is representable, a range error may occur and the correct value shall be returned. +* If the correct value would cause underflow and is not representable,a range error may occur, and `fmod()`, `modf()`, + and `fmodl()` shall return `0.0`, or (if the `IEC 60559` Floating-Point option is not supported) an + implementation-defined value no greater in magnitude than `DBL_MIN`, `FLT_MIN`, and `LDBL_MIN`, respectively. +* If _x_ or _y_ is `NaN`, a `NaN` shall be returned, and none of the conditions below shall be considered. +* If _y_ is zero, a domain error shall occur, and a `NaN` shall be returned. +* If _x_ is infinite, a domain error shall occur, and a `NaN` shall be returned. +* If _x_ is `±0` and _y_ is not zero, `±0` shall be returned. +* If _x_ is not infinite and _y_ is `±Inf`, _x_ shall be returned. +* If the correct value would cause underflow, and is representable, a range error may occur and the correct value shall + be returned. ## Errors - These functions shall fail if: - * `Domain Error` - The _x_ argument is infinite or _y_ is zero.
- If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `EDOM`. If -the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the invalid floating-point exception shall -be raised. +* `Domain Error` - The _x_ argument is infinite or _y_ is zero. +* If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `EDOM`. +* If the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the invalid floating-point + exception shall be raised. These functions may fail if: - * `Range Error` - The result underflows.
- If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If -the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the underflow floating-point exception -shall be raised. - +* `Range Error` - The result underflows. +* If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. +* If the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the underflow floating-point + exception shall be raised. ## Tests @@ -68,6 +66,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fnmatch.part-impl.md b/libc/functions/f/fnmatch.part-impl.md index 4ebdde98..12857018 100644 --- a/libc/functions/f/fnmatch.part-impl.md +++ b/libc/functions/f/fnmatch.part-impl.md @@ -1,79 +1,95 @@ -# Synopsis -`#include `
+# Synopsis -` int fnmatch(const char *pattern, const char *string, int flags);`
+`#include ` + +`int fnmatch(const char *pattern, const char *string, int flags);` ## Status -Partially implemented -## Conformance -IEEE Std 1003.1-2017 -## Description +Partially implemented -The `fnmatch()` function shall match patterns as described below. -It checks the string specified by the -_string_ argument to see if it matches the pattern specified by the _pattern_ argument. +## Conformance -The following patterns matching a single character shall match a single character: ordinary characters, special pattern characters, and pattern bracket expressions. The pattern bracket expression also shall match a single collating element. A `` character shall escape the following character. The escaping `` shall be discarded. If a pattern ends with an unescaped ``, it is unspecified whether the pattern does not match anything or the pattern is treated as invalid. +IEEE Std 1003.1-2017 -An ordinary character is a pattern that shall match itself. It can be any character in the supported character set except for `NUL`, those special shell characters in Quoting that require quoting, and the following three special pattern characters. Matching shall be based on the bit pattern used for encoding the character, not on the graphic representation of the character. If any character (ordinary, shell special, or pattern special) is quoted, that pattern shall match the character itself. The shell special characters always require quoting. +## Description -When unquoted and outside a bracket expression, the following three characters shall have special meaning in the specification of patterns: +The `fnmatch()` function shall match patterns as described below. It checks the string specified by the _string_ +argument to see if it matches the pattern specified by the _pattern_ argument. - * `?` - A `` is a pattern that shall match any character.
- * `*` - An `` is a pattern that shall match multiple characters, as described below.
- * `[` - If an open bracket introduces a bracket expression, except that the `` character `( '!' )` shall replace the `` character `( '^' )` in its role in a non-matching list in the regular expression notation, it shall introduce a pattern bracket expression.
- A bracket expression starting with an unquoted `` character produces unspecified results. Otherwise, `'['` shall match the character itself. When pattern matching is used where shell quote removal is not performed (such as in the argument to the find - name primary when find is being called using one of the exec functions, or in the pattern argument to the `fnmatch()` function), special characters can be escaped to remove their special meaning by preceding them with a `` character. This escaping `` is discarded. The sequence `"\\"` represents one literal ``. All of the requirements and effects of quoting on ordinary, shell special, and special pattern characters shall apply to escaping in this context. +The following patterns matching a single character shall match a single character: ordinary characters, special pattern +characters, and pattern bracket expressions. The pattern bracket expression also shall match a single collating element. +A `\` character shall escape the following character. The escaping `\` shall be discarded. If a +pattern ends with an unescaped `\`, it is unspecified whether the pattern does not match anything or the +pattern is treated as invalid. -The following rules are used to construct patterns matching multiple characters from patterns matching a single character: +An ordinary character is a pattern that shall match itself. It can be any character in the supported character set +except for `NUL`, those special shell characters in Quoting that require quoting, and the following three special +pattern characters. Matching shall be based on the bit pattern used for encoding the character, not on the graphic +representation of the character. If any character (ordinary, shell special, or pattern special) is quoted, that pattern +shall match the character itself. The shell special characters always require quoting. -* The `` `( '*' )` is a pattern that shall match any string, including the null string. +When unquoted and outside a bracket expression, the following three characters shall have special meaning in the +specification of patterns: -* The concatenation of patterns matching a single character is a valid pattern that shall match the concatenation of the single characters or collating elements matched by each of the concatenated patterns. +* `?` - A `?` is a pattern that shall match any character. +* `*` - An `*` is a pattern that shall match multiple characters, as described below. +* `[` - If an open bracket introduces a bracket expression, except that the `` character `'!'` + shall replace the `^` character `'^'` in its role in a non-matching list in the regular expression + notation, it shall introduce a pattern bracket expression. -* The concatenation of one or more patterns matching a single character with one or more `` characters is a valid pattern. In such patterns, each `` shall match a string of zero or more characters, matching the greatest possible number of characters that still allows the remainder of the pattern to match the string. + A bracket expression starting with an unquoted `^` character produces unspecified results. Otherwise, `'['` + shall match the character itself. When pattern matching is used where shell quote removal is not performed (such as in + the argument to the find - name primary when find is being called using one of the exec functions, or in the pattern + argument to the `fnmatch()` function), special characters can be escaped to remove their special meaning by preceding + them with a `\` character. This escaping `\` is discarded. The sequence `"\\"` represents one literal `\`. All of the + requirements and effects of quoting on ordinary, shell special, and special pattern characters shall apply to escaping + in this context. +The following rules are used to construct patterns matching multiple characters from patterns matching a single +character: +* The `*` is a pattern that shall match any string, including the null string. -The _flags_ argument shall modify the interpretation of _pattern_ and _string_. It is the bitwise-inclusive OR of -zero or more of the _flags_ defined in ``. If the `FNM_PATHNAME` flag is -set in _flags_, then a `` character `( '/' )` in _string_ shall be explicitly matched by a `` in _pattern_; it shall not be matched by either the `` or `` special -characters, nor by a bracket expression. If the `FNM_PATHNAME` flag is not set, the `` character shall be treated as an -ordinary character. +* The concatenation of patterns matching a single character is a valid pattern that shall match the concatenation of the +single characters or collating elements matched by each of the concatenated patterns. -* If `FNM_NOESCAPE` is not set in _flags_, a `` character in _pattern_ followed by any other character -shall match that second character in _string_. In particular, `"\\"` shall match a `` in _string_. +* The concatenation of one or more patterns matching a single character with one or more `*` characters is a valid +pattern. In such patterns, each `*` shall match a string of zero or more characters, matching the greatest possible +number of characters that still allows the remainder of the pattern to match the string. -* If _pattern_ ends with an unescaped ``, `fnmatch()` shall return a non-zero value (indicating either no -match or an error). If `FNM_NOESCAPE` is set, a `` character shall be treated as an ordinary character. +The _flags_ argument shall modify the interpretation of _pattern_ and _string_. It is the bitwise-inclusive OR of zero +or more of the _flags_ defined in ``. If the `FNM_PATHNAME` flag is set in _flags_, then a `/` character +`( '/' )` in _string_ shall be explicitly matched by a `/` in _pattern_; it shall not be matched by either the `*` or +`?` special characters, nor by a bracket expression. If the `FNM_PATHNAME` flag is not set, the `/` character shall be +treated as an ordinary character. -* If `FNM_PERIOD` is set in _flags_, then a leading `` `( '.' )` in _string_ shall match a -`` in _pattern_, where the location of `"leading"` is indicated by the value of `FNM_PATHNAME`: +* If `FNM_NOESCAPE` is not set in _flags_, a `\` character in _pattern_ followed by any other character shall match that +second character in _string_. In particular, `"\\"` shall match a `\` in _string_. +* If _pattern_ ends with an unescaped `\`, `fnmatch()` shall return a non-zero value (indicating either no match or an +error). If `FNM_NOESCAPE` is set, a `\` character shall be treated as an ordinary character. -* If `FNM_PATHNAME` is set, a `` is `"leading"` if it is the first character in _string_ or if it immediately follows a ``. +* If `FNM_PERIOD` is set in _flags_, then a leading `` `'.'` in _string_ shall match a `` in +_pattern_, where the location of `"leading"` is indicated by the value of `FNM_PATHNAME`: +* If `FNM_PATHNAME` is set, a `` is `"leading"` if it is the first character in _string_ or if it immediately +follows a `/`. * If `FNM_PATHNAME` is not set, a `` is `"leading"` only if it is the first character of _string_. - -If `FNM_PERIOD` is not set, then no special restrictions are placed on matching a period. - +* If `FNM_PERIOD` is not set, then no special restrictions are placed on matching a period. ## Return value - -If _string_ matches the pattern specified by _pattern_, then `fnmatch()` shall return `0`. If there is no match, `fnmatch()` shall return `FNM_NOMATCH`, which is defined in ``. If an error occurs, `fnmatch()` shall return another non-zero value. - +If _string_ matches the pattern specified by _pattern_, then `fnmatch()` shall return `0`. If there is no match, +`fnmatch()` shall return `FNM_NOMATCH`, which is defined in ``. If an error occurs, `fnmatch()` shall +return another non-zero value. ## Errors - No errors are defined. - - - ## Tests Untested @@ -82,6 +98,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fopen.part-impl.md b/libc/functions/f/fopen.part-impl.md index b8fd83cf..efd9fe20 100644 --- a/libc/functions/f/fopen.part-impl.md +++ b/libc/functions/f/fopen.part-impl.md @@ -1,12 +1,17 @@ -# Synopsis -`#include `
+# Synopsis -` FILE *fopen(const char *restrict pathname, const char *restrict mode);`
+`#include ` + +`FILE *fopen(const char *restrict pathname, const char *restrict mode);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description The `fopen()` function shall open the file whose pathname is the string pointed to by _pathname_, and associates a @@ -23,37 +28,39 @@ mode. Otherwise, the behavior is undefined. * `a+` or `ab+` or `a+b` - Append; open or create file for update, writing at end-of-file. The -character `'b'` shall have no effect, but is allowed for `ISO C` standard conformance. Opening a file with read mode (`r` as the first character in the mode argument) shall -fail if the file does not exist or cannot be read. - -Opening a file with append mode (`a` as the first character in the mode argument) shall cause all subsequent writes -to the file to be forced to the then current end-of-file, regardless of intervening calls to `fseek()`. - -When a file is opened with update mode ( `'+'` as the second or third character in the mode argument), both input -and output may be performed on the associated stream. However, the application shall ensure that output is not directly followed by -input without an intervening call to `fflush()` or to a file positioning function (`fseek()`, `fsetpos()`, or `rewind()`), and input is not directly followed by output without an intervening call to a file -positioning function, unless the input operation encounters end-of-file. - -When opened, a stream is fully buffered if and only if it can be determined not to refer to an interactive device. The error and -end-of-file indicators for the stream shall be cleared. -If -mode is `w`, `wb`, `a`, `ab`, `w+`, `wb+`, `w+b`, `a+`, `ab+`, or -`a+b`, and the file did not previously exist, upon successful completion, `fopen()` shall mark for update the last -data access, last data modification, and last file status change timestamps of the file and the last file status change and last -data modification timestamps of the parent directory. - -If mode is `w`, `wb`, `a`, `ab`, `w+`, `wb+`, `w+b`, `a+`, `ab+`, or -`a+b`, and the file did not previously exist, the `fopen()` function shall create a file as if it called the `creat()` function with a value appropriate for the path argument interpreted from -_pathname_ and a value of `S_IRUSR` | `S_IWUSR` | `S_IRGRP` | `S_IWGRP` | `S_IROTH` | `S_IWOTH` for the mode argument. - -If mode is `w`, `wb`, `w+`, `wb+`, or `w+b`, and the file did previously exist, upon -successful completion, `fopen()` shall mark for update the last data modification and last file status change timestamps of -the file. +character `'b'` shall have no effect, but is allowed for `ISO C` standard conformance. Opening a file with read mode +(`r` as the first character in the mode argument) shall fail if the file does not exist or cannot be read. + +Opening a file with append mode (`a` as the first character in the mode argument) shall cause all subsequent writes to +the file to be forced to the then current end-of-file, regardless of intervening calls to `fseek()`. + +When a file is opened with update mode ( `'+'` as the second or third character in the mode argument), both input and +output may be performed on the associated stream. However, the application shall ensure that output is not directly +followed by input without an intervening call to `fflush()` or to a file positioning function (`fseek()`, `fsetpos()`, +or `rewind()`), and input is not directly followed by output without an intervening call to a file positioning function, +unless the input operation encounters end-of-file. + +When opened, a stream is fully buffered if and only if it can be determined not to refer to an interactive device. The +error and end-of-file indicators for the stream shall be cleared. + +If mode is `w`, `wb`, `a`, `ab`, `w+`, `wb+`, `w+b`, `a+`, `ab+`, or `a+b`, and the file did not previously exist, upon +successful completion, `fopen()` shall mark for update the last data access, last data modification, and last file +status change timestamps of the file and the last file status change and last data modification timestamps of the parent +directory. + +If mode is `w`, `wb`, `a`, `ab`, `w+`, `wb+`, `w+b`, `a+`, `ab+`, or `a+b`, and the file did not previously exist, the +`fopen()` function shall create a file as if it called the `creat()` function with a value appropriate for the path +argument interpreted from _pathname_ and a value of `S_IRUSR` | `S_IWUSR` | `S_IRGRP` | `S_IWGRP` | `S_IROTH` | +`S_IWOTH` for the mode argument. + +If mode is `w`, `wb`, `w+`, `wb+`, or `w+b`, and the file did previously exist, upon successful completion, `fopen()` +shall mark for update the last data modification and last file status change timestamps of the file. + After a successful call to the `fopen()` function, the orientation of the stream shall be cleared, the encoding rule shall be cleared, and the associated `mbstate_t` object shall be set to describe an initial conversion state. -The -file descriptor associated with the opened stream shall be allocated and opened as if by a call to `open()` with the following flags: +The file descriptor associated with the opened stream shall be allocated and opened as if by a call to `open()` with the +following flags: @@ -66,72 +73,71 @@ file descriptor associated with the opened stream shall be allocated and opened | `w+` or `wb+` or `w+b` | `O_RDWR ׀ O_CREAT ׀ O_TRUNC` | | `a+` or `ab+` or `a+b` | `O_RDWR ׀ O_CREAT ׀ O_APPEND` | - ## Return value -Upon successful completion, `fopen()` shall return a pointer to the object controlling the stream. Otherwise, a `null` pointer shall be returned and `errno` shall be set to indicate the error. +Upon successful completion, `fopen()` shall return a pointer to the object controlling the stream. Otherwise, a `null` +pointer shall be returned and `errno` shall be set to indicate the error. ## Errors - The `fopen()` function shall fail if: +* `EACCES` - Search permission is denied on a component of the path prefix, or the file exists and the permissions + specified by mode are denied, or the file does not exist and write permission is denied for the parent directory of the + file to be created. - * `EACCES` - Search permission is denied on a component of the path prefix, or the file exists and the permissions specified by mode are -denied, or the file does not exist and write permission is denied for the parent directory of the file to be created. - - * `EINTR` - A signal was caught during `fopen()`. +* `EINTR` - A signal was caught during `fopen()`. - * `EISDIR` - The named file is a directory and mode requires write access. +* `EISDIR` - The named file is a directory and mode requires write access. - * `ELOOP` - A loop exists in symbolic links encountered during resolution of the path argument. +* `ELOOP` - A loop exists in symbolic links encountered during resolution of the path argument. - * `EMFILE` - All file descriptors available to the process are currently open. +* `EMFILE` - All file descriptors available to the process are currently open. - * `EMFILE` - `STREAM_MAX` streams are currently open in the calling process. +* `EMFILE` - `STREAM_MAX` streams are currently open in the calling process. - * `ENAMETOOLONG` - The length of a _pathname_ exceeds `PATH_MAX`, or _pathname_ resolution of a symbolic link produced an intermediate result with a -length that exceeds `PATH_MAX`. +* `ENAMETOOLONG` - The length of a _pathname_ exceeds `PATH_MAX`, or _pathname_ resolution of a symbolic link produced + an intermediate result with a length that exceeds `PATH_MAX`. - * `ENFILE` - The maximum allowable number of files is currently open in the system. +* `ENFILE` - The maximum allowable number of files is currently open in the system. - * `ENOENT` - The mode string begins with `'r'` and a component of _pathname_ does not name an existing file, or mode -begins with `'w'` or `'a'` and a component of the path prefix of _pathname_ does not name an existing file, or -_pathname_ is an empty string. -`ENOENT` or `ENOTDIR` - -The pathname argument contains at least one non- character and ends with one or more trailing -characters. If pathname without the trailing characters would name an existing file, an `ENOENT` error shall -not occur. +* `ENOENT` - The mode string begins with `'r'` and a component of _pathname_ does not name an existing file, or mode + begins with `'w'` or `'a'` and a component of the path prefix of _pathname_ does not name an existing file, or + _pathname_ is an empty string. `ENOENT` or `ENOTDIR` - * `ENOSPC` - The directory or file system that would contain the new file cannot be expanded, the file does not exist, and the file was to be -created. +The pathname argument contains at least one non- `/` character and ends with one or more trailing `/` +characters. If pathname without the trailing `/` characters would name an existing file, an `ENOENT` error +shall not occur. - * `ENOTDIR` - A component of the path prefix names an existing file that is neither a directory nor a symbolic link to a directory, or the -pathname argument contains at least one non- character and ends with one or more trailing -characters and the last pathname component names an existing file that is neither a directory nor a symbolic link to a directory. +* `ENOSPC` - The directory or file system that would contain the new file cannot be expanded, the file does not exist, + and the file was to be created. +* `ENOTDIR` - A component of the path prefix names an existing file that is neither a directory nor a symbolic link + to a directory, or the pathname argument contains at least one non- `/` character and ends with one or more + trailing `/` characters and the last pathname component names an existing file that is neither a directory nor a + symbolic link to a directory. - * `ENXIO` - The named file is a character special or block special file, and the device associated with this special file does not exist. +* `ENXIO` - The named file is a character special or block special file, and the device associated with this special +file does not exist. - * `EOVERFLOW` - The named file is a regular file and the size of the file cannot be represented correctly in an object of type `off_t`. +* `EOVERFLOW` - The named file is a regular file and the size of the file cannot be represented correctly in an object +of type `off_t`. - * `EROFS` - The named file resides on a read-only file system and mode requires write access. +* `EROFS` - The named file resides on a read-only file system and mode requires write access. The `fopen()` function may fail if: - * `EINVAL` - The value of the mode argument is not valid. +* `EINVAL` - The value of the mode argument is not valid. - * `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the path argument. +* `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the path argument. - * `EMFILE` - `FOPEN_MAX` streams are currently open in the calling process. +* `EMFILE` - `FOPEN_MAX` streams are currently open in the calling process. - * `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. +* `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. - * `ENOMEM` - Insufficient storage space is available. - - * `ETXTBSY` - The file is a pure procedure (shared text) file that is being executed and mode requires write access. +* `ENOMEM` - Insufficient storage space is available. +* `ETXTBSY` - The file is a pure procedure (shared text) file that is being executed and mode requires write access. ## Tests @@ -141,6 +147,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fork.part-impl.md b/libc/functions/f/fork.part-impl.md index b3722d78..8287962a 100644 --- a/libc/functions/f/fork.part-impl.md +++ b/libc/functions/f/fork.part-impl.md @@ -1,14 +1,18 @@ -# Synopsis -`#include `
+# Synopsis -` pid_t fork(void);`
+`#include ` + +`pid_t fork(void);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `fork()` function shall create a new process. The new process (child process) shall be an exact copy of the calling process (parent process) except as detailed below: @@ -19,71 +23,93 @@ process (parent process) except as detailed below: * The child process shall have a different parent process ID, which shall be the process ID of the calling process. -* The child process shall have its own copy of the parent's file descriptors. Each of the child's file descriptors shall refer to the same open file description with the corresponding file descriptor of the parent. +* The child process shall have its own copy of the parent's file descriptors. Each of the child's file descriptors shall +refer to the same open file description with the corresponding file descriptor of the parent. -* The child process shall have its own copy of the parent's open directory streams. Each open directory stream in the child process may share directory stream positioning with the corresponding directory stream of the parent. +* The child process shall have its own copy of the parent's open directory streams. Each open directory stream in the +child process may share directory stream positioning with the corresponding directory stream of the parent. * The child process shall have its own copy of the parent's message catalog descriptors. * The child process values of `tms_utime,` `tms_stime,` `tms_cutime,` and `tms_cstime` shall be set to `0`. -* The time left until an alarm clock signal shall be reset to zero, and the alarm, if any, shall be canceled. See [alarm](../a/alarm.part-impl.md) +* The time left until an alarm clock signal shall be reset to zero, and the alarm, if any, shall be canceled. +See [alarm](../a/alarm.part-impl.md) -* All semaphore adjustment values shall be cleared. +* All semaphore adjustment values shall be cleared. * File locks set by the parent process shall not be inherited by the child process. * The set of signals pending for the child process shall be initialized to the empty set. -* Interval timers shall be reset in the child process. +* Interval timers shall be reset in the child process. * Any semaphores that are open in the parent process shall also be open in the child process. -* The child process shall not inherit any address space memory locks established by the parent process via calls to `mlockall()` or `mlock()`. +* The child process shall not inherit any address space memory locks established by the parent process via calls to +`mlockall()` or `mlock()`. -* Memory mappings created in the parent shall be retained in the child process. `MAP_PRIVATE` mappings inherited from the parent shall also be `MAP_PRIVATE` mappings in the child, and any modifications to the data in these mappings made by the parent prior to calling `fork()` shall be visible to the child. Any modifications to the data in `MAP_PRIVATE` mappings made by the parent after `fork()` returns shall be visible only to the parent. Modifications to the data in `MAP_PRIVATE` mappings made by the child shall be visible only to the child. +* Memory mappings created in the parent shall be retained in the child process. `MAP_PRIVATE` mappings inherited from +the parent shall also be `MAP_PRIVATE` mappings in the child, and any modifications to the data in these mappings made +by the parent prior to calling `fork()` shall be visible to the child. Any modifications to the data in `MAP_PRIVATE` +mappings made by the parent after `fork()` returns shall be visible only to the parent. Modifications to the data in +`MAP_PRIVATE` mappings made by the child shall be visible only to the child. -* For the `SCHED_FIFO` and `SCHED_RR` scheduling policies, the child process shall inherit the policy and priority settings of the parent process during a `fork()` function. For other scheduling policies, the policy and priority settings on `fork()` are implementation-defined. +* For the `SCHED_FIFO` and `SCHED_RR` scheduling policies, the child process shall inherit the policy and priority +settings of the parent process during a `fork()` function. For other scheduling policies, the policy and priority +settings on `fork()` are implementation-defined. * Per-process timers created by the parent shall not be inherited by the child process. -* The child process shall have its own copy of the message queue descriptors of the parent. Each of the message descriptors of the child shall refer to the same open message queue description as the corresponding message descriptor of the parent. +* The child process shall have its own copy of the message queue descriptors of the parent. Each of the message +descriptors of the child shall refer to the same open message queue description as the corresponding message descriptor +of the parent. -* No asynchronous input or asynchronous output operations shall be inherited by the child process. Any use of asynchronous control blocks created by the parent produces undefined behavior. +* No asynchronous input or asynchronous output operations shall be inherited by the child process. Any use of +asynchronous control blocks created by the parent produces undefined behavior. -* A process shall be created with a single thread. If a multi-threaded process calls `fork()`, the new process shall contain a replica of the calling thread and its entire address space, possibly including the states of mutexes and other resources. Consequently, to avoid errors, the child process may only execute async-signal-safe operations until such time as one of the exec functions is called. +* A process shall be created with a single thread. If a multi-threaded process calls `fork()`, the new process shall +contain a replica of the calling thread and its entire address space, possibly including the states of mutexes and other +resources. Consequently, to avoid errors, the child process may only execute async-signal-safe operations until such +time as one of the exec functions is called. - When the application calls `fork()` from a signal handler and any of the fork handlers registered by ``pthread_atfork()`` calls a function that is not async-signal-safe, the behavior is undefined. + When the application calls `fork()` from a signal handler and any of the fork handlers registered by + ``pthread_atfork()`` calls a function that is not async-signal-safe, the behavior is undefined. * If the Trace option and the Trace Inherit option are both supported: - If the calling process was being traced in a trace stream that had its inheritance policy set to `POSIX_TRACE_INHERITED,` the child process shall be traced into that trace stream, and the child process shall inherit the parent's mapping of trace event names to trace event type identifiers. If the trace stream in which the calling process was being traced had its inheritance policy set to `POSIX_TRACE_CLOSE_FOR_CHILD,` the child process shall not be traced into that trace stream. The inheritance policy is set by a call to the ``posix_trace_attr_setinherited()`` function. + If the calling process was being traced in a trace stream that had its inheritance policy set to + `POSIX_TRACE_INHERITED,` the child process shall be traced into that trace stream, and the child process shall inherit + the parent's mapping of trace event names to trace event type identifiers. If the trace stream in which the calling + process was being traced had its inheritance policy set to `POSIX_TRACE_CLOSE_FOR_CHILD,` the child process shall not + be traced into that trace stream. The inheritance policy is set by a call to the ``posix_trace_attr_setinherited()`` + function. * If the Trace option is supported, but the Trace Inherit option is not supported: - The child process shall not be traced into any of the trace streams of its parent process. + The child process shall not be traced into any of the trace streams of its parent process. -* If the Trace option is supported, the child process of a trace controller process shall not control the trace streams controlled by its parent process. +* If the Trace option is supported, the child process of a trace controller process shall not control the trace streams +controlled by its parent process. -* The initial value of the CPU-time clock of the child process shall be set to zero. +* The initial value of the CPU-time clock of the child process shall be set to zero. * The initial value of the CPU-time clock of the single thread of the child process shall be set to zero. - -All other process characteristics defined by `POSIX.1-2017` shall be the same in the parent and child processes. The inheritance -of process characteristics not defined by `POSIX.1-2017` is unspecified. +All other process characteristics defined by `POSIX.1-2017` shall be the same in the parent and child processes. +The inheritance of process characteristics not defined by `POSIX.1-2017` is unspecified. After `fork()`, both the parent and the child processes shall be capable of executing independently before either one terminates. - ## Return value - ## Errors -Upon successful completion, `fork()` shall return `0` to the child process and shall return the process ID of the child process to the parent process. Both processes shall continue to execute from the `fork()` function. Otherwise, `-1` shall be returned to the parent process, no child process shall be created, and `errno` shall be set to indicate the error. - +Upon successful completion, `fork()` shall return `0` to the child process and shall return the process ID of the child +process to the parent process. Both processes shall continue to execute from the `fork()` function. Otherwise, `-1` +shall be returned to the parent process, no child process shall be created, and `errno` shall be set to indicate the +error. ## Tests @@ -93,6 +119,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fprintf.part-impl.md b/libc/functions/f/fprintf.part-impl.md index f739bf83..6db2e0e3 100644 --- a/libc/functions/f/fprintf.part-impl.md +++ b/libc/functions/f/fprintf.part-impl.md @@ -1,13 +1,13 @@ -###Synopsis +# Synopsis `#include ` `int fprintf(FILE *stream, const char *format, ...);` -###Description +## Description Sends formatted output to a stream. -###Return value +## Return value -###Errors \ No newline at end of file +## Errors diff --git a/libc/functions/f/fputc.part-impl.md b/libc/functions/f/fputc.part-impl.md index 37694084..8c51acc4 100644 --- a/libc/functions/f/fputc.part-impl.md +++ b/libc/functions/f/fputc.part-impl.md @@ -1,65 +1,65 @@ -# Synopsis -`#include `
+# Synopsis -` int fputc(int c, FILE *stream);`
+`#include ` + +`int fputc(int c, FILE *stream);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description -The `fputc()` function shall write the byte specified by _c_ (converted to an unsigned char) to the output -stream pointed to by stream, at the position indicated by the associated file-position indicator for the stream (if -defined), and shall advance the indicator appropriately. If the file cannot support positioning requests, or if the stream was +The `fputc()` function shall write the byte specified by _c_ (converted to an unsigned char) to the output stream +pointed to by stream, at the position indicated by the associated file-position indicator for the stream (if defined), +and shall advance the indicator appropriately. If the file cannot support positioning requests, or if the stream was opened with append mode, the byte shall be appended to the output stream. -The -last data modification and last file status change timestamps of the file shall be marked for update between the successful -execution of `fputc()` and the next successful completion of a call to `fflush()` -or `fclose()` on the same stream or a call to `exit()` or `abort()`. +The last data modification and last file status change timestamps of the file shall be marked for update between the +successful execution of `fputc()` and the next successful completion of a call to `fflush()` or `fclose()` on the same +stream or a call to `exit()` or `abort()`. ## Return value - -Upon successful completion, `fputc()` shall return the value it has written. Otherwise, it shall return `EOF`, the error indicator for the stream shall be set and `errno` shall be set to indicate the error. - +Upon successful completion, `fputc()` shall return the value it has written. Otherwise, it shall return `EOF`, the error +indicator for the stream shall be set and `errno` shall be set to indicate the error. ## Errors +The `fputc()` function shall fail if either the stream is unbuffered or the stream's buffer needs to be flushed, and: -The `fputc()` function shall fail if either the stream is unbuffered or the stream's buffer needs to be -flushed, and: - - - * `EAGAIN` - The `O_NONBLOCK` flag is set for the file descriptor underlying stream and the thread would be delayed in the write operation. +* `EAGAIN` - The `O_NONBLOCK` flag is set for the file descriptor underlying stream and the thread would be delayed in +the write operation. +* `EBADF` - The file descriptor underlying stream is not a valid file descriptor open for writing. - * `EBADF` - The file descriptor underlying stream is not a valid file descriptor open for writing. +* `EFBIG` - An attempt was made to write to a file that exceeds the maximum file size. - * `EFBIG` - An attempt was made to write to a file that exceeds the maximum file size. +* `EFBIG` - An attempt was made to write to a file that exceeds the file size limit of the process. - * `EFBIG` - An attempt was made to write to a file that exceeds the file size limit of the process. +* `EFBIG` - The file is a regular file and an attempt was made to write at or beyond the offset maximum. - * `EFBIG` - The file is a regular file and an attempt was made to write at or beyond the offset maximum. +* `EINTR` - The write operation was terminated due to the receipt of a signal, and no data was transferred. - * `EINTR` - The write operation was terminated due to the receipt of a signal, and no data was transferred. +* `EIO` - A physical I/O error has occurred, or the process is a member of a background process group attempting to +write to its controlling terminal, `TOSTOP` is set, the calling thread is not blocking `SIGTTOU`, the process is not +ignoring `SIGTTOU`, and the process group of the process is orphaned. This error may also be returned under +implementation-defined conditions. - * `EIO` - A physical I/O error has occurred, or the process is a member of a background process group attempting to write to its controlling -terminal, `TOSTOP` is set, the calling thread is not blocking `SIGTTOU`, the process is not ignoring `SIGTTOU`, and the process group of -the process is orphaned. This error may also be returned under implementation-defined conditions. - - * `ENOSPC` - There was no free space remaining on the device containing the file. - - * `EPIPE` - An attempt is made to write to a pipe or `FIFO` that is not open for reading by any process. A `SIGPIPE` signal shall also be sent to the -thread. +* `ENOSPC` - There was no free space remaining on the device containing the file. +* `EPIPE` - An attempt is made to write to a pipe or `FIFO` that is not open for reading by any process. A `SIGPIPE` +signal shall also be sent to the thread. The `fputc()` function may fail if: - * `ENOMEM` - Insufficient storage space is available. +* `ENOMEM` - Insufficient storage space is available. - * `ENXIO` - A request was made of a nonexistent device, or the request was outside the capabilities of the device. +* `ENXIO` - A request was made of a nonexistent device, or the request was outside the capabilities of the device. ## Tests @@ -69,6 +69,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fputs.part-impl.md b/libc/functions/f/fputs.part-impl.md index 388b2541..c69915a8 100644 --- a/libc/functions/f/fputs.part-impl.md +++ b/libc/functions/f/fputs.part-impl.md @@ -1,32 +1,35 @@ -# Synopsis -`#include `
+# Synopsis -` int fputs(const char *restrict s, FILE *restrict stream);`
+`#include ` + +`int fputs(const char *restrict s, FILE *restrict stream);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The `fputs()` function shall write the null-terminated string pointed to by s to the stream pointed to by -stream. The terminating null byte shall not be written. -The -last data modification and last file status change timestamps of the file shall be marked for update between the successful -execution of `fputs()` and the next successful completion of a call to `fflush()` -or `fclose()` on the same stream or a call to `exit()` or `abort()`. +The `fputs()` function shall write the null-terminated string pointed to by s to the stream pointed to by stream. The +terminating null byte shall not be written. +The last data modification and last file status change timestamps of the file shall be marked for update between the +successful execution of `fputs()` and the next successful completion of a call to `fflush()` or `fclose()` on the same +stream or a call to `exit()` or `abort()`. ## Return value -Upon successful completion, `fputs()` shall return a non-negative number. Otherwise, it shall return `EOF`, set an error indicator for the stream and set `errno` to indicate the error. +Upon successful completion, `fputs()` shall return a non-negative number. Otherwise, it shall return `EOF`, set an error +indicator for the stream and set `errno` to indicate the error. ## Errors Refer to [fputc](fputc.part-impl.md) - ## Tests Tested in [test-libc](https://github.com/phoenix-rtos/phoenix-rtos-tests/tree/master/libc). @@ -35,6 +38,7 @@ Tested in [test-libc](https://github.com/phoenix-rtos/phoenix-rtos-tests/tree/ma None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fread.part-impl.md b/libc/functions/f/fread.part-impl.md index 4acb141f..f2976cae 100644 --- a/libc/functions/f/fread.part-impl.md +++ b/libc/functions/f/fread.part-impl.md @@ -1,28 +1,37 @@ -# Synopsis -`#include `
+# Synopsis -` size_t fread(void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);`
+`#include ` + +`size_t fread(void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description -The `fread()` function shall read into the array pointed to by _ptr_ up to _nitems_ elements whose size is -specified by _size_ in bytes, from the stream pointed to by _stream_. For each object, size calls shall be made to -the `fgetc()` function and the results stored, in the order read, in an array of -unsigned char exactly overlaying the object. The file position indicator for the stream (if defined) shall be advanced by -the number of bytes successfully read. If an error occurs, the resulting value of the file position indicator for the stream is -unspecified. If a partial element is read, its value is unspecified. -The -`fread()` function may mark the last data access timestamp of the file associated with _stream_ for update. The last data -access timestamp shall be marked for update by the first successful execution of `fgetc()`, `fgets()`, `fread()`, `fscanf()`, `getc()`, `getchar()`, `getdelim()`, `getline()`, `gets()`, or `scanf()` using _stream_ that returns data not supplied by a prior call to `ungetc()`. +The `fread()` function shall read into the array pointed to by _ptr_ up to _nitems_ elements whose size is specified by +_size_ in bytes, from the stream pointed to by _stream_. For each object, size calls shall be made to the `fgetc()` +function and the results stored, in the order read, in an array of unsigned char exactly overlaying the object. The +file position indicator for the stream (if defined) shall be advanced by the number of bytes successfully read. If an +error occurs, the resulting value of the file position indicator for the stream is unspecified. If a partial element is +read, its value is unspecified. +The `fread()` function may mark the last data access timestamp of the file associated with _stream_ for update. The last +data access timestamp shall be marked for update by the first successful execution of `fgetc()`, `fgets()`, `fread()`, +`fscanf()`, `getc()`, `getchar()`, `getdelim()`, `getline()`, `gets()`, or `scanf()` using _stream_ that returns data +not supplied by a prior call to `ungetc()`. ## Return value -Upon successful completion, `fread()` shall return the number of elements successfully read which is less than _nitems_ only if a read error or end-of-file is encountered. If _size_ or _nitems_ is `0`, `fread()` shall return `0` and the contents of the array and the state of the stream remain unchanged. Otherwise, if a read error occurs, the error indicator for the stream shall be set and `errno` shall be set to indicate the error. +Upon successful completion, `fread()` shall return the number of elements successfully read which is less than _nitems_ +only if a read error or end-of-file is encountered. If _size_ or _nitems_ is `0`, `fread()` shall return `0` and the +contents of the array and the state of the stream remain unchanged. Otherwise, if a read error occurs, the error +indicator for the stream shall be set and `errno` shall be set to indicate the error. ## Errors @@ -36,6 +45,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/free.impl.md b/libc/functions/f/free.impl.md index 9041c0d4..9fcf91a7 100644 --- a/libc/functions/f/free.impl.md +++ b/libc/functions/f/free.impl.md @@ -1,25 +1,26 @@ -###Synopsis +# Synopsis `#include ` `void free(void *ptr);` -###Description +## Description -The function deallocates the memory previously allocated by a call to `calloc()`, `malloc()`, or `realloc()`. If ptr is a `NULL` pointer, no operation is performed. +The function deallocates the memory previously allocated by a call to `calloc()`, `malloc()`, or `realloc()`. If _ptr_ +is a `NULL` pointer, no operation is performed. Arguments: -ptr - the pointer to the allocated earlier memory. +_ptr_ - the pointer to the allocated earlier memory. -###Return value +## Return value None. -###Errors +## Errors No errors are defined. -###Implementation tasks +## Implementation tasks * None. diff --git a/libc/functions/f/freeaddrinfo.part-impl.md b/libc/functions/f/freeaddrinfo.part-impl.md index bdbef7fd..07c59cd7 100644 --- a/libc/functions/f/freeaddrinfo.part-impl.md +++ b/libc/functions/f/freeaddrinfo.part-impl.md @@ -1,167 +1,176 @@ -# Synopsis -`#include `
+# Synopsis -`#include `
+`#include ` -` void freeaddrinfo(struct addrinfo *ai);`
+`#include ` -` int getaddrinfo(const char *restrict nodename,`
-`        const char *restrict servname,`
-`        const struct addrinfo *restrict hints,`
-`        struct addrinfo **restrict res);`
+`void freeaddrinfo(struct addrinfo *ai);` + +`int getaddrinfo(const char *restrict nodename, const char *restrict servname, const struct addrinfo *restrict hints, +struct addrinfo **restrict res);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The `freeaddrinfo()` function shall free one or more addrinfo structures returned by `getaddrinfo()`, along -with any additional storage associated with those structures. If the `ai_next` field of the structure is not `null`, the entire +The `freeaddrinfo()` function shall free one or more addrinfo structures returned by `getaddrinfo()`, along with any +additional storage associated with those structures. If the `ai_next` field of the structure is not `null`, the entire list of structures shall be freed. The `freeaddrinfo()` function shall support the freeing of arbitrary sublists of an addrinfo list originally returned by `getaddrinfo()`. The `getaddrinfo()` function shall translate the name of a service location (for example, a host name) and/or a service -name and shall return a set of socket addresses and associated information to be used in creating a socket with which to address -the specified service. +name and shall return a set of socket addresses and associated information to be used in creating a socket with which to +address +the specified service. Note: -In many cases it is implemented by the Domain Name System, as documented in `RFC 1034`, `RFC 1035`, and -`RFC 1886`. - +In many cases it is implemented by the Domain Name System, as documented in `RFC 1034`, `RFC 1035`, and `RFC 1886`. The `freeaddrinfo()` and `getaddrinfo()` functions shall be thread-safe. The _nodename_ and _servname_ arguments are either `null` pointers or pointers to `null`-terminated strings. One or both of these two arguments shall be supplied by the application as a non-`null` pointer. -The format of a valid name depends on the address family or families. If a specific family is not given and the name could be -interpreted as valid within multiple supported families, the implementation shall attempt to resolve the name in all supported -families and, in absence of errors, one or more results shall be returned. +The format of a valid name depends on the address family or families. If a specific family is not given and the name +could be interpreted as valid within multiple supported families, the implementation shall attempt to resolve the name +in all supported families and, in absence of errors, one or more results shall be returned. -If the _nodename_ argument is not `null`, it can be a descriptive name or can be an address string. If the specified address -family is `AF_INET,` [IP6]  `AF_INET6,` or `AF_UNSPEC,` valid -descriptive names include host names. If the specified address family is `AF_INET` or `AF_UNSPEC,` address strings using Internet -standard dot notation as specified in `inet_addr` are valid. -If the specified address family is `AF_INET6` or `AF_UNSPEC,` standard IPv6 text forms described in `inet_ntop` are valid. -If _nodename_ is not `null`, the requested service location is named by _nodename_; otherwise, the requested service -location is local to the caller. +If the _nodename_ argument is not `null`, it can be a descriptive name or can be an address string. If the specified +address family is `AF_INET,` [IP6]  `AF_INET6,` or `AF_UNSPEC,` valid descriptive names include host names. If the +specified address family is `AF_INET` or `AF_UNSPEC,` address strings using Internet standard dot notation as specified +in `inet_addr` are valid. If the specified address family is `AF_INET6` or `AF_UNSPEC,` standard IPv6 text forms +described in `inet_ntop` are valid. If _nodename_ is not `null`, the requested service location is named by _nodename_; +otherwise, the requested service location is local to the caller. -If _servname_ is `null`, the call shall return network-level addresses for the specified _nodename_. If _servname_ -is not `null`, it is a `null`-terminated character string identifying the requested service. This can be either a descriptive name or a -numeric representation suitable for use with the address family or families. If the specified address family is `AF_INET,` -`AF_INET6,` or `AF_UNSPEC,` the service can be specified as a -string specifying a decimal port number. +If _servname_ is `null`, the call shall return network-level addresses for the specified _nodename_. If _servname_ is +not `null`, it is a `null`-terminated character string identifying the requested service. This can be either a +descriptive name or a numeric representation suitable for use with the address family or families. If the specified +address family is `AF_INET,` `AF_INET6,` or `AF_UNSPEC,` the service can be specified as a string specifying a decimal +port number. If the _hints_ argument is not `null`, it refers to a structure containing input values that directs the operation by -providing options and by limiting the returned information to a specific socket type, address family, and/or protocol, as described -below. The application shall ensure that each of the `ai_addrlen,` `ai_addr,` `ai_canonname,` and `ai_next` -members, as well as each of the non-standard additional members, if any, of this _hints_ structure is initialized. If any of -these members has a value other than the value that would result from default initialization, the behavior is -implementation-defined. A value of `AF_UNSPEC` for `ai_family` means that the caller shall accept any address family. A value of -zero for `ai_socktype` means that the caller shall accept any socket type. A value of zero for `ai_protocol` means that -the caller shall accept any protocol. If _hints_ is a `null` pointer, the behavior shall be as if it referred to a structure -containing the value zero for the `ai_flags,` `ai_socktype,` and `ai_protocol` fields, and `AF_UNSPEC` for the -`ai_family` field. +providing options and by limiting the returned information to a specific socket type, address family, and/or protocol, +as described below. The application shall ensure that each of the `ai_addrlen,` `ai_addr,` `ai_canonname,` and `ai_next` +members, as well as each of the non-standard additional members, if any, of this _hints_ structure is initialized. If +any of these members has a value other than the value that would result from default initialization, the behavior is +implementation-defined. A value of `AF_UNSPEC` for `ai_family` means that the caller shall accept any address family. + A value of zero for `ai_socktype` means that the caller shall accept any socket type. A value of zero for `ai_protocol` + means that the caller shall accept any protocol. If _hints_ is a `null` pointer, the behavior shall be as if it + referred to a structure containing the value zero for the `ai_flags,` `ai_socktype,` and `ai_protocol` fields, and + `AF_UNSPEC` for the `ai_family` field. The `ai_flags` field to which the _hints_ parameter points shall be set to zero or be the bitwise-inclusive OR of one -or more of the values `AI_PASSIVE,` `AI_CANONNAME,` `AI_NUMERICHOST,` `AI_NUMERICSERV,` `AI_V4MAPPED,` `AI_ALL,` and `AI_ADDRCONFIG`. - -If the `AI_PASSIVE` flag is specified, the returned address information shall be suitable for use in binding a socket for -accepting incoming connections for the specified service. In this case, if the _nodename_ argument is `null`, then the IP -address portion of the socket address structure shall be set to `INADDR_ANY` for an IPv4 address or `IN6ADDR_ANY_INIT` for an IPv6 -address. If the `AI_PASSIVE` flag is not specified, the returned address information shall be suitable for a call to `connect()` (for a connection-mode protocol) or for a call to `connect()`, `sendto()`, or `sendmsg()` (for a connectionless protocol). In this case, if the _nodename_ argument is -`null`, then the IP address portion of the socket address structure shall be set to the loopback address. The `AI_PASSIVE` flag shall -be ignored if the _nodename_ argument is not `null`. - -If the `AI_CANONNAME` flag is specified and the _nodename_ argument is not `null`, the function shall attempt to determine the -canonical name corresponding to _nodename_ (for example, if _nodename_ is an alias or shorthand notation for a complete -name). +or more of the values `AI_PASSIVE,` `AI_CANONNAME,` `AI_NUMERICHOST,` `AI_NUMERICSERV,` `AI_V4MAPPED,` `AI_ALL,` and +`AI_ADDRCONFIG`. + +If the `AI_PASSIVE` flag is specified, the returned address information shall be suitable for use in binding a socket +for accepting incoming connections for the specified service. In this case, if the _nodename_ argument is `null`, then +the IP address portion of the socket address structure shall be set to `INADDR_ANY` for an IPv4 address or +`IN6ADDR_ANY_INIT` for an IPv6 address. If the `AI_PASSIVE` flag is not specified, the returned address information +shall be suitable for a call to `connect()` (for a connection-mode protocol) or for a call to `connect()`, `sendto()`, +or `sendmsg()` (for a connectionless protocol). In this case, if the _nodename_ argument is `null`, then the IP address +portion of the socket address structure shall be set to the loopback address. The `AI_PASSIVE` flag shall be ignored if +the _nodename_ argument is not `null`. + +If the `AI_CANONNAME` flag is specified and the _nodename_ argument is not `null`, the function shall attempt to +determine the canonical name corresponding to _nodename_ (for example, if _nodename_ is an alias or shorthand notation +for a complete name). Note: -Since different implementations use different conceptual models, the terms ``canonical name'' and ``alias'' cannot be precisely -defined for the general case. However, Domain Name System implementations are expected to interpret them as they are used in -`RFC 1034`. +Since different implementations use different conceptual models, the terms canonical name '' and alias '' cannot be +precisely defined for the general case. However, Domain Name System implementations are expected to interpret them as +they are used in `RFC 1034`. A numeric host address string is not a `name`, and thus does not have a `canonical name` form, no address to host name translation is performed. See below for handling of the case where a canonical name cannot be obtained. +If the `AI_NUMERICHOST` flag is specified, then a non-`null` _nodename_ string supplied shall be a numeric host address +string. - -If the `AI_NUMERICHOST` flag is specified, then a non-`null` _nodename_ string supplied shall be a numeric host address string. - -Otherwise, an ``EAI_NONAME`` error is returned. This flag shall prevent any type of name resolution service (for example, the DNS) -from being invoked. +Otherwise, an ``EAI_NONAME`` error is returned. This flag shall prevent any type of name resolution service +(for example, the DNS) from being invoked. If the `AI_NUMERICSERV` flag is specified, then a non-`null` _servname_ string supplied shall be a numeric port string. -Otherwise, an ``EAI_NONAME`` error shall be returned. This flag shall prevent any type of name resolution service (for example, NIS+) -from being invoked. -By default, with an `ai_family` of `AF_INET6,` `getaddrinfo()` shall return only IPv6 addresses. If the `AI_V4MAPPED` flag is -specified along with an `ai_family` of `AF_INET6,` then `getaddrinfo()` shall return IPv4-mapped IPv6 addresses on finding -no matching IPv6 addresses. The `AI_V4MAPPED` flag shall be ignored unless `ai_family` equals `AF_INET6`. If the `AI_ALL` flag is -used with the `AI_V4MAPPED` flag, then `getaddrinfo()` shall return all matching IPv6 and IPv4 addresses. The `AI_ALL` flag -without the `AI_V4MAPPED` flag shall be ignored. -If the `AI_ADDRCONFIG` flag is specified, IPv4 addresses shall be returned only if an IPv4 address is configured on the local -system, and IPv6 addresses shall be returned only if an IPv6 address is configured on the local system. -The `ai_socktype` field to which argument _hints_ points specifies the socket type for the service, as defined in socket. If a specific socket type is not given (for example, a value of zero) and the -service name could be interpreted as valid with multiple supported socket types, the implementation shall attempt to resolve the -service name for all supported socket types and, in the absence of errors, all possible results shall be returned. A non-zero -socket type value shall limit the returned information to values with the specified socket type. +Otherwise, an ``EAI_NONAME`` error shall be returned. This flag shall prevent any type of name resolution service +(for example, NIS+) from being invoked. + +By default, with an `ai_family` of `AF_INET6,` `getaddrinfo()` shall return only IPv6 addresses. If the `AI_V4MAPPED` +flag is specified along with an `ai_family` of `AF_INET6,` then `getaddrinfo()` shall return IPv4-mapped IPv6 addresses +on finding no matching IPv6 addresses. The `AI_V4MAPPED` flag shall be ignored unless `ai_family` equals `AF_INET6`. If +the `AI_ALL` flag is used with the `AI_V4MAPPED` flag, then `getaddrinfo()` shall return all matching IPv6 and IPv4 +addresses. The `AI_ALL` flag without the `AI_V4MAPPED` flag shall be ignored. +If the `AI_ADDRCONFIG` flag is specified, IPv4 addresses shall be returned only if an IPv4 address is configured on the +local system, and IPv6 addresses shall be returned only if an IPv6 address is configured on the local system. +The `ai_socktype` field to which argument _hints_ points specifies the socket type for the service, as defined in +socket. If a specific socket type is not given (for example, a value of zero) and the service name could be interpreted +as valid with multiple supported socket types, the implementation shall attempt to resolve the service name for all +supported socket types and, in the absence of errors, all possible results shall be returned. A non-zero socket type +value shall limit the returned information to values with the specified socket type. If the `ai_family` field to which _hints_ points has the value `AF_UNSPEC,` addresses shall be returned for use with any address family that can be used with the specified _nodename_ and/or _servname_. Otherwise, addresses shall be returned for use only with the specified address family. If `ai_family` is not `AF_UNSPEC` and `ai_protocol` is not zero, then -addresses shall be returned for use only with the specified address family and protocol; the value of `ai_protocol` shall be -interpreted as in a call to the `socket()` function with the corresponding values of -`ai_family` and `ai_protocol`. - +addresses shall be returned for use only with the specified address family and protocol; the value of `ai_protocol` +shall be interpreted as in a call to the `socket()` function with the corresponding values of `ai_family` and +`ai_protocol`. ## Return value -A zero return value for `getaddrinfo()` indicates successful completion, a non-zero return value indicates failure. The possible values for the failures are listed in the `ERRORS` section. +A zero return value for `getaddrinfo()` indicates successful completion, a non-zero return value indicates failure. The +possible values for the failures are listed in the `ERRORS` section. + +Upon successful return of `getaddrinfo()`, the location to which _res_ points shall refer to a linked list of `addrinfo` +structures, each of which shall specify a socket address and information for use in creating a socket with which to use +that socket address. The list shall include at least one addrinfo structure. The `ai_next` field of each structure +contains a pointer to the next structure on the list, or a `null` pointer if it is the last structure on the list. +Each structure on the list shall include values for use with a call to the `socket()` function, and a socket address +for use with the `connect()` function or, if the `AI_PASSIVE` flag was specified, for use with the `bind()` function. +The fields `ai_family`, `ai_socktype`, and `ai_protocol` shall be usable as the arguments to the `socket()` function to +create a socket suitable for use with the returned address. The fields `ai_addr` and `ai_addrlen` are usable as the +arguments to the `connect()` or `bind()` functions with such a socket, according to the `AI_PASSIVE` flag. -Upon successful return of `getaddrinfo()`, the location to which _res_ points shall refer to a linked list of `addrinfo` structures, each of which shall specify a socket address and information for use in creating a socket with which to use that socket address. The list shall include at least one addrinfo structure. The `ai_next` field of each structure contains a pointer to the next structure on the list, or a `null` pointer if it is the last structure on the list. Each structure on the list shall include values for use with a call to the `socket()` function, and a socket address for use with the `connect()` function or, if the `AI_PASSIVE` flag was specified, for use with the `bind()` function. The fields `ai_family`, `ai_socktype`, and `ai_protocol` shall be usable as the arguments to the `socket()` function to create a socket suitable for use with the returned address. The fields `ai_addr` and `ai_addrlen` are usable as the arguments to the `connect()` or `bind()` functions with such a socket, according to the `AI_PASSIVE` flag. +If _nodename_ is not `null`, and if requested by the `AI_CANONNAME` flag, the ai_canonname field of the first returned +`addrinfo` structure shall point to a `null`-terminated string containing the canonical name corresponding to the input +_nodename_, if the canonical name is not available, then `ai_canonname` shall refer to the _nodename_ argument or a +string with the same contents. The contents of the ai_flags field of the returned structures are undefined. -If _nodename_ is not `null`, and if requested by the `AI_CANONNAME` flag, the ai_canonname field of the first returned `addrinfo` structure shall point to a `null`-terminated string containing the canonical name corresponding to the input _nodename_, if the canonical name is not available, then `ai_canonname` shall refer to the _nodename_ argument or a string with the same contents. The contents of the ai_flags field of the returned structures are undefined. +All fields in socket address structures returned by `getaddrinfo()` that are not filled in through an explicit argument +(for example, `sin6_flowinfo`) shall be set to zero. -All fields in socket address structures returned by `getaddrinfo()` that are not filled in through an explicit argument (for example, `sin6_flowinfo`) shall be set to zero. Note: This makes it easier to compare socket address structures. ## Errors - The `getaddrinfo()` function shall fail and return the corresponding error value if: +* `EAI_AGAIN` - The name could not be resolved at this time. Future attempts may succeed. - * `EAI_AGAIN` - The name could not be resolved at this time. Future attempts may succeed. -`EAI_BADFLAGS` +* `EAI_BADFLAGS` - The flags parameter had an invalid value. -The flags parameter had an invalid value. +* `EAI_FAIL` - A non-recoverable error occurred when attempting to resolve the name. - * `EAI_FAIL` - A non-recoverable error occurred when attempting to resolve the name. +* `EAI_FAMILY` - The address family was not recognized. - * `EAI_FAMILY` - The address family was not recognized. +* `EAI_MEMORY` - There was a memory allocation failure when trying to allocate storage for the return value. - * `EAI_MEMORY` - There was a memory allocation failure when trying to allocate storage for the return value. - - * `EAI_NONAME` - The name does not resolve for the supplied parameters. +* `EAI_NONAME` - The name does not resolve for the supplied parameters. Neither _nodename_ nor _servname_ were supplied. At least one of these shall be supplied. - - * `EAI_SERVICE` - The service passed was not recognized for the specified socket type. +* `EAI_SERVICE` - The service passed was not recognized for the specified socket type. `EAI_SOCKTYPE` The intended socket type was not recognized. - * `EAI_SYSTEM` - A system error occurred, the error code can be found in `errno`. - - - - +* `EAI_SYSTEM` - A system error occurred, the error code can be found in `errno`. ## Tests @@ -171,6 +180,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/freopen.part-impl.md b/libc/functions/f/freopen.part-impl.md index db0cf98c..145749df 100644 --- a/libc/functions/f/freopen.part-impl.md +++ b/libc/functions/f/freopen.part-impl.md @@ -1,20 +1,23 @@ -# Synopsis -`#include `
+# Synopsis -` FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream);`
+`#include ` +`FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The purpose is to open the stream. The `freopen()` function shall first attempt to flush the stream associated with _stream_ as if by a call to -`fflush(stream)`. Failure to flush the stream successfully shall be ignored. If _pathname_ is not a `null` pointer, -`freopen()` shall close any file descriptor associated with _stream_. Failure to close the file descriptor successfully -shall be ignored. The error and end-of-file indicators for the stream shall be cleared. +The purpose is to open the stream. The `freopen()` function shall first attempt to flush the stream associated with +_stream_ as if by a call to `fflush(stream)`. Failure to flush the stream successfully shall be ignored. If _pathname_ +is not a `null` pointer, `freopen()` shall close any file descriptor associated with _stream_. Failure to close the +file descriptor successfully shall be ignored. The error and end-of-file indicators for the stream shall be cleared. The `freopen()` function shall open the file whose _pathname_ is the string pointed to by _pathname_ and associate the stream pointed to by _stream_ with it. The _mode_ argument shall be used just as in `fopen()`. @@ -22,17 +25,16 @@ stream pointed to by _stream_ with it. The _mode_ argument shall be used just as The original stream shall be closed regardless of whether the subsequent open succeeds. If _pathname_ is a `null` pointer, the `freopen()` function shall attempt to change the mode of the stream to that -specified by _mode_, as if the name of the file currently associated with the stream had been used. In this case, the file -descriptor associated with the stream need not be closed if the call to `freopen()` succeeds. It is implementation-defined -which changes of _mode_ are permitted (if any), and under what circumstances. - -After a successful call to the `freopen()` function, the orientation of the stream shall be cleared, the encoding -rule shall be cleared, and the associated `mbstate_t` object -shall be set to describe an initial conversion state. -If -_pathname_ is not a `null` pointer, or if _pathname_ is a `null` pointer and the specified mode change necessitates the file -descriptor associated with the stream to be closed and reopened, the file descriptor associated with the reopened stream shall be -allocated and opened as if by a call to `open()` with the following flags: +specified by _mode_, as if the name of the file currently associated with the stream had been used. In this case, the +file descriptor associated with the stream need not be closed if the call to `freopen()` succeeds. It is +implementation-defined which changes of _mode_ are permitted (if any), and under what circumstances. + +After a successful call to the `freopen()` function, the orientation of the stream shall be cleared, the encoding rule +shall be cleared, and the associated `mbstate_t` object shall be set to describe an initial conversion state. + +If _pathname_ is not a `null` pointer, or if _pathname_ is a `null` pointer and the specified mode change necessitates +the file descriptor associated with the stream to be closed and reopened, the file descriptor associated with the +reopened stream shall be allocated and opened as if by a call to `open()` with the following flags: | `freopen()` Mode | `open()` Flags | |------------------------|-------------------------------| @@ -43,79 +45,75 @@ allocated and opened as if by a call to `open()` with the following flags: | `w+` or `wb+` or `w+b` | `O_RDWR\|O_CREAT\|O_TRUNC` | | `a+` or `ab+` or `a+b` | `O_RDWR\|O_CREAT\|O_APPEND` | - ## Return value - -Upon successful completion, `freopen()` shall return the value of _stream_. Otherwise, a `null` pointer shall be returned, and `errno` shall be set to indicate the error. - +Upon successful completion, `freopen()` shall return the value of _stream_. Otherwise, a `null` pointer shall be +returned, and `errno` shall be set to indicate the error. ## Errors - The `freopen()` function shall fail if: +* `EACCES` - Search permission is denied on a component of the path prefix, or the file exists and the permissions +specified by _mode_ are denied, or the file does not exist and write permission is denied for the parent directory of +the file to be created. - * `EACCES` - Search permission is denied on a component of the path prefix, or the file exists and the permissions specified by _mode_ are -denied, or the file does not exist and write permission is denied for the parent directory of the file to be created. - - * `EBADF` - The file descriptor underlying the stream is not a valid file descriptor when _pathname_ is a `null` pointer. - - * `EINTR` - A signal was caught during `freopen()`. +* `EBADF` - The file descriptor underlying the stream is not a valid file descriptor when _pathname_ is a `null` +pointer. - * `EISDIR` - The named file is a directory and _mode_ requires write access. +* `EINTR` - A signal was caught during `freopen()`. - * `ELOOP` - A loop exists in symbolic links encountered during resolution of the path argument. +* `EISDIR` - The named file is a directory and _mode_ requires write access. - * `EMFILE` - All file descriptors available to the process are currently open. +* `ELOOP` - A loop exists in symbolic links encountered during resolution of the path argument. - * `ENAMETOOLONG` - The length of a component of a _pathname_ is longer than `NAME_MAX`. +* `EMFILE` - All file descriptors available to the process are currently open. - * `ENFILE` - The maximum allowable number of files is currently open in the system. +* `ENAMETOOLONG` - The length of a component of a _pathname_ is longer than `NAME_MAX`. - * `ENOENT` - The _mode_ string begins with 'r' and a component of _pathname_ does not name an existing file, or _mode_ -begins with 'w' or 'a' and a component of the path prefix of _pathname_ does not name an existing file, or -_pathname_ is an empty string. -* `ENOENT` or `ENOTDIR` - The _pathname_ argument contains at least one non- character and ends with one or more trailing -characters. If _pathname_ without the trailing characters would name an existing file, an `ENOENT` error shall -not occur. +* `ENFILE` - The maximum allowable number of files is currently open in the system. - * `ENOSPC` - The directory or file system that would contain the new file cannot be expanded, the file does not exist, and it was to be created. +* `ENOENT` - The _mode_ string begins with 'r' and a component of _pathname_ does not name an existing file, or _mode_ +begins with 'w' or 'a' and a component of the path prefix of _pathname_ does not name an existing file, or _pathname_ +is an empty string. +* `ENOENT` or `ENOTDIR` - The _pathname_ argument contains at least one non- `/` character and ends with one or more +trailing `/` characters. If _pathname_ without the trailing `/` characters would name an existing file, an `ENOENT` +error shall not occur. - * `ENOTDIR` - A component of the path prefix names an existing file that is neither a directory nor a symbolic link to a directory, or the -_pathname_ argument contains at least one non- character and ends with one or more trailing -characters and the last _pathname_ component names an existing file that is neither a directory nor a symbolic link to a directory. +* `ENOSPC` - The directory or file system that would contain the new file cannot be expanded, the file does not exist, +and it was to be created. +* `ENOTDIR` - A component of the path prefix names an existing file that is neither a directory nor a symbolic link to a +directory, or the _pathname_ argument contains at least one non- `/` character and ends with one or more trailing `/` +characters and the last _pathname_ component names an existing file that is neither a directory nor a symbolic link to a +directory. - * `ENXIO` - The named file is a character special or block special file, and the device associated with this special file does not exist. +* `ENXIO` - The named file is a character special or block special file, and the device associated with this special +file does not exist. - * `EOVERFLOW` - The named file is a regular file and the size of the file cannot be represented correctly in an object of type `off_t`. +* `EOVERFLOW` - The named file is a regular file and the size of the file cannot be represented correctly in an object +of type `off_t`. - * `EROFS` - The named file resides on a read-only file system and _mode_ requires write access. +* `EROFS` - The named file resides on a read-only file system and _mode_ requires write access. The `freopen()` function may fail if: +* `EBADF` - The _mode_ with which the file descriptor underlying the stream was opened does not support the requested +mode when _pathname_ is a `null` pointer. - * `EBADF` - The _mode_ with which the file descriptor underlying the stream was opened does not support the requested mode when _pathname_ -is a `null` pointer. - - * `EINVAL` - The value of the _mode_ argument is not valid. - - * `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the path argument. +* `EINVAL` - The value of the _mode_ argument is not valid. - * `ENAMETOOLONG` - The length of a _pathname_ exceeds `PATH_MAX`, or _pathname_ resolution of a symbolic link produced an intermediate result with a -length that exceeds `PATH_MAX`. - - * `ENOMEM` - Insufficient storage space is available. - - * `ENXIO` - A request was made of a nonexistent device, or the request was outside the capabilities of the device. - - * `ETXTBSY` - The file is a pure procedure (shared text) file that is being executed and _mode_ requires write access. +* `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the path argument. +* `ENAMETOOLONG` - The length of a _pathname_ exceeds `PATH_MAX`, or _pathname_ resolution of a symbolic link produced +an intermediate result with a length that exceeds `PATH_MAX`. +* `ENOMEM` - Insufficient storage space is available. +* `ENXIO` - A request was made of a nonexistent device, or the request was outside the capabilities of the device. +* `ETXTBSY` - The file is a pure procedure (shared text) file that is being executed and _mode_ requires write access. ## Tests @@ -125,6 +123,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/frexp.part-impl.md b/libc/functions/f/frexp.part-impl.md index 834e7b0b..0064fb0c 100644 --- a/libc/functions/f/frexp.part-impl.md +++ b/libc/functions/f/frexp.part-impl.md @@ -1,39 +1,38 @@ -# Synopsis -`#include `
+# Synopsis -` double frexp(double num, int *exp);`
+`#include ` -` float frexpf(float num, int *exp);`
+`double frexp(double num, int *exp);` + +`float frexpf(float num, int *exp);` ## Status + Partially implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 -The purpose is to extract mantissa and exponent from a double precision number. These functions shall break a floating-point number _num_ into a normalized fraction and an integral power of 2. The -integer exponent shall be stored in the int object pointed to by _exp_. +## Description +The purpose is to extract mantissa and exponent from a double precision number. These functions shall break a +floating-point number _num_ into a normalized fraction and an integral power of 2. The integer exponent shall be +stored in the int object pointed to by _exp_. ## Return value +For finite arguments, these functions shall return the value `x`, such that `x` has a magnitude in the interval `[½,1)` +or `0`, and _num_ equals `x` times `2` raised to the power _*exp_. -For finite arguments, these functions shall return the value `x`, such that `x` has a magnitude in the interval `[½,1)` or `0`, and _num_ equals `x` times `2` raised to the power _*exp_. - -If _num_ is `NaN`, a `NaN` shall be returned, and the value of _*exp_ is unspecified. - -If _num_ is `±0`, `±0` shall be returned, and the value of _*exp_ shall be `0`. - -If _num_ is `±Inf`, _num_ shall be returned, and the value of _*exp_ is unspecified. - +* If _num_ is `NaN`, a `NaN` shall be returned, and the value of _*exp_ is unspecified. +* If _num_ is `±0`, `±0` shall be returned, and the value of _*exp_ shall be `0`. +* If _num_ is `±Inf`, _num_ shall be returned, and the value of _*exp_ is unspecified. ## Errors - No errors are defined. - ## Tests Untested @@ -42,6 +41,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fscanf.part-impl.md b/libc/functions/f/fscanf.part-impl.md index b6798763..4163bc09 100644 --- a/libc/functions/f/fscanf.part-impl.md +++ b/libc/functions/f/fscanf.part-impl.md @@ -1,263 +1,273 @@ -# Synopsis -`#include `
+# Synopsis -` int fscanf(FILE *restrict stream, const char *restrict format, ...);`
+`#include ` -` int scanf(const char *restrict format, ...);`
+`int fscanf(FILE *restrict stream, const char *restrict format, ...);` -` int sscanf(const char *restrict s, const char *restrict format, ...);`
+`int scanf(const char *restrict format, ...);` + +`int sscanf(const char *restrict s, const char *restrict format, ...);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description +The purpose is to convert formatted input. The `fscanf()` function shall read from the named input _stream_. The +`scanf()` function shall read from the standard input stream `stdin`. The `sscanf()` function shall read from the +string _s_. Each function reads bytes, interprets them according to a _format_, and stores the results in its arguments. +Each expects, as arguments, a control string format described below, and a set of pointer arguments indicating where the +converted input should be stored. The result is undefined if there are insufficient arguments for the _format_. If the +format is exhausted while arguments remain, the excess arguments shall be evaluated but otherwise ignored. -The purpose is to convert formatted input. The `fscanf()` function shall read from the named input _stream_. The `scanf()` function shall read from the -standard input stream `stdin`. The `sscanf()` function shall read from the string _s_. Each function reads bytes, -interprets them according to a _format_, and stores the results in its arguments. Each expects, as arguments, a control string -format described below, and a set of pointer arguments indicating where the converted input should be stored. The -result is undefined if there are insufficient arguments for the _format_. If the format is exhausted while arguments remain, the -excess arguments shall be evaluated but otherwise ignored. Conversions can be applied to the nth argument after the _format_ in the argument list, rather than to the next unused -argument. In this case, the conversion specifier character `%` (see below) is replaced by the sequence -`"%n$"`, where `n` is a decimal integer in the range `[1,NL_ARGMAX]`. This feature provides for the -definition of format strings that select arguments in an order appropriate to specific languages. In format strings containing the -`"%n$"` form of conversion specifications, it is unspecified whether numbered arguments in the argument list -can be referenced from the format string more than once. - -The _format_ can contain either form of a conversion specification-that is, `%` or -`"%n$"`-but the two forms cannot be mixed within a single format string. The only exception to this -is that `%%` or `%*` can be mixed with the `"%n$"` form. When numbered argument specifications -are used, specifying the Nth argument requires that all the leading arguments, from the first to the `(N-1)`th, are +argument. In this case, the conversion specifier character `%` (see below) is replaced by the sequence `"%n$"`, where +`n` is a decimal integer in the range `[1,NL_ARGMAX]`. This feature provides for the definition of format strings that +select arguments in an order appropriate to specific languages. In format strings containing the `"%n$"` form of +conversion specifications, it is unspecified whether numbered arguments in the argument list can be referenced from the +format string more than once. + +The _format_ can contain either form of a conversion specification-that is, `%` or `"%n$"`-but the two forms cannot be +mixed within a single format string. The only exception to this is that `%%` or `%*` can be mixed with the `"%n$"` form. +When numbered argument specifications are used, specifying the Nth argument requires that all the leading arguments, +from the first to the `(N-1)`th, are pointers. -The `fscanf()` function in all its forms shall allow detection of a language-dependent radix character in the input string. +The `fscanf()` function in all its forms shall allow detection of a language-dependent radix character in the input +string. -The radix character is defined in the current locale (category `LC_NUMERIC)`. In the POSIX locale, or in a locale where the -radix character is not defined, the radix character shall default to a ` ( '.' )`. -The _format_ is a character string, beginning and ending in its initial shift state, if any, composed of zero or more directives. +The radix character is defined in the current locale category `LC_NUMERIC)`. In the POSIX locale, or in a locale where +the radix character is not defined, the radix character shall default to a ` ( '.' )`. The _format_ is a +character string, beginning and ending in its initial shift state, if any, composed of zero or more directives. Each directive is composed of one of the following: one or more white-space characters ( ``, ``, -``, ``, or ``), an ordinary character (neither '`%`' nor a white-space -character), or a conversion specification. Each conversion specification is introduced by the character `'%'` or the -character sequence `"%n$"`,  after -which the following appear in sequence: - - +``, ``, or ``), an ordinary character (neither '`%`' nor a white-space character), +or a conversion specification. Each conversion specification is introduced by the character `'%'` or the character +sequence `"%n$"`,  after which the following appear in sequence: * An optional assignment-suppressing character `'*'`. - * An optional non-zero decimal integer that specifies the maximum field width. - -* An optional assignment-allocation character `'m'`. - +* An optional assignment-allocation character `'m'`. * An option length modifier that specifies the size of the receiving object. +* A conversion specifier character that specifies the type of conversion to be applied. The valid conversion specifiers +are described below. -* A conversion specifier character that specifies the type of conversion to be applied. The valid conversion specifiers are described below. +The `fscanf()` functions shall execute each directive of the _format_ in turn. If a directive fails, as detailed below, +the function shall return. Failures are described as input failures (due to the unavailability of input bytes) or +matching failures (due to inappropriate input). +A directive composed of one or more white-space characters shall be executed by reading input until no more valid input +can be read, or up to the first byte which is not a white-space character, which remains unread. -The `fscanf()` functions shall execute each directive of the _format_ in turn. If a directive fails, as detailed below, the -function shall return. Failures are described as input failures (due to the unavailability of input bytes) or matching failures -(due to inappropriate input). +A directive that is an ordinary character shall be executed as follows: the next byte shall be read from the input and +compared with the byte that comprises the directive, if the comparison shows that they are not equivalent, the directive +shall fail, and the differing and subsequent bytes shall remain unread. Similarly, if end-of-file, an encoding error, or +a read error prevents a character from being read, the directive shall fail. -A directive composed of one or more white-space characters shall be executed by reading input until no more valid input can be -read, or up to the first byte which is not a white-space character, which remains unread. +A directive that is a conversion specification defines a set of matching input sequences, as described below for each +conversion character. A conversion specification shall be executed in the following steps. -A directive that is an ordinary character shall be executed as follows: the next byte shall be read from the input and compared -with the byte that comprises the directive, if the comparison shows that they are not equivalent, the directive shall fail, and the -differing and subsequent bytes shall remain unread. Similarly, if end-of-file, an encoding error, or a read error prevents a -character from being read, the directive shall fail. - -A directive that is a conversion specification defines a set of matching input sequences, as described below for each conversion -character. A conversion specification shall be executed in the following steps. - -Input white-space characters (as specified by isspace) shall be skipped, unless -the conversion specification includes a `[`, `c`, `C`, or `n` conversion specifier. +Input white-space characters (as specified by isspace) shall be skipped, unless the conversion specification includes a +`[`, `c`, `C`, or `n` conversion specifier. An item shall be read from the input, unless the conversion specification includes an n conversion specifier. An input -item shall be defined as the longest sequence of input bytes (up to any specified maximum field width, which may be measured in -characters or bytes dependent on the conversion specifier) which is an initial subsequence of a matching sequence. The first byte, -if any, after the input item shall remain unread. If the length of the input item is `0`, the execution of the conversion -specification shall fail; this condition is a matching failure, unless end-of-file, an encoding error, or a read error prevented -input from the _stream_, in which case it is an input failure. - -Except in the case of a `%` conversion specifier, the input item (or, in the case of a `%n` conversion -specification, the count of input bytes) shall be converted to a type appropriate to the conversion character. If the input item is -not a matching sequence, the execution of the conversion specification fails; this condition is a matching failure. Unless -assignment suppression was indicated by a `'*'`, the result of the conversion shall be placed in the object pointed to by -the first argument following the _format_ argument that has not already received a conversion result if the conversion -specification is introduced by `%`, or in the nth argument if introduced by the character -sequence `"%n$"`. If this object does not -have an appropriate type, or if the result of the conversion cannot be represented in the space provided, the behavior is -undefined. -The `%c`, `%s`, and `%[` conversion specifiers shall accept an optional assignment-allocation character -`'m'`, which shall cause a memory buffer to be allocated to hold the string converted including a terminating `null` -character. In such a case, the argument corresponding to the conversion specifier should be a reference to a pointer variable that -will receive a pointer to the allocated buffer. The system shall allocate a buffer as if `malloc()` had been called. The application shall be responsible for freeing the memory after -usage. If there is insufficient memory to allocate a buffer, the function shall set `errno` to `ENOMEM` and a conversion error -shall result. If the function returns `EOF`, any memory successfully allocated for parameters using assignment-allocation character -`'m'` by this call shall be freed before the function returns. +item shall be defined as the longest sequence of input bytes (up to any specified maximum field width, which may be +measured in characters or bytes dependent on the conversion specifier) which is an initial subsequence of a matching +sequence. The first byte, if any, after the input item shall remain unread. If the length of the input item is `0`, +the execution of the conversion specification shall fail; this condition is a matching failure, unless end-of-file, +an encoding error, or a read error prevented input from the _stream_, in which case it is an input failure. + +Except in the case of a `%` conversion specifier, the input item (or, in the case of a `%n` conversion specification, +the count of input bytes) shall be converted to a type appropriate to the conversion character. If the input item is +not a matching sequence, the execution of the conversion specification fails; this condition is a matching failure. +Unless assignment suppression was indicated by a `'*'`, the result of the conversion shall be placed in the object +pointed to by the first argument following the _format_ argument that has not already received a conversion result +if the conversion specification is introduced by `%`, or in the nth argument if introduced by the character sequence +`"%n$"`. If this object does not have an appropriate type, or if the result of the conversion cannot be represented +in the space provided, the behavior is undefined. + +The `%c`, `%s`, and `%[` conversion specifiers shall accept an optional assignment-allocation character `'m'`, which +shall cause a memory buffer to be allocated to hold the string converted including a terminating `null` character. In +such a case, the argument corresponding to the conversion specifier should be a reference to a pointer variable that +will receive a pointer to the allocated buffer. The system shall allocate a buffer as if `malloc()` had been called. +The application shall be responsible for freeing the memory after usage. If there is insufficient memory to allocate +a buffer, the function shall set `errno` to `ENOMEM` and a conversion error shall result. If the function returns `EOF`, +any memory successfully allocated for parameters using assignment-allocation character `'m'` by this call shall be freed +before the function returns. The length modifiers and their meanings are: -* `hh` - Specifies that `a` following `d`, `i`, `o`, `u`, `x`, `X`, or `n` -conversion specifier applies to an argument with type pointer to `signed` `char` or `unsigned` `char`. +* `hh` - Specifies that `a` following `d`, `i`, `o`, `u`, `x`, `X`, or `n` conversion specifier applies to an argument +with type pointer to `signed` `char` or `unsigned` `char`. -* `h` - Specifies that a following `d`, `i`, `o`, `u`, `x`, `X`, or `n` -conversion specifier applies to an argument with type pointer to `short` or `unsigned` `short`. +* `h` - Specifies that a following `d`, `i`, `o`, `u`, `x`, `X`, or `n` conversion specifier applies to an argument with +type pointer to `short` or `unsigned` `short`. -* `l (ell)` - Specifies that a following `d`, `i`, `o`, `u`, `x`, `X`, or `n` -conversion specifier applies to an argument with type pointer to `long` or `unsigned` `long`, that a following a, -`A`, `e`, `E`, `f`, `F`, `g`, or `G` conversion specifier applies to an -argument with type pointer to `double`, or that a following `c`, `s`, or `[` conversion specifier -applies to an argument with type pointer to `wchar_t`. If the `'m'` assignment-allocation character is specified, -the conversion applies to an argument with the type pointer to a pointer to `wchar_t`. +* `l (ell)` - Specifies that a following `d`, `i`, `o`, `u`, `x`, `X`, or `n` conversion specifier applies to an +argument with type pointer to `long` or `unsigned` `long`, that a following a, `A`, `e`, `E`, `f`, `F`, `g`, or `G` +conversion specifier applies to an argument with type pointer to `double`, or that a following `c`, `s`, or `[` +conversion specifier applies to an argument with type pointer to `wchar_t`. If the `'m'` assignment-allocation character +is specified, the conversion applies to an argument with the type pointer to a pointer to `wchar_t`. -* `ll (ell-ell)` -Specifies that a following `d`, `i`, `o`, `u`, `x`, `X`, or `n` conversion -specifier applies to an argument with type pointer to `long` `long` or `unsigned` `long` `long`. +* `ll (ell-ell)` -Specifies that a following `d`, `i`, `o`, `u`, `x`, `X`, or `n` conversion specifier applies to an +argument with type pointer to `long` `long` or `unsigned` `long` `long`. -* `j` - Specifies that a following `d`, `i`, `o`, `u`, `x`, `X`, or `n` -conversion specifier applies to an argument with type pointer to `intmax_t` or `uintmax_t`. +* `j` - Specifies that a following `d`, `i`, `o`, `u`, `x`, `X`, or `n` conversion specifier applies to an argument with +type pointer to `intmax_t` or `uintmax_t`. -* `z` - Specifies that a following `d`, `i`, `o`, `u`, `x`, `X`, or `n` -conversion specifier applies to an argument with type pointer to `size_t` or the corresponding signed integer type. +* `z` - Specifies that a following `d`, `i`, `o`, `u`, `x`, `X`, or `n` conversion specifier applies to an argument with +type pointer to `size_t` or the corresponding signed integer type. -* `t` - Specifies that a following `d`, `i`, `o`, `u`, x, `X`, or `n` -conversion specifier applies to an argument with type pointer to `ptrdiff_t` or the corresponding `unsigned` type. +* `t` - Specifies that a following `d`, `i`, `o`, `u`, x, `X`, or `n` conversion specifier applies to an argument with +type pointer to `ptrdiff_t` or the corresponding `unsigned` type. -* `L` - Specifies that a following `a`, `A`, `e`, `E`, `f`, `F`, `g`, or -`G` conversion specifier applies to an argument with type pointer to `long` `double`. +* `L` - Specifies that a following `a`, `A`, `e`, `E`, `f`, `F`, `g`, or `G` conversion specifier applies to an argument +with type pointer to `long` `double`. If a length modifier appears with any conversion specifier other than as specified above, the behavior is undefined. The following conversion specifiers are valid: -* `d` - Matches an optionally signed decimal integer, whose format is the same as expected for the subject sequence of `strtol()` with the value `10` for the base argument. In the absence of a size modifier, the application shall ensure that the corresponding argument is a pointer to `int`. +* `d` - Matches an optionally signed decimal integer, whose format is the same as expected for the subject sequence of +`strtol()` with the value `10` for the base argument. In the absence of a size modifier, the application shall ensure +that the corresponding argument is a pointer to `int`. -* `i` - Matches an optionally signed integer, whose format is the same as expected for the subject sequence of `strtol()` with `0` for the base argument. In the absence of a size modifier, the application shall ensure that the corresponding argument is a pointer to `int`. +* `i` - Matches an optionally signed integer, whose format is the same as expected for the subject sequence of +`strtol()` with `0` for the base argument. In the absence of a size modifier, the application shall ensure that the +corresponding argument is a pointer to `int`. -* `o` - Matches an optionally signed octal integer, whose format is the same as expected for the subject sequence of `strtoul()` with the value `8` for the base argument. In the absence of a size modifier, -the application shall ensure that the corresponding argument is a pointer to `unsigned`. +* `o` - Matches an optionally signed octal integer, whose format is the same as expected for the subject sequence of +`strtoul()` with the value `8` for the base argument. In the absence of a size modifier, the application shall ensure +that the corresponding argument is a pointer to `unsigned`. -* `u` - Matches an optionally signed decimal integer, whose format is the same as expected for the subject sequence of `strtoul()` with the value `10` for the base argument. In the absence of a size modifier, -the application shall ensure that the corresponding argument is a pointer to `unsigned`. +* `u` - Matches an optionally signed decimal integer, whose format is the same as expected for the subject sequence of +`strtoul()` with the value `10` for the base argument. In the absence of a size modifier, the application shall ensure +that the corresponding argument is a pointer to `unsigned`. -* `x` - Matches an optionally signed hexadecimal integer, whose format is the same as expected for the subject sequence of `strtoul()` with the value `16` for the base argument. In the absence of a size modifier, -the application shall ensure that the corresponding argument is a pointer to `unsigned`. +* `x` - Matches an optionally signed hexadecimal integer, whose format is the same as expected for the subject sequence +of `strtoul()` with the value `16` for the base argument. In the absence of a size modifier, the application shall +ensure that the corresponding argument is a pointer to `unsigned`. -* `a`, `e`, `f`, `g` - Matches an optionally signed floating-point number, infinity, or `NaN`, whose format is the same as expected for the subject sequence -of `strtod()`. In the absence of a size modifier, the application shall ensure that the -corresponding argument is a pointer to float. If the `fprintf()` family of functions generates character string representations -for infinity and `NaN` (a symbolic entity encoded in floating-point format) to support `IEEE Std 754-1985`, the `fscanf()` family of functions shall recognize them as input. +* `a`, `e`, `f`, `g` - Matches an optionally signed floating-point number, infinity, or `NaN`, whose format is the same +as expected for the subject sequence of `strtod()`. In the absence of a size modifier, the application shall ensure that +the corresponding argument is a pointer to float. If the `fprintf()` family of functions generates character string +representations for infinity and `NaN` (a symbolic entity encoded in floating-point format) to support +`IEEE Std 754-1985`, the `fscanf()` family of functions shall recognize them as input. + +* `s` - Matches a sequence of bytes that are not white-space characters. If the `'m'` assignment-allocation character is +not specified, the application shall ensure that the corresponding argument is a pointer to the initial byte of an array +of `char`, `signed` `char`, or `unsigned` `char` large enough to accept the sequence and a terminating `null` character +code, which shall be added automatically.  Otherwise, the application shall ensure that the corresponding argument is +a pointer to a pointer to a `char`. -* `s` - Matches a sequence of bytes that are not white-space characters. If the `'m'` assignment-allocation character is not -specified, the application shall ensure that the corresponding argument is a pointer to the initial byte of an array of -`char`, `signed` `char`, or `unsigned` `char` large enough to accept the sequence and a terminating `null` character code, -which shall be added automatically.  Otherwise, the application shall ensure that the corresponding argument is a pointer to a -pointer to a `char`. -If an `l (ell)` qualifier is present, the input is a sequence of characters that begins in the initial shift state. Each -character shall be converted to a wide character as if by a call to the `mbrtowc()` -function, with the conversion state described by an `mbstate_t` object initialized to zero before the first character is -converted. If the `'m'` assignment-allocation character is not specified, the application shall ensure that the -corresponding argument is a pointer to an array of `wchar_t` large enough to accept the sequence and the terminating null wide -character, which shall be added automatically. Otherwise, the application shall ensure that the corresponding -argument is a pointer to a pointer to a `wchar_t`. - -* `[` - Matches a non-empty sequence of bytes from a set of expected bytes (the scanset). The normal skip over white-space -characters shall be suppressed in this case. If the `'m'` assignment-allocation character is not specified, the application -shall ensure that the corresponding argument is a pointer to the initial byte of an array of `char`, `signed` `char`, or -`unsigned` `char` large enough to accept the sequence and a terminating `null` byte, which shall be added automatically. -Otherwise, the application shall ensure that the corresponding argument is a pointer to a pointer to a `char`. If an `l (ell)` qualifier is present, the input is a sequence of characters that begins in the initial shift state. Each -character in the sequence shall be converted to a wide character as if by a call to the `mbrtowc()` function, with the conversion state described by an `mbstate_t` object -initialized to zero before the first character is converted. If the `'m'` assignment-allocation character is not specified, -the application shall ensure that the corresponding argument is a pointer to an array of `wchar_t` large enough to accept the -sequence and the terminating `null` wide character, which shall be added automatically. -Otherwise, the application shall ensure that the corresponding argument is a pointer to a pointer to a `wchar_t`. -The conversion specification includes all subsequent bytes in the format string up to and including the matching -`` `( ']' )`. The bytes between the square brackets (the scanlist) comprise the scanset, -unless the byte after the `` is a `` `( '^' )`, in which case the scanset contains -all bytes that do not appear in the scanlist between the `` and the ``. If the conversion -specification begins with `"[]"` or `"[^]"`, the `` is included in the scanlist and the -next `` is the matching `` that ends the conversion specification; otherwise, -the first `` is the one that ends the conversion specification. If a `'-'` is in the scanlist and -is not the first character, nor the second where the first character is a `'^'`, nor the last character, the behavior is -implementation-defined. - -* `c` - Matches a sequence of bytes of the number specified by the field width (`1` if no field width is present in the conversion -specification). No `null` byte is added. The normal skip over white-space characters shall be suppressed in this case. If the -`'m'` assignment-allocation character is not specified, the application shall ensure that the corresponding argument is a -pointer to the initial byte of an array of `char`, `signed` `char`, or `unsigned` `char` large enough to accept the -sequence.  Otherwise, the application shall ensure that the corresponding argument is a pointer to a pointer to a `char`. -If an `l (ell)` qualifier is present, the input shall be a sequence of characters that begins in the initial shift state. Each character in the sequence is converted to a wide character as if by a call to the `mbrtowc()` function, with the conversion state described by an `mbstate_t` object -initialized to zero before the first character is converted. No `null` wide character is added. If the `'m'` -assignment-allocation character is not specified, the application shall ensure that the corresponding argument is a pointer to an -array of `wchar_t` large enough to accept the resulting sequence of wide characters.  Otherwise, the -application shall ensure that the corresponding argument is a pointer to a pointer to a `wchar_t`. - -* `p` - Matches an implementation-defined set of sequences, which shall be the same as the set of sequences that is produced by the -`%p` conversion specification of the corresponding `fprintf()` functions. The -application shall ensure that the corresponding argument is a pointer to a pointer to void. The interpretation of the input -item is implementation-defined. If the input item is a value converted earlier during the same program execution, the pointer that -results shall compare equal to that value; otherwise, the behavior of the %p conversion specification is undefined. -* `n` - No input is consumed. The application shall ensure that the corresponding argument is a pointer to the integer into which shall -be written the number of bytes read from the input so far by this call to the `fscanf()` functions. Execution of a `%n` -conversion specification shall not increment the assignment count returned at the completion of execution of the function. No -argument shall be converted, but one shall be consumed. If the conversion specification includes an assignment-suppressing -character or a field width, the behavior is undefined. - -* `C` - Equivalent to `lc`. - -* `S` - Equivalent to `ls`. - -* `%` - Matches a single `'%'` character; no conversion or assignment occurs. The complete conversion specification shall be `%%`. +character shall be converted to a wide character as if by a call to the `mbrtowc()` function, with the conversion state +described by an `mbstate_t` object initialized to zero before the first character is converted. If the `'m'` +assignment-allocation character is not specified, the application shall ensure that the corresponding argument is a +pointer to an array of `wchar_t` large enough to accept the sequence and the terminating null wide character, which +shall be added automatically. Otherwise, the application shall ensure that the corresponding argument is a pointer +to a pointer to a `wchar_t`. + +* `[` - Matches a non-empty sequence of bytes from a set of expected bytes (the scanset). The normal skip over +white-space characters shall be suppressed in this case. If the `'m'` assignment-allocation character is not specified, +the application shall ensure that the corresponding argument is a pointer to the initial byte of an array of `char`, +`signed` `char`, or `unsigned` `char` large enough to accept the sequence and a terminating `null` byte, which shall be +added automatically. Otherwise, the application shall ensure that the corresponding argument is a pointer to a pointer +to a `char`. If an `l (ell)` qualifier is present, the input is a sequence of characters that begins in the initial +shift state. Each character in the sequence shall be converted to a wide character as if by a call to the `mbrtowc()` +function, with the conversion state described by an `mbstate_t` object initialized to zero before the first character +is converted. If the `'m'` assignment-allocation character is not specified, the application shall ensure that the +corresponding argument is a pointer to an array of `wchar_t` large enough to accept the sequence and the terminating +`null` wide character, which shall be added automatically. Otherwise, the application shall ensure that the +corresponding argument is a pointer to a pointer to a `wchar_t`. The conversion specification includes all subsequent +bytes in the format string up to and including the matching`]`. The bytes between the square brackets (the scanlist) +comprise the scanset, unless the byte after the `` is a `` `( '^' )`, in which case +the scanset contains all bytes that do not appear in the scanlist between the `` and the `]`. If the +conversion specification begins with `"[]"` or `"[^]"`, the `]` is included in the scanlist and the next `]` is the +matching `]` that ends the conversion specification; otherwise, the first `]` is the one that ends the conversion +specification. If a `'-'` is in the scanlist and is not the first character, nor the second where the first character +is a `'^'`, nor the last character, the behavior is implementation-defined. + +* `c` - Matches a sequence of bytes of the number specified by the field width (`1` if no field width is present in the +conversion specification). No `null` byte is added. The normal skip over white-space characters shall be suppressed in +this case. If the `'m'` assignment-allocation character is not specified, the application shall ensure that the +corresponding argument is a pointer to the initial byte of an array of `char`, `signed` `char`, or `unsigned` `char` +large enough to accept the sequence.  Otherwise, the application shall ensure that the corresponding argument is a +pointer to a pointer to a `char`. If an `l (ell)` qualifier is present, the input shall be a sequence of characters +that begins in the initial shift state. Each character in the sequence is converted to a wide character as if by a +call to the `mbrtowc()` function, with the conversion state described by an `mbstate_t` object initialized to zero +before the first character is converted. No `null` wide character is added. If the `'m'` assignment-allocation character +is not specified, the application shall ensure that the corresponding argument is a pointer to an array of `wchar_t` +large enough to accept the resulting sequence of wide characters.Otherwise, the application shall ensure that the +corresponding argument is a pointer to a pointer to a `wchar_t`. + +* `p` - Matches an implementation-defined set of sequences, which shall be the same as the set of sequences that is +produced by the `%p` conversion specification of the corresponding `fprintf()` functions. The application shall ensure +that the corresponding argument is a pointer to a pointer to void. The interpretation of the input item is +implementation-defined. If the input item is a value converted earlier during the same program execution, the pointer +that results shall compare equal to that value; otherwise, the behavior of the %p conversion specification is undefined. +* `n` - No input is consumed. The application shall ensure that the corresponding argument is a pointer to the integer +into which shall be written the number of bytes read from the input so far by this call to the `fscanf()` functions. +Execution of a `%n` conversion specification shall not increment the assignment count returned at the completion of +execution of the function. No argument shall be converted, but one shall be consumed. If the conversion specification +includes an assignment-suppressing character or a field width, the behavior is undefined. + +* `C` - Equivalent to `lc`. + +* `S` - Equivalent to `ls`. + +* `%` - Matches a single `'%'` character; no conversion or assignment occurs. The complete conversion specification +shall be `%%`. If a conversion specification is invalid, the behavior is undefined. -The conversion specifiers `A`, `E`, `F`, `G`, and `X` are also valid and shall be -equivalent to `a`, `e`, `f`, `g`, and `x`, respectively. +The conversion specifiers `A`, `E`, `F`, `G`, and `X` are also valid and shall be equivalent to `a`, `e`, `f`, `g`, +and `x`, respectively. -If end-of-file is encountered during input, conversion shall be terminated. If end-of-file occurs before any bytes matching the -current conversion specification (except for `%n` ) have been read (other than leading white-space characters, where -permitted), execution of the current conversion specification shall terminate with an input failure. Otherwise, unless execution of -the current conversion specification is terminated with a matching failure, execution of the following conversion specification (if -any) shall be terminated with an input failure. +If end-of-file is encountered during input, conversion shall be terminated. If end-of-file occurs before any bytes +matching the current conversion specification (except for `%n` ) have been read (other than leading white-space +characters, where permitted), execution of the current conversion specification shall terminate with an input failure. +Otherwise, unless execution of the current conversion specification is terminated with a matching failure, execution of +the following conversion specification (if any) shall be terminated with an input failure. Reaching the end of the string in `sscanf()` shall be equivalent to encountering end-of-file for `fscanf()`. -If conversion terminates on a conflicting input, the offending input is left unread in the input. Any trailing white space -(including `` characters) shall be left unread unless matched by a conversion specification. The success of literal -matches and suppressed assignments is only directly determinable via the `%n` conversion specification. -The -`fscanf()` and `scanf()` functions may mark the last data access timestamp of the file associated with _stream_ for -update. The last data access timestamp shall be marked for update by the first successful execution of `fgetc()`, `fgets()`, `fread()`, `getc()`, `getchar()`, `getdelim()`, `getline()`, `gets()`, `fscanf()`, or -`scanf()` using _stream_ that returns data not supplied by a prior call to `ungetc()`. +If conversion terminates on a conflicting input, the offending input is left unread in the input. Any trailing white +space (including `` characters) shall be left unread unless matched by a conversion specification. The success +of literal matches and suppressed assignments is only directly determinable via the `%n` conversion specification. +The `fscanf()` and `scanf()` functions may mark the last data access timestamp of the file associated with _stream_ for +update. The last data access timestamp shall be marked for update by the first successful execution of `fgetc()`, +`fgets()`, `fread()`, `getc()`, `getchar()`, `getdelim()`, `getline()`, `gets()`, `fscanf()`, or `scanf()` using +_stream_ that returns data not supplied by a prior call to `ungetc()`. ## Return value -Upon successful completion, these functions shall return the number of successfully matched and assigned input items, this number can be zero in the event of an early matching failure. If the input ends before the first conversion (if any) has completed, and without a matching failure having occurred, `EOF` shall be returned. If an error occurs before the first conversion (if any) has completed, and without a matching failure having occurred, `EOF` shall be returned and `errno` shall be set to indicate the error. If a read error occurs, the error indicator for the stream shall be set. - +Upon successful completion, these functions shall return the number of successfully matched and assigned input items, +this number can be zero in the event of an early matching failure. If the input ends before the first conversion +(if any) has completed, and without a matching failure having occurred, `EOF` shall be returned. If an error occurs +before the first conversion (if any) has completed, and without a matching failure having occurred, `EOF` shall be +returned and `errno` shall be set to indicate the error. If a read error occurs, the error indicator for the stream +shall be set. ## Errors - For the conditions under which the `fscanf()` functions fail and may fail, refer to `fgetc` or `fgetwc`. In addition, the `fscanf()` function shall fail if: +* `EILSEQ` - Input byte sequence does not form a valid character. - * `EILSEQ` - Input byte sequence does not form a valid character. - - * `ENOMEM` - Insufficient storage space is available. +* `ENOMEM` - Insufficient storage space is available. In addition, the `fscanf()` function may fail if: - - `EINVAL` - There are insufficient arguments. - - +* `EINVAL` - There are insufficient arguments. ## Tests @@ -267,6 +277,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fseek.part-impl.md b/libc/functions/f/fseek.part-impl.md index aa37a78f..f9c42c02 100644 --- a/libc/functions/f/fseek.part-impl.md +++ b/libc/functions/f/fseek.part-impl.md @@ -1,107 +1,104 @@ -# Synopsis -`#include `
+# Synopsis -` int fseek(FILE *stream, long offset, int whence);`
+`#include ` -`int fseeko(FILE *stream, off_t offset, int whence);`
+`int fseek(FILE *stream, long offset, int whence);` + +`int fseeko(FILE *stream, off_t offset, int whence);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The purpose is to reposition a file-position indicator in a stream. The `fseek()` function shall set the file-position indicator for the stream pointed to by _stream_. If a read or write -error occurs, the error indicator for the stream shall be set and `fseek()` fails. +The purpose is to reposition a file-position indicator in a stream. The `fseek()` function shall set the file-position +indicator for the stream pointed to by _stream_. If a read or write error occurs, the error indicator for the stream +shall be set and `fseek()` fails. The new position, measured in bytes from the beginning of the file, shall be obtained by adding _offset_ to the position -specified by _whence_. The specified point is the beginning of the file for `SEEK_SET,` the current value of the file-position -indicator for `SEEK_CUR,` or end-of-file for `SEEK_END`. +specified by _whence_. The specified point is the beginning of the file for `SEEK_SET,` the current value of the +file-position indicator for `SEEK_CUR,` or end-of-file for `SEEK_END`. If the stream is to be used with wide-character input/output functions, the application shall ensure that _offset_ is -either `0` or a value returned by an earlier call to `ftell()` on the same stream and -_whence_ is `SEEK_SET`. +either `0` or a value returned by an earlier call to `ftell()` on the same stream and _whence_ is `SEEK_SET`. -A successful call to `fseek()` shall clear the end-of-file indicator for the stream and undo any effects of `ungetc()` and `ungetwc()` on the same stream. +A successful call to `fseek()` shall clear the end-of-file indicator for the stream and undo any effects of `ungetc()` +and `ungetwc()` on the same stream. -After an `fseek()` call, the next operation on an update stream may be either input or output. -If the most recent operation, other than `ftell()`, on a given stream is `fflush()`, the file offset in the underlying open file description shall be adjusted to -reflect the location specified by `fseek()`. +After an `fseek()` call, the next operation on an update stream may be either input or output. If the most recent +operation, other than `ftell()`, on a given stream is `fflush()`, the file offset in the underlying open file +description shall be adjusted to reflect the location specified by `fseek()`. -The `fseek()` function shall allow the file-position indicator to be set beyond the end of existing data in the file. If -data is later written at this point, subsequent reads of data in the gap shall return bytes with the value `0` until data is actually -written into the gap. +The `fseek()` function shall allow the file-position indicator to be set beyond the end of existing data in the file. +If data is later written at this point, subsequent reads of data in the gap shall return bytes with the value `0` until +data is actually written into the gap. -The behavior of `fseek()` on devices which are incapable of seeking is implementation-defined. The value of the file offset -associated with such a device is undefined. +The behavior of `fseek()` on devices which are incapable of seeking is implementation-defined. The value of the file +offset associated with such a device is undefined. If the stream is writable and buffered data had not been written to the underlying file, `fseek()` shall cause the -unwritten data to be written to the file and shall mark the last data modification and last file status change timestamps of the -file for update. - -In a locale with state-dependent encoding, whether `fseek()` restores the stream's shift state is -implementation-defined. +unwritten data to be written to the file and shall mark the last data modification and last file status change +timestamps of the file for update. -The `fseeko()` function shall be equivalent to the `fseek()` function except that the _offset_ argument is of -type `off_t`. +In a locale with state-dependent encoding, whether `fseek()` restores the stream's shift state is implementation-defined. +The `fseeko()` function shall be equivalent to the `fseek()` function except that the _offset_ argument is of type +`off_t`. ## Return value - The `fseek()` and `fseeko()` functions shall return `0` if they succeed. Otherwise, they shall return `-1` and set `errno` to indicate the error. - ## Errors +The `fseek()`  and `fseeko()`  functions shall fail if, either the stream is unbuffered or the stream's buffer needed +to be flushed, and the call to `fseek()` or `fseeko()` causes an underlying `lseek()` or `write()` to be invoked, and: -The `fseek()`  and `fseeko()` - functions shall fail if, either the stream is unbuffered or the stream's buffer needed to be flushed, and -the call to `fseek()` or `fseeko()` causes an underlying `lseek()` or `write()` to be invoked, and: - - - * `EAGAIN` - The `O_NONBLOCK` flag is set for the file descriptor and the thread would be delayed in the write operation. +* `EAGAIN` - The `O_NONBLOCK` flag is set for the file descriptor and the thread would be delayed in the write + operation. - * `EBADF` - The file descriptor underlying the stream file is not open for writing or the stream's buffer needed to be flushed and the file is -not open. +* `EBADF` - The file descriptor underlying the stream file is not open for writing or the stream's buffer needed to be + flushed and the file is not open. - * `EFBIG` - An attempt was made to write a file that exceeds the maximum file size. +* `EFBIG` - An attempt was made to write a file that exceeds the maximum file size. - * `EFBIG` - An attempt was made to write a file that exceeds the file size limit of the process. +* `EFBIG` - An attempt was made to write a file that exceeds the file size limit of the process. - * `EFBIG` - The file is a regular file and an attempt was made to write at or beyond the offset maximum associated with the corresponding -stream. +* `EFBIG` - The file is a regular file and an attempt was made to write at or beyond the offset maximum associated + with the corresponding stream. - * `EINTR` - The write operation was terminated due to the receipt of a signal, and no data was transferred. +* `EINTR` - The write operation was terminated due to the receipt of a signal, and no data was transferred. - * `EINVAL` - The _whence_ argument is invalid. The resulting file-position indicator would be set to a negative value. +* `EINVAL` - The _whence_ argument is invalid. The resulting file-position indicator would be set to a negative value. - * `EIO` - A physical I/O error has occurred, or the process is a member of a background process group attempting to perform a `write()` to its controlling terminal, `TOSTOP` is set, the calling thread is not blocking -`SIGTTOU`, the process is not ignoring `SIGTTOU`, and the process group of the process is orphaned. This error may also be returned -under implementation-defined conditions. +* `EIO` - A physical I/O error has occurred, or the process is a member of a background process group attempting to + perform a `write()` to its controlling terminal, `TOSTOP` is set, the calling thread is not blocking `SIGTTOU`, the + process is not ignoring `SIGTTOU`, and the process group of the process is orphaned. This error may also be returned + under implementation-defined conditions. - * `ENOSPC` - There was no free space remaining on the device containing the file. +* `ENOSPC` - There was no free space remaining on the device containing the file. - * `EOVERFLOW` - For `fseek()`, the resulting file offset would be a value which cannot be represented correctly in an object of type -`long`. +* `EOVERFLOW` - For `fseek()`, the resulting file offset would be a value which cannot be represented correctly in an + object of type `long`. - * `EOVERFLOW` - For `fseeko()`, the resulting file offset would be a value which cannot be represented correctly in an object of type -`off_t`. +* `EOVERFLOW` - For `fseeko()`, the resulting file offset would be a value which cannot be represented correctly in an + object of type `off_t`. - * `EPIPE` - An attempt was made to write to a pipe or FIFO that is not open for reading by any process; a `SIGPIPE` signal shall also be sent to the -thread. +* `EPIPE` - An attempt was made to write to a pipe or FIFO that is not open for reading by any process; a `SIGPIPE` + signal shall also be sent to the thread. - * `ESPIPE` - The file descriptor underlying stream is associated with a pipe, FIFO, or socket. - -The `fseek()` and `fseeko()` - functions may fail if: - - * `ENXIO` - A request was made of a nonexistent device, or the request was outside the capabilities of the device. +* `ESPIPE` - The file descriptor underlying stream is associated with a pipe, FIFO, or socket. +The `fseek()` and `fseeko()` functions may fail if: +* `ENXIO` - A request was made of a nonexistent device, or the request was outside the capabilities of the device. ## Tests @@ -111,6 +108,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fstatat.part-impl.md b/libc/functions/f/fstatat.part-impl.md index cb6732ea..6a962c06 100644 --- a/libc/functions/f/fstatat.part-impl.md +++ b/libc/functions/f/fstatat.part-impl.md @@ -1,62 +1,69 @@ -# Synopsis -`#include `
+# Synopsis -`#include `
+`#include ` -` int fstatat(int fd, const char *restrict path,`
+`#include ` -`        struct stat *restrict buf, int flag);`
+`int fstatat(int fd, const char *restrict path,` -` int lstat(const char *restrict path, struct stat *restrict buf);`
+`struct stat *restrict buf, int flag);` -` int stat(const char *restrict path, struct stat *restrict buf);`
+`int lstat(const char *restrict path, struct stat *restrict buf);` + +`int stat(const char *restrict path, struct stat *restrict buf);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The purpose is to get file status. The `stat()` function shall obtain information about the named file and write it to the area pointed to by the buf -argument. The _path_ argument points to a pathname naming a file. Read, write, or execute permission of the named file is not -required. An implementation that provides additional or alternate file access control mechanisms may, under implementation-defined -conditions, cause `stat()` to fail. In particular, the system may deny the existence of the file specified by _path_. +The purpose is to get file status. The `stat()` function shall obtain information about the named file and write it to +the area pointed to by the buf argument. The _path_ argument points to a pathname naming a file. Read, write, or execute +permission of the named file is not required. An implementation that provides additional or alternate file access +control mechanisms may, under implementation-defined conditions, cause `stat()` to fail. In particular, the system may +deny the existence of the file specified by _path_. If the named file is a symbolic link, the `stat()` function shall continue pathname resolution using the contents of the symbolic link, and shall return information pertaining to the resulting file if the file exists. -The buf argument is a pointer to a stat structure, as defined in the `` header, into which information is placed concerning the file. +The buf argument is a pointer to a stat structure, as defined in the `` header, into which information is +placed concerning the file. -The `stat()` function shall update any time-related fields, before writing into the stat structure. -If the named file is a shared memory object, the implementation shall update in the stat structure pointed to by the -buf argument the `st_uid,` `st_gid,` `st_size,` and `st_mode` fields, and only the `S_IRUSR,` `S_IWUSR,` -`S_IRGRP,` `S_IWGRP,` `S_IROTH,` and `S_IWOTH` file permission bits need be valid. The implementation may update other fields and flags. +The `stat()` function shall update any time-related fields, before writing into the stat structure. If the named file is +a shared memory object, the implementation shall update in the stat structure pointed to by the buf argument the +`st_uid,` `st_gid,` `st_size,` and `st_mode` fields, and only the `S_IRUSR,` `S_IWUSR,` `S_IRGRP,` `S_IWGRP,` `S_IROTH,` +and `S_IWOTH` file permission bits need be valid. The implementation may update other fields and flags. -If the named file is a typed memory object, the implementation shall update in the stat structure pointed to by the -buf argument the `st_uid,` `st_gid,` `st_size,` and `st_mode` fields, and only the `S_IRUSR,` `S_IWUSR,` -`S_IRGRP,` `S_IWGRP,` `S_IROTH,` and `S_IWOTH` file permission bits need be valid. The implementation may update other fields and flags. +If the named file is a typed memory object, the implementation shall update in the stat structure pointed to by the buf +argument the `st_uid,` `st_gid,` `st_size,` and `st_mode` fields, and only the `S_IRUSR,` `S_IWUSR,` `S_IRGRP,` +`S_IWGRP,` `S_IROTH,` and `S_IWOTH` file permission bits need be valid. The implementation may update other fields and +flags. -For all other file types defined in this volume of `POSIX.1-2017`, the structure members `st_mode,` `st_ino,` -`st_dev,` `st_uid,` `st_gid,` `st_atim,` `st_ctim,` and `st_mtim` shall have meaningful values and -the value of the member `st_nlink` shall be set to the number of links to the file. +For all other file types defined in this volume of `POSIX.1-2017`, the structure members `st_mode,` `st_ino,` `st_dev,` +`st_uid,` `st_gid,` `st_atim,` `st_ctim,` and `st_mtim` shall have meaningful values and the value of the member +`st_nlink` shall be set to the number of links to the file. -The `lstat()` function shall be equivalent to `stat()`, except when _path_ refers to a symbolic link. In that -case `lstat()` shall return information about the link, while `stat()` shall return information about the file the link +The `lstat()` function shall be equivalent to `stat()`, except when _path_ refers to a symbolic link. In that case +`lstat()` shall return information about the link, while `stat()` shall return information about the file the link references. -For symbolic links, the `st_mode` member shall contain meaningful information when used with the file type macros. The file -mode bits in `st_mode` are unspecified. The structure members `st_ino,` `st_dev,` `st_uid,` `st_gid,` -`st_atim,` `st_ctim,` and `st_mtim` shall have meaningful values and the value of the `st_nlink` member shall -be set to the number of (hard) links to the symbolic link. The value of the `st_size` member shall be set to the length of the -pathname contained in the symbolic link not including any terminating null byte. +For symbolic links, the `st_mode` member shall contain meaningful information when used with the file type macros. The +file mode bits in `st_mode` are unspecified. The structure members `st_ino,` `st_dev,` `st_uid,` `st_gid,` `st_atim,` +`st_ctim,` and `st_mtim` shall have meaningful values and the value of the `st_nlink` member shall be set to the number +of (hard) links to the symbolic link. The value of the `st_size` member shall be set to the length of the pathname +contained in the symbolic link not including any terminating null byte. -The `fstatat()` function shall be equivalent to the `stat()` or `lstat()` function, depending on the value of -flag (see below), except in the case where _path_ specifies a relative path. In this case the status shall be retrieved -from a file relative to the directory associated with the file descriptor _fd_ instead of the current working directory. If -the access mode of the open file description associated with the file descriptor is not `O_SEARCH,` the function shall check whether -directory searches are permitted using the current permissions of the directory underlying the file descriptor. If the access mode -is `O_SEARCH,` the function shall not perform the check. +The `fstatat()` function shall be equivalent to the `stat()` or `lstat()` function, depending on the value of flag +(see below), except in the case where _path_ specifies a relative path. In this case the status shall be retrieved from +a file relative to the directory associated with the file descriptor _fd_ instead of the current working directory. If +the access mode of the open file description associated with the file descriptor is not `O_SEARCH,` the function shall +check whether directory searches are permitted using the current permissions of the directory underlying the file +descriptor. If the access mode is `O_SEARCH,` the function shall not perform the check. Values for flag are constructed by a bitwise-inclusive `OR` of flags from the following list, defined in ``: @@ -65,70 +72,59 @@ Values for flag are constructed by a bitwise-inclusive `OR` of flags from the fo If _path_ names a symbolic link, the status of the symbolic link is returned. If `fstatat()` is passed the special value `AT_FDCWD` in the _fd_ parameter, the current working directory shall be used -and the behavior shall be identical to a call to `stat()` or `lstat()` respectively, depending on whether or not the -`AT_SYMLINK_NOFOLLOW` bit is set in flag. - +and the behavior shall be identical to a call to `stat()` or `lstat()` respectively, depending on whether or not +the `AT_SYMLINK_NOFOLLOW` bit is set in flag. ## Return value - -Upon successful completion, these functions shall return `0`. Otherwise, these functions shall return `-1` and set `errno` to indicate the error. - +Upon successful completion, these functions shall return `0`. Otherwise, these functions shall return `-1` and set +`errno` to indicate the error. ## Errors - These functions shall fail if: +* `EACCES` - Search permission is denied for a component of the _path_ prefix. - * `EACCES` - Search permission is denied for a component of the _path_ prefix. +* `EIO` - An error occurred while reading from the file system. - * `EIO` - An error occurred while reading from the file system. +* `ELOOP` - A loop exists in symbolic links encountered during resolution of the _path_ argument. - * `ELOOP` - A loop exists in symbolic links encountered during resolution of the _path_ argument. +* `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. - * `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. +* `ENOENT` - A component of _path_ does not name an existing file or _path_ is an empty string. - * `ENOENT` - A component of _path_ does not name an existing file or _path_ is an empty string. +* `ENOTDIR` - A component of the _path_ prefix names an existing file that is neither a directory nor a symbolic link to +a directory, or the _path_ argument contains at least one non- `/` character and ends with one or more trailing `/` +characters and the last pathname component names an existing file that is neither a directory nor a symbolic link +to a directory. - * `ENOTDIR` - A component of the _path_ prefix names an existing file that is neither a directory nor a symbolic link to a directory, or the -_path_ argument contains at least one non- character and ends with one or more trailing characters -and the last pathname component names an existing file that is neither a directory nor a symbolic link to a directory. - - * `EOVERFLOW` - The file size in bytes or the number of blocks allocated to the file or the file serial number cannot be represented correctly -in the structure pointed to by buf. +* `EOVERFLOW` - The file size in bytes or the number of blocks allocated to the file or the file serial number cannot +be represented correctly in the structure pointed to by buf. The `fstatat()` function shall fail if: +* `EACCES` - The access mode of the open file description associated with _fd_ is not `O_SEARCH` and the permissions of +the directory underlying _fd_ do not permit directory searches. - * `EACCES` - The access mode of the open file description associated with _fd_ is not `O_SEARCH` and the permissions of the directory -underlying _fd_ do not permit directory searches. - - * `EBADF` - The _path_ argument does not specify an absolute path and the _fd_ argument is neither `AT_FDCWD` nor a valid file -descriptor open for reading or searching. +* `EBADF` - The _path_ argument does not specify an absolute path and the _fd_ argument is neither `AT_FDCWD` nor a +valid file descriptor open for reading or searching. - * `ENOTDIR` - The _path_ argument is not an absolute path and _fd_ is a file descriptor associated with a non-directory file. +* `ENOTDIR` - The _path_ argument is not an absolute path and _fd_ is a file descriptor associated with a non-directory +file. These functions may fail if: +* `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the _path_ argument. - * `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the _path_ argument. -`ENAMETOOLONG` - -The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an intermediate result with a -length that exceeds `PATH_MAX`. - - * `EOVERFLOW` - A value to be stored would overflow one of the members of the stat structure. +* `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an +intermediate result with a length that exceeds `PATH_MAX`. +* `EOVERFLOW` - A value to be stored would overflow one of the members of the stat structure. The `fstatat()` function may fail if: - - * `EINVAL` - The value of the flag argument is not valid. - - - - +* `EINVAL` - The value of the flag argument is not valid. ## Tests @@ -138,6 +134,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fsync.not-impl.md b/libc/functions/f/fsync.not-impl.md index 04dd79c5..145bb8fb 100644 --- a/libc/functions/f/fsync.not-impl.md +++ b/libc/functions/f/fsync.not-impl.md @@ -1,47 +1,45 @@ -# Synopsis -`#include `
+# Synopsis -` int fsync(int fildes); `
+`#include ` +` int fsync(int fildes); ` ## Status + Declared, not implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `fsync()` function shall request that all data for the open file descriptor named by _fildes_ is to be transferred -to the storage device associated with the file described by _fildes_. The nature of the transfer is implementation-defined. +to the storage device associated with the file described by _fildes_. The nature of the transfer is +implementation-defined. The `fsync()` function shall not return until the system has completed that action or until an error is detected. -If `_POSIX_SYNCHRONIZED_IO` is defined, the `fsync()` function shall force all currently queued I/O operations associated with -the file indicated by file descriptor _fildes_ to the synchronized I/O completion state. All I/O operations shall be completed -as defined for synchronized I/O file integrity completion. - +If `_POSIX_SYNCHRONIZED_IO` is defined, the `fsync()` function shall force all currently queued I/O operations +associated with the file indicated by file descriptor _fildes_ to the synchronized I/O completion state. All I/O +operations shall be completed as defined for synchronized I/O file integrity completion. ## Return value - -Upon successful completion, `fsync()` shall return `0`. Otherwise, `-1` shall be returned and `errno` set to indicate the error. If the `fsync()` function fails, outstanding I/O operations are not guaranteed to have been completed. - +Upon successful completion, `fsync()` shall return `0`. Otherwise, `-1` shall be returned and `errno` set to indicate +the error. If the `fsync()` function fails, outstanding I/O operations are not guaranteed to have been completed. ## Errors - The `fsync()` function shall fail if: +* `EBADF` - The _fildes_ argument is not a valid descriptor. +* `EINTR` - The `fsync()` function was interrupted by a signal. +* `EINVAL` - The _fildes_ argument does not refer to a file on which this operation is possible. +* `EIO` - An I/O error occurred while reading from or writing to the file system. - * `EBADF` - The _fildes_ argument is not a valid descriptor. - - * `EINTR` - The `fsync()` function was interrupted by a signal. - - * `EINVAL` - The _fildes_ argument does not refer to a file on which this operation is possible. - - * `EIO` - An I/O error occurred while reading from or writing to the file system. - -In the event that any of the queued I/O operations fail, `fsync()` shall return the error conditions defined for `read()` and `write()`. +In the event that any of the queued I/O operations fail, `fsync()` shall return the error conditions defined for `read()` +and `write()`. ## Tests @@ -51,6 +49,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/ftell.part-impl.md b/libc/functions/f/ftell.part-impl.md index de78da2e..206d796f 100644 --- a/libc/functions/f/ftell.part-impl.md +++ b/libc/functions/f/ftell.part-impl.md @@ -1,47 +1,48 @@ -# Synopsis -`#include `
+# Synopsis -` long ftell(FILE *stream);`
+`#include ` -`off_t ftello(FILE *stream); `
+`long ftell(FILE *stream);` + +`off_t ftello(FILE *stream);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The purpose is to return a file offset in a stream. The `ftell()` function shall obtain the current value of the file-position indicator for the stream pointed to by -_stream_. +The purpose is to return a file offset in a stream. The `ftell()` function shall obtain the current value of the +file-position indicator for the stream pointed to by _stream_. The `ftell()` function shall not change the setting of errno if successful. -The `ftello()` function shall be equivalent to `ftell()`, except that the return value is of type `off_t` and the `ftello()` function may change the setting of `errno` if successful. +The `ftello()` function shall be equivalent to `ftell()`, except that the return value is of type `off_t` and the +`ftello()` function may change the setting of `errno` if successful. ## Return value - -Upon successful completion, `ftell()` and `ftello()` shall return the current value of the file-position indicator for the stream measured in bytes from the beginning of the file. +Upon successful completion, `ftell()` and `ftello()` shall return the current value of the file-position indicator for +the stream measured in bytes from the beginning of the file. Otherwise, `ftell()` and `ftello()` shall return `-1`, and set `errno` to indicate the error. - ## Errors - The `ftell()`  and `ftello()` functions shall fail if: +* `EBADF` - The file descriptor underlying stream is not an open file descriptor. - * `EBADF` - The file descriptor underlying stream is not an open file descriptor. +* `EOVERFLOW` - For `ftell()`, the current file offset cannot be represented correctly in an object of type long. - * `EOVERFLOW` - For `ftell()`, the current file offset cannot be represented correctly in an object of type long. - - * `EOVERFLOW` - For `ftello()`, the current file offset cannot be represented correctly in an object of type `off_t`. - - * `ESPIPE` - The file descriptor underlying stream is associated with a pipe, FIFO, or socket. +* `EOVERFLOW` - For `ftello()`, the current file offset cannot be represented correctly in an object of type `off_t`. +* `ESPIPE` - The file descriptor underlying stream is associated with a pipe, FIFO, or socket. ## Tests @@ -51,6 +52,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/ftruncate.part-impl.md b/libc/functions/f/ftruncate.part-impl.md index 3e3b4bb0..5f8564d0 100644 --- a/libc/functions/f/ftruncate.part-impl.md +++ b/libc/functions/f/ftruncate.part-impl.md @@ -1,71 +1,70 @@ -# Synopsis -`#include `
+# Synopsis -` int ftruncate(int fildes, off_t length);`
+`#include ` + +`int ftruncate(int fildes, off_t length);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The purpose is to truncate a file to a specified length. If _fildes_ is not a valid file descriptor open for writing, the `ftruncate()` function shall fail. +The purpose is to truncate a file to a specified length. If _fildes_ is not a valid file descriptor open for writing, +the `ftruncate()` function shall fail. If _fildes_ refers to a regular file, the `ftruncate()` function shall cause the size of the file to be truncated to -_length_. If the size of the file previously exceeded _length_, the extra data shall no longer be available to reads on -the file. If the file previously was smaller than this size, `ftruncate()` shall increase the size of the file. If the file -size is increased, the extended area shall appear as if it were zero-filled. The value of the seek pointer shall not be modified by -a call to `ftruncate()`. + _length_. + +If the size of the file previously exceeded _length_, the extra data shall no longer be available to reads on the file. + +If the file previously was smaller than this size, `ftruncate()` shall increase the size of the file. If the file size +is increased, the extended area shall appear as if it were zero-filled. The value of the seek pointer shall not be +modified by a call to `ftruncate()`. Upon successful completion, if _fildes_ refers to a regular file, `ftruncate()` shall mark for update the last data -modification and last file status change timestamps of the file and the `S_ISUID` and `S_ISGID` bits of the file mode may be cleared. +modification and last file status change timestamps of the file and the `S_ISUID` and `S_ISGID` bits of the file mode +may be cleared. If the `ftruncate()` function is unsuccessful, the file is unaffected. -If the request would cause the file size to exceed the soft file size limit for the process, the request shall fail and the -implementation shall generate the `SIGXFSZ` signal for the thread. + +If the request would cause the file size to exceed the soft file size limit for the process, the request shall fail and +the implementation shall generate the `SIGXFSZ` signal for the thread. + If _fildes_ refers to a directory, `ftruncate()` shall fail. If _fildes_ refers to any other file type, except a shared memory object, the result is unspecified. -If _fildes_ refers to a shared memory object, `ftruncate()` shall set the size of the shared memory object to -_length_. -If the effect of `ftruncate()` is to decrease the size of a memory mapped file or a shared -memory object  and whole pages beyond the new end were -previously mapped, then the whole pages beyond the new end shall be discarded. -References to discarded pages shall result in the generation of a `SIGBUS` signal. +If _fildes_ refers to a shared memory object, `ftruncate()` shall set the size of the shared memory object to _length_. + +If the effect of `ftruncate()` is to decrease the size of a memory mapped file or a shared memory object and whole pages +beyond the new end were previously mapped, then the whole pages beyond the new end shall be discarded. -If the effect of `ftruncate()` is to increase the size of a memory object, it is unspecified whether the contents of any -mapped pages between the old end-of-file and the new are flushed to the underlying object. +References to discarded pages shall result in the generation of a `SIGBUS` signal. +If the effect of `ftruncate()` is to increase the size of a memory object, it is unspecified whether the +contents of any mapped pages between the old end-of-file and the new are flushed to the underlying object. ## Return value -Upon successful completion, `ftruncate()` shall return `0`, otherwise, `-1` shall be returned and `errno` set to indicate the error. +Upon successful completion, `ftruncate()` shall return `0`, otherwise, `-1` shall be returned and `errno` +set to indicate the error. ## Errors - The `ftruncate()` function shall fail if: - - * `EINTR` - A signal was caught during execution. - - * `EINVAL` - The _length_ argument was less than `0`. - - * `EFBIG` or `EINVAL` - The _length_ argument was greater than the maximum file size. - - * `EFBIG` - The file is a regular file and _length_ is greater than the offset maximum established in the open file description -associated with _fildes_. - - * `EIO` - An I/O error occurred while reading from or writing to a file system. -`EBADF` or `EINVAL` - -The _fildes_ argument is not a file descriptor open for writing. - - - - +* `EINTR` - A signal was caught during execution. +* `EINVAL` - The _length_ argument was less than `0`. +* `EFBIG` or `EINVAL` - The _length_ argument was greater than the maximum file size. +* `EFBIG` - The file is a regular file and _length_ is greater than the offset maximum established in the open file + description associated with _fildes_. +* `EIO` - An I/O error occurred while reading from or writing to a file system. +* `EBADF` or `EINVAL` - The _fildes_ argument is not a file descriptor open for writing. ## Tests @@ -75,6 +74,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/f/fwrite.part-impl.md b/libc/functions/f/fwrite.part-impl.md index 2ac3b83a..02f3e22e 100644 --- a/libc/functions/f/fwrite.part-impl.md +++ b/libc/functions/f/fwrite.part-impl.md @@ -1,40 +1,40 @@ -# Synopsis -`#include `
+# Synopsis -` size_t fwrite(const void *restrict ptr, size_t size, size_t nitems,`
-`        FILE *restrict stream);`
+`#include ` + +`size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The `fwrite()` function shall write, from the array pointed to by _ptr_, up to _nitems_ elements whose size is -specified by _size_, to the stream pointed to by _stream_. For each object, size calls shall be made to the `fputc()` function, taking the values (in order) from an array of unsigned char -exactly overlaying the object. The file-position indicator for the stream (if defined) shall be advanced by the number of bytes -successfully written. If an error occurs, the resulting value of the file-position indicator for the stream is unspecified. -The -last data modification and last file status change timestamps of the file shall be marked for update between the successful -execution of `fwrite()` and the next successful completion of a call to `fflush()` -or `fclose()` on the same stream, or a call to `exit()` or `abort()`. +The `fwrite()` function shall write, from the array pointed to by _ptr_, up to _nitems_ elements whose size is specified +by _size_, to the stream pointed to by _stream_. For each object, size calls shall be made to the `fputc()` function, +taking the values (in order) from an array of unsigned char exactly overlaying the object. The file-position indicator +for the stream (if defined) shall be advanced by the number of bytes successfully written. If an error occurs, the +resulting value of the file-position indicator for the stream is unspecified. +The last data modification and last file status change timestamps of the file shall be marked for update between the +successful execution of `fwrite()` and the next successful completion of a call to `fflush()` or `fclose()` on the same +stream, or a call to `exit()` or `abort()`. ## Return value - -The `fwrite()` function shall return the number of elements successfully written, which may be less than _nitems_ if a write error is encountered. If _size_ or _nitems_ is `0`, `fwrite()` shall return `0` and the state of the stream remains unchanged. Otherwise, if a write error occurs, the error indicator for the stream shall be set, and `errno` shall be set to indicate the error. - +The `fwrite()` function shall return the number of elements successfully written, which may be less than _nitems_ if a +write error is encountered. If _size_ or _nitems_ is `0`, `fwrite()` shall return `0` and the state of the stream +remains unchanged. Otherwise, if a write error occurs, the error indicator for the stream shall be set, and `errno` +shall be set to indicate the error. ## Errors - Refer to fputc. - - - ## Tests Untested @@ -43,6 +43,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/func_template.md b/libc/functions/func_template.md index 596f98f9..46c92ac5 100644 --- a/libc/functions/func_template.md +++ b/libc/functions/func_template.md @@ -1,6 +1,6 @@ -# Synopsis +# Synopsis `#include `
`int func_template(int x)`
@@ -13,34 +13,35 @@ Partially implemented ## Conformance -IEEE Std 1003.1-2017 +IEEE Std 1003.1-2017 -## Description - -The `_Exit()` and `_exit()` functions terminate the calling process. +## Description + +The `_Exit()` and `_exit()` functions terminate the calling process. ## Return value -The functions can never return. +The functions can never return. ## Errors -No errors are defined. +No errors are defined. - + ## Tests -Untested +Untested -## Known bugs +## Known bugs None ## See Also 1. [Standard library functions](../README.md) -2. [Table of Contents](../../../README.md) \ No newline at end of file +2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/gai_strerror.part-impl.md b/libc/functions/g/gai_strerror.part-impl.md index aa834c60..a3fa6a2d 100644 --- a/libc/functions/g/gai_strerror.part-impl.md +++ b/libc/functions/g/gai_strerror.part-impl.md @@ -1,21 +1,25 @@ -# Synopsis -`#include `
+# Synopsis -` const char *gai_strerror(int ecode);`
+`#include ` + +`const char *gai_strerror(int ecode);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The purpose is to address and name information error description. The `gai_strerror()` function shall return a text string describing an error value for the `getaddrinfo()` and `getnameinfo()` +The purpose is to address and name information error description. The `gai_strerror()` function shall return a text +string describing an error value for the `getaddrinfo()` and `getnameinfo()` functions listed in the `` header. When the _ecode_ argument is one of the following values listed in the `` header: - * `EAI_AGAIN` * `EAI_BADFLAGS` * `EAI_FAIL` @@ -27,11 +31,8 @@ When the _ecode_ argument is one of the following values listed in the ``
+# Synopsis -`#include `
+`#include ` -` void freeaddrinfo(struct addrinfo *ai);`
+`#include ` -` int getaddrinfo(const char *restrict nodename,`
-`        const char *restrict _servname_,`
-`        const struct addrinfo *restrict hints,`
-`        struct addrinfo **restrict res);`
+`void freeaddrinfo(struct addrinfo *ai);` + +`int getaddrinfo(const char *restrict nodename, const char *restrict _servname_, const struct addrinfo *restrict hints, +struct addrinfo **restrict res);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The purpose is to get address information. The `freeaddrinfo()` function shall free one or more `addrinfo` structures returned by `getaddrinfo()`, along -with any additional storage associated with those structures. If the `ai_next` field of the structure is not `null`, the entire -list of structures shall be freed. The `freeaddrinfo()` function shall support the freeing of arbitrary sublists of an -`addrinfo` list originally returned by `getaddrinfo()`. +The purpose is to get address information. The `freeaddrinfo()` function shall free one or more `addrinfo` structures +returned by `getaddrinfo()`, along with any additional storage associated with those structures. If the `ai_next` +field of the structure is not `null`, the entire list of structures shall be freed. The `freeaddrinfo()` function +shall support the freeing of arbitrary sublists of an `addrinfo` list originally returned by `getaddrinfo()`. -The `getaddrinfo()` function shall translate the name of a service location (for example, a host name) and/or a service -name and shall return a set of socket addresses and associated information to be used in creating a socket with which to address -the specified service. +The `getaddrinfo()` function shall translate the name of a service location (for example, a host name) and/or a +service name and shall return a set of socket addresses and associated information to be used in creating a socket +with which to address the specified service. Note: -In many cases it is implemented by the Domain Name System, as documented in `RFC 1034`, `RFC 1035`, and -`RFC 1886`. - +In many cases it is implemented by the Domain Name System, as documented in `RFC 1034`, `RFC 1035`, and `RFC 1886`. The `freeaddrinfo()` and `getaddrinfo()` functions shall be thread-safe. -The _nodename_ and _servname_ arguments are either `null` pointers or pointers to `null`-terminated strings. One or both -of these two arguments shall be supplied by the application as a non-`null` pointer. +The _nodename_ and _servname_ arguments are either `null` pointers or pointers to `null`-terminated strings. One or +both of these two arguments shall be supplied by the application as a non-`null` pointer. -The format of a valid name depends on the address family or families. If a specific family is not given and the name could be -interpreted as valid within multiple supported families, the implementation shall attempt to resolve the name in all supported -families and, in absence of errors, one or more results shall be returned. +The format of a valid name depends on the address family or families. If a specific family is not given and the name +could be interpreted as valid within multiple supported families, the implementation shall attempt to resolve the name +in all supported families and, in absence of errors, one or more results shall be returned. + +If the _nodename_ argument is not `null`, it can be a descriptive name or can be an address string. If the specified +address family is `AF_INET`, `AF_INET6`, or `AF_UNSPEC`, valid descriptive names include host names. If the specified +address family is `AF_INET` or `AF_UNSPEC,` address strings using Internet standard dot notation as specified in +`inet_addr` are valid. + +If the specified address family is `AF_INET6` or `AF_UNSPEC`, standard `IPv6` text forms described in `inet_ntop` are +valid. -If the _nodename_ argument is not `null`, it can be a descriptive name or can be an address string. If the specified address -family is `AF_INET`, `AF_INET6`, or `AF_UNSPEC`, valid -descriptive names include host names. If the specified address family is `AF_INET` or `AF_UNSPEC,` address strings using Internet -standard dot notation as specified in `inet_addr` are valid. -If the specified address family is `AF_INET6` or `AF_UNSPEC`, standard `IPv6` text forms described in `inet_ntop` are valid. If _nodename_ is not `null`, the requested service location is named by _nodename_, otherwise, the requested service location is local to the caller. -If _servname_ is `null`, the call shall return network-level addresses for the specified _nodename_. If _servname_ -is not `null`, it is a `null`-terminated character string identifying the requested service. This can be either a descriptive name or a -numeric representation suitable for use with the address family or families. If the specified address family is `AF_INET`, -`AF_INET6`, or `AF_UNSPEC`, the service can be specified as a -string specifying a decimal port number. +If _servname_ is `null`, the call shall return network-level addresses for the specified _nodename_. If _servname_ is +not `null`, it is a `null`-terminated character string identifying the requested service. This can be either a +descriptive name or a numeric representation suitable for use with the address family or families. If the specified +address family is `AF_INET`, `AF_INET6`, or `AF_UNSPEC`, the service can be specified as a string specifying a decimal +port number. If the _hints_ argument is not `null`, it refers to a structure containing input values that directs the operation by -providing options and by limiting the returned information to a specific socket type, address family, and/or protocol, as described -below. The application shall ensure that each of the `ai_addrlen`, `ai_addr`, `ai_canonname`, and `ai_next` -members, as well as each of the non-standard additional members, if any, of this _hints_ structure is initialized. If any of -these members has a value other than the value that would result from default initialization, the behavior is -implementation-defined. A value of `AF_UNSPEC` for `ai_family` means that the caller shall accept any address family. A value of -zero for `ai_socktype` means that the caller shall accept any socket type. A value of zero for `ai_protocol` means that -the caller shall accept any protocol. If _hints_ is a `null` pointer, the behavior shall be as if it referred to a structure -containing the value zero for the `ai_flags`, `ai_socktype`, and `ai_protocol` fields, and `AF_UNSPEC` for the -`ai_family` field. - -The `ai_flags` field to which the _hints_ parameter points shall be set to zero or be the bitwise-inclusive OR of one -or more of the values `AI_PASSIVE`, `AI_CANONNAME`, `AI_NUMERICHOST`, `AI_NUMERICSERV`, `AI_V4MAPPED`, `AI_ALL`, and `AI_ADDRCONFIG`. - -If the `AI_PASSIVE` flag is specified, the returned address information shall be suitable for use in binding a socket for -accepting incoming connections for the specified service. In this case, if the _nodename_ argument is `null`, then the IP -address portion of the socket address structure shall be set to `INADDR_ANY` for an `IPv4` address or `IN6ADDR_ANY_INIT` for an `IPv6` -address. If the `AI_PASSIVE` flag is not specified, the returned address information shall be suitable for a call to `connect()` (for a connection-mode protocol) or for a call to `connect()`, `sendto()`, or `sendmsg()` (for a connectionless protocol). In this case, if the _nodename_ argument is -`null`, then the IP address portion of the socket address structure shall be set to the loopback address. The `AI_PASSIVE` flag shall -be ignored if the _nodename_ argument is not `null`. - -If the `AI_CANONNAME` flag is specified and the _nodename_ argument is not `null`, the function shall attempt to determine the -canonical name corresponding to _nodename_ (for example, if _nodename_ is an alias or shorthand notation for a complete -name). - -* Since different implementations use different conceptual models, the terms ``canonical name`` and ``alias`` cannot be precisely defined for the general case. However, Domain Name System implementations are expected to interpret them as they are used in `RFC 1034`. +providing options and by limiting the returned information to a specific socket type, address family, and/or protocol, +as described below. The application shall ensure that each of the `ai_addrlen`, `ai_addr`, `ai_canonname`, and `ai_next` +members, as well as each of the non-standard additional members, if any, of this _hints_ structure is initialized. If +any of these members has a value other than the value that would result from default initialization, the behavior is +implementation-defined. A value of `AF_UNSPEC` for `ai_family` means that the caller shall accept any address family. +A value of zero for `ai_socktype` means that the caller shall accept any socket type. A value of zero for `ai_protocol` +means that the caller shall accept any protocol. If _hints_ is a `null` pointer, the behavior shall be as if it referred +to a structure containing the value zero for the `ai_flags`, `ai_socktype`, and `ai_protocol` fields, and `AF_UNSPEC` +for the `ai_family` field. + +The `ai_flags` field to which the _hints_ parameter points shall be set to zero or be the bitwise-inclusive OR of one or +more of the values `AI_PASSIVE`, `AI_CANONNAME`, `AI_NUMERICHOST`, `AI_NUMERICSERV`, `AI_V4MAPPED`, `AI_ALL`, and +`AI_ADDRCONFIG`. + +If the `AI_PASSIVE` flag is specified, the returned address information shall be suitable for use in binding a socket +for accepting incoming connections for the specified service. In this case, if the _nodename_ argument is `null`, then +the IP address portion of the socket address structure shall be set to `INADDR_ANY` for an `IPv4` address or +`IN6ADDR_ANY_INIT` for an `IPv6` address. If the `AI_PASSIVE` flag is not specified, the returned address information +shall be suitable for a call to `connect()` (for a connection-mode protocol) or for a call to `connect()`, `sendto()`, +or `sendmsg()` (for a connectionless protocol). In this case, if the _nodename_ argument is `null`, then the IP address +portion of the socket address structure shall be set to the loopback address. The `AI_PASSIVE` flag shall be ignored if +the _nodename_ argument is not `null`. + +If the `AI_CANONNAME` flag is specified and the _nodename_ argument is not `null`, the function shall attempt to +determine the canonical name corresponding to _nodename_ (for example, if _nodename_ is an alias or shorthand notation +for a complete name). + +* Since different implementations use different conceptual models, the terms ``canonical name`` and ``alias`` cannot be +precisely defined for the general case. However, Domain Name System implementations are expected to interpret them as +they are used in `RFC 1034`. + + A numeric host address string is not a ``name``, and thus does not have a ``canonical name`` form; no address to host + name translation is performed. See below for handling of the case where a canonical name cannot be obtained. + +If the `AI_NUMERICHOST` flag is specified, then a non-`null` _nodename_ string supplied shall be a numeric host address +string. + +Otherwise, an ``EAI_NONAME`` error is returned. This flag shall prevent any type of name resolution service +(for example, the `DNS`) from being invoked. - A numeric host address string is not a ``name``, and thus does not have a ``canonical name`` form; no address to host name translation is performed. See below for handling of the case where a canonical name cannot be obtained. - - - -If the `AI_NUMERICHOST` flag is specified, then a non-`null` _nodename_ string supplied shall be a numeric host address string. +If the `AI_NUMERICSERV` flag is specified, then a non-`null` _servname_ string supplied shall be a numeric port string. -Otherwise, an ``EAI_NONAME`` error is returned. This flag shall prevent any type of name resolution service (for example, the `DNS`) -from being invoked. +Otherwise, an ``EAI_NONAME`` error shall be returned. This flag shall prevent any type of name resolution service +(for example, `NIS+`) from being invoked. -If the `AI_NUMERICSERV` flag is specified, then a non-`null` _servname_ string supplied shall be a numeric port string. +By default, with an `ai_family` of `AF_INET6`, `getaddrinfo()` shall return only `IPv6` addresses. If the `AI_V4MAPPED` +flag is specified along with an `ai_family` of `AF_INET6`, then `getaddrinfo()` shall return `IPv4`-mapped `IPv6` +addresses on finding no matching `IPv6` addresses. The `AI_V4MAPPED` flag shall be ignored unless `ai_family` equals +`AF_INET6`. If the `AI_ALL` flag is used with the `AI_V4MAPPED` flag, then `getaddrinfo()` shall return all matching +`IPv6` and `IPv4` addresses. The `AI_ALL` flag without the `AI_V4MAPPED` flag shall be ignored. -Otherwise, an ``EAI_NONAME`` error shall be returned. This flag shall prevent any type of name resolution service (for example, `NIS+`) -from being invoked. -By default, with an `ai_family` of `AF_INET6`, `getaddrinfo()` shall return only `IPv6` addresses. If the `AI_V4MAPPED` flag is -specified along with an `ai_family` of `AF_INET6`, then `getaddrinfo()` shall return `IPv4`-mapped `IPv6` addresses on finding -no matching `IPv6` addresses. The `AI_V4MAPPED` flag shall be ignored unless `ai_family` equals `AF_INET6`. If the `AI_ALL` flag is -used with the `AI_V4MAPPED` flag, then `getaddrinfo()` shall return all matching `IPv6` and `IPv4` addresses. The `AI_ALL` flag -without the `AI_V4MAPPED` flag shall be ignored. -If the `AI_ADDRCONFIG` flag is specified, `IPv4` addresses shall be returned only if an `IPv4` address is configured on the local -system, and `IPv6` addresses shall be returned only if an `IPv6` address is configured on the local system. -The `ai_socktype` field to which argument _hints_ points specifies the socket type for the service, as defined in socket. If a specific socket type is not given (for example, a value of zero) and the -service name could be interpreted as valid with multiple supported socket types, the implementation shall attempt to resolve the -service name for all supported socket types and, in the absence of errors, all possible results shall be returned. A non-zero -socket type value shall limit the returned information to values with the specified socket type. +If the `AI_ADDRCONFIG` flag is specified, `IPv4` addresses shall be returned only if an `IPv4` address is configured on +the local system, and `IPv6` addresses shall be returned only if an `IPv6` address is configured on the local system. +The `ai_socktype` field to which argument _hints_ points specifies the socket type for the service, as defined in +socket. If a specific socket type is not given (for example, a value of zero) and the service name could be interpreted +as valid with multiple supported socket types, the implementation shall attempt to resolve the service name for all +supported socket types and, in the absence of errors, all possible results shall be returned. A non-zero socket type +value shall limit the returned information to values with the specified socket type. If the `ai_family` field to which _hints_ points has the value `AF_UNSPEC`, addresses shall be returned for use with any address family that can be used with the specified _nodename_ and/or _servname_. Otherwise, addresses shall be returned for use only with the specified address family. If `ai_family` is not `AF_UNSPEC` and `ai_protocol` is not zero, then -addresses shall be returned for use only with the specified address family and protocol; the value of `ai_protocol` shall be -interpreted as in a call to the `socket()` function with the corresponding values of -`ai_family` and `ai_protocol`. - +addresses shall be returned for use only with the specified address family and protocol; the value of `ai_protocol` +shall be interpreted as in a call to the `socket()` function with the corresponding values of `ai_family` and +`ai_protocol`. ## Return value -A zero return value for `getaddrinfo()` indicates successful completion, a non-zero return value indicates failure. The possible values for the failures are listed in the `ERRORS` section. +A zero return value for `getaddrinfo()` indicates successful completion, a non-zero return value indicates failure. The +possible values for the failures are listed in the `ERRORS` section. -Upon successful return of `getaddrinfo()`, the location to which _res_ points shall refer to a linked list of `addrinfo` structures, each of which shall specify a socket address and information for use in creating a socket with which to use that socket address. The list shall include at least one `addrinfo` structure. The `ai_next` field of each structure contains a pointer to the next structure on the list, or a `null` pointer if it is the last structure on the list. Each structure on the list shall include values for use with a call to the `socket()` function, and a socket address for use with the `connect()` function or, if the `AI_PASSIVE` flag was specified, for use with the `bind()` function. The fields `ai_family`, `ai_socktype`, and `ai_protocol` shall be usable as the arguments to the `socket()` function to create a socket suitable for use with the returned address. The fields `ai_addr` and `ai_addrlen` are usable as the arguments to the `connect()` or `bind()` functions with such a socket, according to the `AI_PASSIVE` flag. +Upon successful return of `getaddrinfo()`, the location to which _res_ points shall refer to a linked list of `addrinfo` +structures, each of which shall specify a socket address and information for use in creating a socket with which to use +that socket address. The list shall include at least one `addrinfo` structure. The `ai_next` field of each structure +contains a pointer to the next structure on the list, or a `null` pointer if it is the last structure on the list. Each +structure on the list shall include values for use with a call to the `socket()` function, and a socket address for use +with the `connect()` function or, if the `AI_PASSIVE` flag was specified, for use with the `bind()` function. The fields +`ai_family`, `ai_socktype`, and `ai_protocol` shall be usable as the arguments to the `socket()` function to create a +socket suitable for use with the returned address. The fields `ai_addr` and `ai_addrlen` are usable as the arguments to +the `connect()` or `bind()` functions with such a socket, according to the `AI_PASSIVE` flag. -If _nodename_ is not `null`, and if requested by the `AI_CANONNAME` flag, the `ai_canonname` field of the first returned `addrinfo` structure shall point to a `null`-terminated string containing the canonical name corresponding to the input _nodename_, if the canonical name is not available, then ai_canonname shall refer to the _nodename_ argument or a string with the same contents. The contents of the ai_flags field of the returned structures are undefined. +If _nodename_ is not `null`, and if requested by the `AI_CANONNAME` flag, the `ai_canonname` field of the first returned +`addrinfo` structure shall point to a `null`-terminated string containing the canonical name corresponding to the input +_nodename_, if the canonical name is not available, then ai_canonname shall refer to the _nodename_ argument or a string +with the same contents. The contents of the ai_flags field of the returned structures are undefined. + +All fields in socket address structures returned by `getaddrinfo()` that are not filled in through an explicit argument +(for example, `sin6_flowinfo`) shall be set to zero. -All fields in socket address structures returned by `getaddrinfo()` that are not filled in through an explicit argument (for example, `sin6_flowinfo`) shall be set to zero. Note: This makes it easier to compare socket address structures. ## Errors - The `getaddrinfo()` function shall fail and return the corresponding error value if: +* `EAI_AGAIN` - The name could not be resolved at this time. Future attempts may succeed. - * `EAI_AGAIN` - The name could not be resolved at this time. Future attempts may succeed. - - * `EAI_BADFLAGS` - The flags parameter had an invalid value. +* `EAI_BADFLAGS` - The flags parameter had an invalid value. - * `EAI_FAIL` - A non-recoverable error occurred when attempting to resolve the name. +* `EAI_FAIL` - A non-recoverable error occurred when attempting to resolve the name. - * `EAI_FAMILY` - The address family was not recognized. +* `EAI_FAMILY` - The address family was not recognized. - * `EAI_MEMORY` - There was a memory allocation failure when trying to allocate storage for the return value. +* `EAI_MEMORY` - There was a memory allocation failure when trying to allocate storage for the return value. - * `EAI_NONAME` - The name does not resolve for the supplied parameters. +* `EAI_NONAME` - The name does not resolve for the supplied parameters. Neither _nodename_ nor _servname_ were supplied. At least one of these shall be supplied. - - * `EAI_SERVICE` - The service passed was not recognized for the specified socket type. +* `EAI_SERVICE` - The service passed was not recognized for the specified socket type. * `EAI_SOCKTYPE` - The intended socket type was not recognized. - * `EAI_SYSTEM` - A system error occurred, the error code can be found in `errno`. - +* `EAI_SYSTEM` - A system error occurred, the error code can be found in `errno`. ## Tests @@ -162,6 +182,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getc.part-impl.md b/libc/functions/g/getc.part-impl.md index 0a2b473c..2f989bd0 100644 --- a/libc/functions/g/getc.part-impl.md +++ b/libc/functions/g/getc.part-impl.md @@ -1,34 +1,31 @@ -# Synopsis -`#include `
+# Synopsis -` int getc(FILE *stream);`
+`#include ` + +`int getc(FILE *stream);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The purpose is to get a byte from a stream. The `getc()` function shall be equivalent to `fgetc`, except that if it is implemented as a macro it may evaluate stream more than once, so the argument should never be an expression with side-effects. - ## Return value - Refer to [fgetc](../f/fgetc.part-impl.md). - ## Errors - Refer to [fgetc](../f/fgetc.part-impl.md). - - - ## Tests Untested @@ -37,6 +34,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getc_unlocked.part-impl.md b/libc/functions/g/getc_unlocked.part-impl.md index 671d6a8e..2b31a450 100644 --- a/libc/functions/g/getc_unlocked.part-impl.md +++ b/libc/functions/g/getc_unlocked.part-impl.md @@ -1,4 +1,4 @@ -###Synopsis +# Synopsis `#include ` @@ -7,39 +7,48 @@ `int putc_unlocked(int c, FILE *stream);` `int putchar_unlocked(int c);` -###Description +## Description `stdio` functions with explicit client locking. Arguments: -stream - the stream to be read or written, -c - a character to be put down. +_stream_ - the stream to be read or written, +_c_ - a character to be put down. -Versions of the functions with names without "_unlocked" which are functionally equivalent to the original versions, with the exception that they are not implemented in a fully thread-safe manner. They are thread-safe when used within a scope protected by `flockfile()` (or `ftrylockfile()`) and `funlockfile()`. These functions can safely be used in a multi-threaded program if and only if they are called while the invoking thread owns the ( `FILE *`) object, as is the case after a successful call to the `flockfile()` or `ftrylockfile()` functions. +Versions of the functions with names without "_unlocked" which are functionally equivalent to the original versions, +with the exception that they are not implemented in a fully thread-safe manner. They are thread-safe when used within +a scope protected by `flockfile()` (or `ftrylockfile()`) and `funlockfile()`. These functions can safely be used in a +multi-threaded program if and only if they are called while the invoking thread owns the ( `FILE *`) object, as is the +case after a successful call to the `flockfile()` or `ftrylockfile()` functions. -If `getc_unlocked()` or `putc_unlocked()` are implemented as macros they may evaluate stream more than once, so the stream argument should never be an expression with side-effects. +If `getc_unlocked()` or `putc_unlocked()` are implemented as macros they may evaluate stream more than once, so the +_stream_ argument should never be an expression with side-effects. -###Return value +## Return value -Upon successful completion, the functions return the byte read or written to or from the stream pointed to by stream. +Upon successful completion, the functions return the byte read or written to or from the stream pointed to by _stream_. -###Errors +## Errors -[`EAGAIN`] The `O_NONBLOCK` flag is set for the file descriptor underlying stream and the thread would be delayed in the operation. -[`EBADF`] The file descriptor underlying stream is not a valid file descriptor open for reading or writing. -[`EFBIG`] An attempt was made to write to a file that exceeds the maximum file size. -[`EINTR`] The read or write operation was terminated due to the receipt of a signal, and no data was transferred. -[`EIO`] A physical I/O error has occurred, or the process is in a background process group attempting to read or write from or to its controlling terminal. -[`ENOSPC`] There was no free space remaining on the device containing the file. -[`EOVERFLOW`] The file is a regular file and an attempt was made to read at or beyond the offset maximum associated with the corresponding stream. -[`ENOMEM`] Insufficient storage space is available. +[`EAGAIN`] The `O_NONBLOCK` flag is set for the file descriptor underlying stream and the thread would be delayed in +the operation. +[`EBADF`] The file descriptor underlying stream is not a valid file descriptor open for reading or writing. +[`EFBIG`] An attempt was made to write to a file that exceeds the maximum file size. +[`EINTR`] The read or write operation was terminated due to the receipt of a signal, and no data was transferred. +[`EIO`] A physical I/O error has occurred, or the process is in a background process group attempting to read or +write from or to its controlling terminal. +[`ENOSPC`] There was no free space remaining on the device containing the file. +[`EOVERFLOW`] The file is a regular file and an attempt was made to read at or beyond the offset maximum associated +with the corresponding stream. +[`ENOMEM`] Insufficient storage space is available. [`ENXIO`] A request was made of a nonexistent device, or the request was outside the capabilities of the device. -[`EPIPE`] An attempt is made to write to a pipe or `FIFO` that is not open for reading by any process. A `SIGPIPE` signal is also sent to the thread. +[`EPIPE`] An attempt is made to write to a pipe or `FIFO` that is not open for reading by any process. A `SIGPIPE` +signal is also sent to the thread. -###Implementation tasks +## Implementation tasks * Implement error handling for the `getc_unlocked()` function. * Implement error handling for the `getchar_unlocked()` function. * Implement error handling for the `putc_unlocked()` function. -* Implement error handling for the `putchar_unlocked()` function. \ No newline at end of file +* Implement error handling for the `putchar_unlocked()` function. diff --git a/libc/functions/g/getchar.md b/libc/functions/g/getchar.md index 063f47ec..b06a4f16 100644 --- a/libc/functions/g/getchar.md +++ b/libc/functions/g/getchar.md @@ -1,29 +1,36 @@ -###Synopsis +# Synopsis `#include ` `int getchar(void);` -###Description +## Description Gets a character (an unsigned char) from `stdin`. It is equivalent to `getc(stdin)`. -###Return value - -Upon successful completion, `getchar()` returns the next byte from `stdin`, the standard input stream. If the end-of-file indicator for `stdin` is set, or if `stdin` is at end-of-file, the end-of-file indicator for `stdin` is set and `getchar()` returns `EOF`. If a read error occurs, the error indicator for `stdin` is set, `getchar()` returns `EOF`, and sets `errno` to indicate the error. - -###Errors - -[`EAGAIN`] The `O_NONBLOCK` flag is set for the file descriptor underlying stream and the thread would be delayed in the `getc()` operation. -[`EBADF`] The file descriptor underlying stream is not a valid file descriptor open for reading. -[`EINTR`] The read operation was terminated due to the receipt of a signal, and no data was transferred. -[`EIO`] A physical I/O error has occurred, or the process is in a background process group attempting to read from its controlling terminal, and either the calling thread is blocking `SIGTTIN` or the process is ignoring `SIGTTIN` or the process group of the process is orphaned. -[`EOVERFLOW`] The file is a regular file and an attempt was made to read at or beyond the offset maximum associated with the corresponding stream. -[`ENOMEM`] Insufficient storage space is available. +## Return value + +Upon successful completion, `getchar()` returns the next byte from `stdin`, the standard input stream. If the +end-of-file indicator for `stdin` is set, or if `stdin` is at end-of-file, the end-of-file indicator for `stdin` is +set and `getchar()` returns `EOF`. If a read error occurs, the error indicator for `stdin` is set, `getchar()` returns +`EOF`, and sets `errno` to indicate the error. + +## Errors + +[`EAGAIN`] The `O_NONBLOCK` flag is set for the file descriptor underlying stream and the thread would be delayed in the +`getc()` operation. +[`EBADF`] The file descriptor underlying stream is not a valid file descriptor open for reading. +[`EINTR`] The read operation was terminated due to the receipt of a signal, and no data was transferred. +[`EIO`] A physical I/O error has occurred, or the process is in a background process group attempting to read from +its controlling terminal, and either the calling thread is blocking `SIGTTIN` or the process is ignoring `SIGTTIN` or +the process group of the process is orphaned. +[`EOVERFLOW`] The file is a regular file and an attempt was made to read at or beyond the offset maximum associated +with the corresponding stream. +[`ENOMEM`] Insufficient storage space is available. [`ENXIO`] A request was made of a nonexistent device, or the request was outside the capabilities of the device. -###Implementation tasks +## Implementation tasks -* Implement error handling for the `getchar()` function. \ No newline at end of file +* Implement error handling for the `getchar()` function. diff --git a/libc/functions/g/getchar.part-impl.md b/libc/functions/g/getchar.part-impl.md index 7d63a77e..a775771e 100644 --- a/libc/functions/g/getchar.part-impl.md +++ b/libc/functions/g/getchar.part-impl.md @@ -1,30 +1,29 @@ -# Synopsis -`#include `
+# Synopsis -` int getchar(void);`
+`#include ` + +`int getchar(void);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The purpose is to get a byte from a stdin stream. The `getchar()` function shall be equivalent to `getc(stdin)`. - ## Return value - Refer to [fgetc](../f/fgetc.part-impl.md). - ## Errors - Refer to [fgetc](../f/fgetc.part-impl.md). - ## Tests Untested @@ -33,6 +32,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getcwd.part-impl.md b/libc/functions/g/getcwd.part-impl.md index b83838b8..2ac067ba 100644 --- a/libc/functions/g/getcwd.part-impl.md +++ b/libc/functions/g/getcwd.part-impl.md @@ -1,52 +1,48 @@ -# Synopsis -`#include `
+# Synopsis -` char *getcwd(char *buf, size_t size);`
+`#include ` + +`char *getcwd(char *buf, size_t size);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The purpose is to get the `pathname` of the current working directory. The `getcwd()` function shall place an absolute `pathname` of the current working directory in the array pointed to by -_buf_, and return _buf_. The `pathname` shall contain no components that are dot or dot-dot, or are symbolic links. +The purpose is to get the `pathname` of the current working directory. The `getcwd()` function shall place an absolute +`pathname` of the current working directory in the array pointed to by _buf_, and return _buf_. The `pathname` shall +contain no components that are dot or dot-dot, or are symbolic links. If there are multiple `pathnames` that `getcwd()` could place in the array pointed to by _buf_, one beginning with a single `` character and one or more beginning with two `` characters, then `getcwd()` shall place the -`pathname` beginning with a single `` character in the array. The `pathname` shall not contain any unnecessary `` -characters after the leading one or two `` characters. - -The _size_ argument is the size in bytes of the character array pointed to by the _buf_ argument. If _buf_ is a -`null` pointer, the behavior of `getcwd()` is unspecified. +`pathname` beginning with a single `` character in the array. The `pathname` shall not contain any unnecessary +`` characters after the leading one or two `` characters. +The _size_ argument is the size in bytes of the character array pointed to by the _buf_ argument. If _buf_ is a `null` +pointer, the behavior of `getcwd()` is unspecified. ## Return value -Upon successful completion, `getcwd()` shall return the _buf_ argument. Otherwise, `getcwd()` shall return a `null` pointer and set `errno` to indicate the error. The contents of the array pointed to by _buf_ are then undefined. +Upon successful completion, `getcwd()` shall return the _buf_ argument. Otherwise, `getcwd()` shall return a `null` +pointer and set `errno` to indicate the error. The contents of the array pointed to by _buf_ are then undefined. ## Errors - The `getcwd()` function shall fail if: - - * `EINVAL` - The _size_ argument is `0`. - - * `ERANGE` - The _size_ argument is greater than `0`, but is smaller than the length of the `string + 1`. +* `EINVAL` - The _size_ argument is `0`. +* `ERANGE` - The _size_ argument is greater than `0`, but is smaller than the length of the `string + 1`. The `getcwd()` function may fail if: - - * `EACCES` - Search permission was denied for the current directory, or read or search permission was denied for a directory above the -current directory in the file hierarchy. - - * `ENOMEM` - Insufficient storage space is available. - - - - +* `EACCES` - Search permission was denied for the current directory, or read or search permission was denied for a + directory above the current directory in the file hierarchy. +* `ENOMEM` - Insufficient storage space is available. ## Tests @@ -56,6 +52,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getegid.md b/libc/functions/g/getegid.md index de50688b..7a734016 100644 --- a/libc/functions/g/getegid.md +++ b/libc/functions/g/getegid.md @@ -1,24 +1,24 @@ -###Synopsis +# Synopsis `#include ` `gid_t getegid(void);` -###Description +## Description The `getegid()` function returns the effective group ID of the calling process. Arguments: None. -###Return value +## Return value The effective group ID of the calling process. -###Errors +## Errors No errors are defined. -###Implementation tasks +## Implementation tasks * Implement the `getegid()` function. diff --git a/libc/functions/g/getegid.part-impl.md b/libc/functions/g/getegid.part-impl.md index 2ab2386a..b2ffeb2b 100644 --- a/libc/functions/g/getegid.part-impl.md +++ b/libc/functions/g/getegid.part-impl.md @@ -1,29 +1,30 @@ -# Synopsis -`#include `
+# Synopsis -` gid_t getegid(void);`
+`#include ` + +`gid_t getegid(void);` ## Status + Declared, not implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 -The `getegid()` function shall return the effective group ID of the calling process. The `getegid()` function shall not modify `errno`. +## Description +The `getegid()` function shall return the effective group ID of the calling process. The `getegid()` function shall +not modify `errno`. ## Return value - The `getegid()` function shall always be successful and no return value is reserved to indicate an error. ## Errors - No errors are defined. - ## Tests Untested @@ -32,6 +33,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getenv.part-impl.md b/libc/functions/g/getenv.part-impl.md index c67c98f6..99573aea 100644 --- a/libc/functions/g/getenv.part-impl.md +++ b/libc/functions/g/getenv.part-impl.md @@ -1,32 +1,37 @@ -# Synopsis -`#include `
+# Synopsis -`int getenv(const char *name);`
+`#include ` + +`int getenv(const char *name);` ## Status + Partially implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 -The `getenv()` function shall search the environment of the calling process (see XBD Environment Variables) for the environment variable name if it exists and return a pointer to the value of the environment variable. If the specified environment variable cannot be found, a null pointer shall be returned. The application shall ensure that it does not modify the string pointed to by the `getenv()` function. +## Description -The returned string pointer might be invalidated or the string content might be overwritten by a subsequent call to `getenv()`, `setenv()`, `unsetenv()`, or `putenv()` but they shall not be affected by a call to any other function in this volume of `POSIX.1-2017`. +The `getenv()` function shall search the environment of the calling process (see XBD Environment Variables) for the +environment variable name if it exists and return a pointer to the value of the environment variable. If the specified +environment variable cannot be found, a null pointer shall be returned. The application shall ensure that it does not +modify the string pointed to by the `getenv()` function. +The returned string pointer might be invalidated or the string content might be overwritten by a subsequent call to +`getenv()`,`setenv()`,`unsetenv()`, or `putenv()` but they shall not be affected by a call to any other function in +this volume of `POSIX.1-2017`. ## Return value - -Upon successful completion, `getenv()` shall return a pointer to a string containing the value for the specified name. If the specified name cannot be found in the environment of the calling process, a null pointer shall be returned. - +Upon successful completion, `getenv()` shall return a pointer to a string containing the value for the specified name. +If the specified name cannot be found in the environment of the calling process, a null pointer shall be returned. ## Errors - No errors are defined. - ## Tests Tested @@ -35,6 +40,7 @@ Tested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/geteuid.not-impl.md b/libc/functions/g/geteuid.not-impl.md index 62c3b9b9..8f9337c0 100644 --- a/libc/functions/g/geteuid.not-impl.md +++ b/libc/functions/g/geteuid.not-impl.md @@ -1,34 +1,30 @@ -# Synopsis -`#include ` +# Synopsis -` uid_t geteuid(void);` +`#include ` +`uid_t geteuid(void);` ## Status + Declared, not implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `geteuid()` function shall return the effective user ID of the calling process. The `geteuid()` function shall not modify `errno`. - ## Return value - The `geteuid()` function shall always be successful and no return value is reserved to indicate an error. - ## Errors - No errors are defined. - - - ## Tests Untested @@ -37,6 +33,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getgid.not-impl.md b/libc/functions/g/getgid.not-impl.md index c658ae95..42dcb84d 100644 --- a/libc/functions/g/getgid.not-impl.md +++ b/libc/functions/g/getgid.not-impl.md @@ -1,33 +1,30 @@ -# Synopsis +# Synopsis + `#include ` -` gid_t getgid(void);` +`gid_t getgid(void);` ## Status + Declared, not implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `getgid()` function shall return the real group ID of the calling process. The `getgid()` function shall not modify `errno`. - ## Return value - The `getgid()` function shall always be successful and no return value is reserved to indicate an error. - ## Errors - No errors are defined. - - - ## Tests Untested @@ -36,6 +33,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getgroups.not-impl.md b/libc/functions/g/getgroups.not-impl.md index 3b266ec4..5dcb479e 100644 --- a/libc/functions/g/getgroups.not-impl.md +++ b/libc/functions/g/getgroups.not-impl.md @@ -1,49 +1,43 @@ -# Synopsis -`#include ` +# Synopsis -` int getgroups(int gidsetsize, gid_t grouplist[]);` +`#include ` +`int getgroups(int gidsetsize, gid_t grouplist[]);` ## Status + Declared, not implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `getgroups()` function shall fill in the array _grouplist_ with the current supplementary group IDs of the calling -process. It is implementation-defined whether `getgroups()` also returns the effective group ID in the _grouplist_ + process. It is implementation-defined whether `getgroups()` also returns the effective group ID in the _grouplist_ array. The _gidsetsize_ argument specifies the number of elements in the array _grouplist_. The actual number of group IDs -stored in the array shall be returned. The values of array entries with indices greater than or equal to the value returned are -undefined. +stored in the array shall be returned. The values of array entries with indices greater than or equal to the value +returned are undefined. If _gidsetsize_ is 0, `getgroups()` shall return the number of group IDs that it would otherwise return without modifying the array pointed to by _grouplist_. -If the effective group ID of the process is returned with the supplementary group IDs, the value returned shall always be -greater than or equal to one and less than or equal to the value of `NGROUPS_MAX`+1. - +If the effective group ID of the process is returned with the supplementary group IDs, the value returned shall always +be greater than or equal to one and less than or equal to the value of `NGROUPS_MAX`+1. ## Return value - -Upon successful completion, the number of supplementary group IDs shall be returned. A return value of -1 indicates failure and -errno shall be set to indicate the error. - +Upon successful completion, the number of supplementary group IDs shall be returned. A return value of -1 indicates +failure and errno shall be set to indicate the error. ## Errors - The `getgroups()` function shall fail if: - - * `EINVAL` - The _gidsetsize_ argument is non-zero and less than the number of group IDs that would have been returned. - - - - +* `EINVAL` - The _gidsetsize_ argument is non-zero and less than the number of group IDs that would have been returned. ## Tests @@ -53,6 +47,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getline.part-impl.md b/libc/functions/g/getline.part-impl.md index 1096b489..8cd9f3d4 100644 --- a/libc/functions/g/getline.part-impl.md +++ b/libc/functions/g/getline.part-impl.md @@ -1,69 +1,71 @@ -# Synopsis -`#include `
+# Synopsis -` ssize_t getdelim(char **restrict lineptr, size_t *restrict n,`
-`        int delimiter, FILE *restrict stream);`
+`#include ` -` ssize_t getline(char **restrict lineptr, size_t *restrict n,`
-`        FILE *restrict stream); `
+`ssize_t getdelim(char **restrict lineptr, size_t *restrict n, int delimiter, FILE *restrict stream);` + +` ssize_t getline(char **restrict lineptr, size_t *restrict n, FILE *restrict stream); ` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description +The purpose is to read a delimited record from stream. The `getdelim()` function shall read from _stream_ until it +encounters a character matching the delimiter character. -The purpose is to read a delimited record from stream. The `getdelim()` function shall read from _stream_ until it encounters a character matching the delimiter -character. The _delimiter_ argument is an `int`, the value of which the application shall ensure is a character -representable as an `unsigned` `char` of equal value that terminates the read process. If the _delimiter_ argument has any +The _delimiter_ argument is an `int`, the value of which the application shall ensure is a character representable as an +`unsigned` `char` of equal value that terminates the read process. If the _delimiter_ argument has any other value, the behavior is undefined. -The application shall ensure that _`*lineptr`_ is a valid argument that could be passed to the `free()` function. If _`*n`_ is non-zero, the application shall ensure that _`*lineptr`_ -either points to an object of size at least _`*n`_ bytes, or is a `null` pointer. +The application shall ensure that _`*lineptr`_ is a valid argument that could be passed to the `free()` function. If +_`*n`_ is non-zero, the application shall ensure that _`*lineptr`_ either points to an object of size at least _`*n`_ +bytes, or is a `null` pointer. -If _`*lineptr`_ is a `null` pointer or if the object pointed to by _`*lineptr`_ is of insufficient size, an object shall be -allocated as if by `malloc()` or the object shall be reallocated as if by `realloc()`, respectively, such that the object is large enough to hold the characters to be -written to it, including the terminating `NUL`, and _`*n`_ shall be set to the new size. If the object was allocated, or if the -reallocation operation moved the object, _`*lineptr`_ shall be updated to point to the new object or new location. The -characters read, including any delimiter, shall be stored in the object, and a terminating `NUL` added when the _delimiter_ or -end-of-file is encountered. +If _`*lineptr`_ is a `null` pointer or if the object pointed to by _`*lineptr`_ is of insufficient size, an object shall +be allocated as if by `malloc()` or the object shall be reallocated as if by `realloc()`, respectively, such that the +object is large enough to hold the characters to be written to it, including the terminating `NUL`, and _`*n`_ shall be +set to the new size. If the object was allocated, or if the reallocation operation moved the object, _`*lineptr`_ shall +be updated to point to the new object or new location. The characters read, including any delimiter, shall be stored in +the object, and a terminating `NUL` added when the _delimiter_ or end-of-file is encountered. The `getline()` function shall be equivalent to the `getdelim()` function with the delimiter character equal to the `` character. -The `getdelim()` and `getline()` functions may mark the last data access timestamp of the file associated with -_stream_ for update. The last data access timestamp shall be marked for update by the first successful execution of `fgetc()`, `fgets()`, `fread()`, `fscanf()`, `getc()`, `getchar()`, `getdelim()`, -`getline()`, `gets()`, or `scanf()` using +The `getdelim()` and `getline()` functions may mark the last data access timestamp of the file associated with _stream_ +for update. The last data access timestamp shall be marked for update by the first successful execution of `fgetc()`, +`fgets()`, `fread()`, `fscanf()`, `getc()`, `getchar()`, `getdelim()`, `getline()`, `gets()`, or `scanf()` using _stream_ that returns data not supplied by a prior call to `ungetc()`. - ## Return value - -Upon successful completion, the `getline()` and `getdelim()` functions shall return the number of bytes written into -the buffer, including the _delimiter_ character if one was encountered before `EOF`, but excluding the terminating `NUL` character. If -the end-of-file indicator for the _stream_ is set, or if no characters were read and the _stream_ is at end-of-file, the end-of-file -indicator for the _stream_ shall be set and the function shall return `-1`. If an error occurs, the error indicator for the _stream_ -shall be set, and the function shall return `-1` and set `errno` to indicate the error. +Upon successful completion, the `getline()` and `getdelim()` functions shall return the number of bytes written into the +buffer, including the _delimiter_ character if one was encountered before `EOF`, but excluding the terminating `NUL` +character. If the end-of-file indicator for the _stream_ is set, or if no characters were read and the _stream_ is at +end-of-file, the end-of-file indicator for the _stream_ shall be set and the function shall return `-1`. If an error +occurs, the error indicator for the _stream_ shall be set, and the function shall return `-1` and set `errno` to +indicate the error. ## Errors - -For the conditions under which the `getdelim()` and `getline()` functions shall fail and may fail, refer to [fgetc](../f/fgetc.part-impl.md). +For the conditions under which the `getdelim()` and `getline()` functions shall fail and may fail, refer to +[fgetc](../f/fgetc.part-impl.md). In addition, these functions shall fail if: - * `EINVAL` - _lineptr_ or _n_ is a `null` pointer. +* `EINVAL` - _lineptr_ or _n_ is a `null` pointer. - * `ENOMEM` - Insufficient memory is available. +* `ENOMEM` - Insufficient memory is available. These functions may fail if: - * `EOVERFLOW` - The number of bytes to be written into the buffer, including the _delimiter_ character (if encountered), would exceed -`SSIZE_MAX`. - - +* `EOVERFLOW` - The number of bytes to be written into the buffer, including the _delimiter_ character + (if encountered), would exceed `SSIZE_MAX`. ## Tests @@ -73,6 +75,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getlogin.not-impl.md b/libc/functions/g/getlogin.not-impl.md index 504d2769..f622ea90 100644 --- a/libc/functions/g/getlogin.not-impl.md +++ b/libc/functions/g/getlogin.not-impl.md @@ -1,74 +1,68 @@ -# Synopsis -`#include ` +# Synopsis -` char *getlogin(void);` +`#include ` -` int getlogin_r(char *name, size_t namesize);` +`char *getlogin(void);` +`int getlogin_r(char *name, size_t namesize);` ## Status + Declared, not implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The `getlogin()` function shall return a pointer to a string containing the user name associated by the login activity with -the controlling terminal of the current process. If `getlogin()` returns a non-null pointer, then that pointer points to the -name that the user logged in under, even if there are several login names with the same user ID. +The `getlogin()` function shall return a pointer to a string containing the user name associated by the login activity +with the controlling terminal of the current process. If `getlogin()` returns a non-null pointer, then that pointer +points to the name that the user logged in under, even if there are several login names with the same user ID. The `getlogin()` function need not be thread-safe. The `getlogin_r()` function shall put the name associated by the login activity with the controlling terminal of the -current process in the character array pointed to by _name_. The array is _namesize _characters long and should have -space for the _name_ and the terminating null character. The maximum size of the login name is `LOGIN_NAME_MAX`. +current process in the character array pointed to by _name_. The array is _namesize_characters long and should have +space for the_name_ and the terminating null character. The maximum size of the login name is `LOGIN_NAME_MAX`. -If `getlogin_r()` is successful, _name_ points to the name the user used at login, even if there are several login -names with the same user ID. +If `getlogin_r()` is successful, _name_ points to the name the user used at login, even if there are several login names +with the same user ID. The `getlogin()` and `getlogin_r()` functions may make use of file descriptors 0, 1, and 2 to find the controlling -terminal of the current process, examining each in turn until the terminal is found. If in this case none of these three file -descriptors is open to the controlling terminal, these functions may fail. The method used to find the terminal associated with a -file descriptor may depend on the file descriptor being open to the actual terminal device, not /dev/tty. - +terminal of the current process, examining each in turn until the terminal is found. If in this case none of these +three file descriptors is open to the controlling terminal, these functions may fail. The method used to find the +terminal associated with a file descriptor may depend on the file descriptor being open to the actual terminal device, +not /dev/tty. ## Return value - Upon successful completion, `getlogin()` shall return a pointer to the login name or a null pointer if the user's login name cannot be found. Otherwise, it shall return a null pointer and set `errno` to indicate the error. -The application shall not modify the string returned. The returned pointer might be invalidated or the string content might be -overwritten by a subsequent call to `getlogin()`. The returned pointer and the string content might also be invalidated if the -calling thread is terminated. - -If successful, the `getlogin_r()` function shall return zero; otherwise, an error number shall be returned to indicate the -error. +The application shall not modify the string returned. The returned pointer might be invalidated or the string content +might be overwritten by a subsequent call to `getlogin()`. The returned pointer and the string content might also be +invalidated if the calling thread is terminated. +If successful, the `getlogin_r()` function shall return zero; otherwise, an error number shall be returned to indicate +the error. ## Errors - These functions may fail if: +* `EMFILE` - All file descriptors available to the process are currently open. - * `EMFILE` - All file descriptors available to the process are currently open. - - * `ENFILE` - The maximum allowable number of files is currently open in the system. +* `ENFILE` - The maximum allowable number of files is currently open in the system. - * `ENOTTY` - None of the file descriptors 0, 1, or 2 is open to the controlling terminal of the current process. +* `ENOTTY` - None of the file descriptors 0, 1, or 2 is open to the controlling terminal of the current process. - * `ENXIO` - The calling process has no controlling terminal. +* `ENXIO` - The calling process has no controlling terminal. The `getlogin_r()` function may fail if: - - * `ERANGE` - The value of _namesize_ is smaller than the length of the string to be returned including the terminating null -character. - - - - +* `ERANGE` - The value of _namesize_ is smaller than the length of the string to be returned including the terminating + null character. ## Tests @@ -78,6 +72,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getopt.part-impl.md b/libc/functions/g/getopt.part-impl.md index 0c82b90e..724aae29 100644 --- a/libc/functions/g/getopt.part-impl.md +++ b/libc/functions/g/getopt.part-impl.md @@ -1,59 +1,86 @@ -# Synopsis -`#include `
+# Synopsis -`int getopt(int argc, char * const argv[], const char *optstring);`
-`extern char *optarg;`
-`extern int opterr, optind, optopt;`
+`#include ` + +`int getopt(int argc, char * const argv[], const char *optstring);` + +`extern char *optarg;` + +`extern int opterr, optind, optopt;` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The `getopt()` function is a command-line parser that shall follow Utility Syntax Guidelines `3`, `4`, `5`, `6`, `7`, `9`, and `10` in `XBD Utility Syntax Guidelines`. +The `getopt()` function is a command-line parser that shall follow Utility Syntax Guidelines `3`, `4`, `5`, `6`, `7`, +`9`, and `10` in `XBD Utility Syntax Guidelines`. -The parameters _argc_ and _argv_ are the argument count and argument array as passed to `main()`. The argument _optstring_ is a string of recognized option characters; if a character is followed by a ``, the option takes an argument. All option characters allowed by `Utility Syntax Guideline 3` are allowed in _optstring_. The implementation may accept other characters as an extension. +The parameters _argc_ and _argv_ are the argument count and argument array as passed to `main()`. The argument +_optstring_ is a string of recognized option characters; if a character is followed by a ``, the option +takes an argument. All option characters allowed by `Utility Syntax Guideline 3` are allowed in _optstring_. The +implementation may accept other characters as an extension. -The variable _optind_ is the index of the next element of the `argv[]` vector to be processed. It shall be initialized to `1` by the system, and `getopt()` shall update it when it finishes with each element of `argv[]`. If the application sets optind to zero before calling `getopt()`, the behavior is unspecified. When an element of `argv[]` contains multiple option characters, it is unspecified how `getopt()` determines which options have already been processed. +The variable _optind_ is the index of the next element of the `argv[]` vector to be processed. It shall be initialized +to `1` by the system, and `getopt()` shall update it when it finishes with each element of `argv[]`. If the application +sets optind to zero before calling `getopt()`, the behavior is unspecified. When an element of `argv[]` contains +multiple option characters, it is unspecified how `getopt()` determines which options have already been processed. -The `getopt()` function shall return the next option character (if one is found) from argv that matches a character in optstring, if there is one that matches. If the option takes an argument, `getopt()` shall set the variable _optarg_ to point to the option-argument as follows: +The `getopt()` function shall return the next option character (if one is found) from argv that matches a character in +optstring, if there is one that matches. If the option takes an argument, `getopt()` shall set the variable _optarg_ +to point to the option-argument as follows: - 1. If the option was the last character in the string pointed to by an element of `argv`, then _optarg_ shall contain the next element of `argv`, and _optind_ shall be incremented by `2`. If the resulting value of _optind_ is greater than `argc`, this indicates a missing option-argument, and `getopt()` shall return an error indication. + 1. If the option was the last character in the string pointed to by an element of `argv`, then _optarg_ shall contain + the next element of `argv`, and _optind_ shall be incremented by `2`. If the resulting value of _optind_ is greater + than `argc`, this indicates a missing option-argument, and `getopt()` shall return an error indication. - 2. Otherwise, _optarg_ shall point to the string following the option character in that element of argv, and _optind_ shall be incremented by `1`. + 2. Otherwise, _optarg_ shall point to the string following the option character in that element of argv, and _optind_ + shall be incremented by `1`. If, when `getopt()` is called: - - `argv[optind] is a null pointer`
- - `*argv[optind] is not the character -`
- - `argv[optind] points to the string "-"`
- +- `argv[optind] is a null pointer` + +- `*argv[optind] is not the character -` + +- `argv[optind] points to the string "-"` + `getopt()` shall return `-1` without changing _optind_. If: - - `argv[optind] points to the string "--"` +- `argv[optind] points to the string "--"` `getopt()` shall return `-1` after incrementing optind. -If `getopt()` encounters an option character that is not contained in _optstring_, it shall return the `` ( `'?'` ) character. If it detects a missing option-argument, it shall return the `` character ( `':'` ) if the first character of _optstring_ was a ``, or a `` character ( `'?'` ) otherwise. In either case, `getopt()` shall set the variable _optopt_ to the option character that caused the error. If the application has not set the variable opterr to `0` and the first character of _optstring_ is not a ``, `getopt()` shall also print a diagnostic message to `stderr` in the format specified for the `getopts` utility, unless the `stderr` stream has wide orientation, in which case the behavior is undefined - +If `getopt()` encounters an option character that is not contained in _optstring_, it shall return the `` +( `'?'` ) character. If it detects a missing option-argument, it shall return the `` character ( `':'` ) if the +first character of _optstring_ was a ``, or a `` character ( `'?'` ) otherwise. In either case, +`getopt()` shall set the variable _optopt_ to the option character that caused the error. If the application has not set +the variable opterr to `0` and the first character of _optstring_ is not a ``, `getopt()` shall also print a +diagnostic message to `stderr` in the format specified for the `getopts` utility, unless the `stderr` stream has wide +orientation, in which case the behavior is undefined ## Return value The `getopt()` function shall return the next option character specified on the command line. -A `` ( `':'` ) shall be returned if getopt() detects a missing argument and the first character of optstring was a `` ( `':'` ). +A `` ( `':'` ) shall be returned if getopt() detects a missing argument and the first character of optstring was +a `` ( `':'` ). -A `` ( `'?'` ) shall be returned if `getopt()` encounters an option character not in _optstring_ or detects a missing argument and the first character of _optstring_ was not a `` ( `':'` ). +A `` ( `'?'` ) shall be returned if `getopt()` encounters an option character not in _optstring_ or +detects a missing argument and the first character of _optstring_ was not a `` ( `':'` ). Otherwise, `getopt()` shall return `-1` when all command line options are parsed. ## Errors - -If the application has not set the variable _opterr_ to `0`, the first character of optstring is not a ``, and a write error occurs while `getopt()` is printing a diagnostic message to `stderr`, then the error indicator for `stderr` shall be set; but `getopt()` shall still succeed and the value of `errno` after `getopt()` is unspecified. - +If the application has not set the variable _opterr_ to `0`, the first character of optstring is not a ``, and a +write error occurs while `getopt()` is printing a diagnostic message to `stderr`, then the error indicator for `stderr` +shall be set; but `getopt()` shall still succeed and the value of `errno` after `getopt()` is unspecified. ## Tests @@ -63,6 +90,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) -2. [Table of Contents](../../../README.md) \ No newline at end of file +2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getpgid.part-impl.md b/libc/functions/g/getpgid.part-impl.md index 2fdb05e0..01f71a26 100644 --- a/libc/functions/g/getpgid.part-impl.md +++ b/libc/functions/g/getpgid.part-impl.md @@ -1,38 +1,39 @@ -# Synopsis -`#include `
+# Synopsis -`pid_t getpgid(pid_t pid);`
+`#include ` + +`pid_t getpgid(pid_t pid);` ## Status + Partially implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 -The `getpgid()` function shall return the process group ID of the process whose process ID is equal to _pid_. If _pid_ is equal to `0`, `getpgid()` shall return the process group ID of the calling process. +## Description +The `getpgid()` function shall return the process group ID of the process whose process ID is equal to _pid_. If _pid_ +is equal to `0`, `getpgid()` shall return the process group ID of the calling process. ## Return value - -Upon successful completion, `getpgid()` shall return a process group ID. Otherwise, it shall return `(pid_t)-1` and set `errno` to indicate the error. - +Upon successful completion, `getpgid()` shall return a process group ID. Otherwise, it shall return `(pid_t)-1` and set +`errno` to indicate the error. ## Errors - The `getpgid()` function shall fail if: - * `EPERM` - The process whose process ID is equal to _pid_ is not in the same session as the calling process, and the implementation does not allow access to the process group ID of that process from the calling process. +* `EPERM` - The process whose process ID is equal to _pid_ is not in the same session as the calling process, and the + implementation does not allow access to the process group ID of that process from the calling process. - * `ESRCH` - There is no process with a process ID equal to _pid_. +* `ESRCH` - There is no process with a process ID equal to _pid_. The `getpgid()` function may fail if: - * `EINVAL` - The value of the _pid_ argument is invalid. - - +* `EINVAL` - The value of the _pid_ argument is invalid. ## Tests @@ -42,6 +43,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getpgrp.md b/libc/functions/g/getpgrp.md index 86725d8f..0ee1c836 100644 --- a/libc/functions/g/getpgrp.md +++ b/libc/functions/g/getpgrp.md @@ -1,10 +1,11 @@ -###Synopsis +# Synopsis + `#include ` `pid_t getpgrp(void);` -###Description +## Description -###Return value +## Return value -###Errors \ No newline at end of file +## Errors diff --git a/libc/functions/g/getpgrp.part-impl.md b/libc/functions/g/getpgrp.part-impl.md index 83226bea..4381c84e 100644 --- a/libc/functions/g/getpgrp.part-impl.md +++ b/libc/functions/g/getpgrp.part-impl.md @@ -1,30 +1,29 @@ -# Synopsis -`#include `
+# Synopsis -` pid_t getpgrp(void);`
+`#include ` + +`pid_t getpgrp(void);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `getpgrp()` function shall return the process group ID of the calling process. - ## Return value - The `getpgrp()` function shall always be successful and no return value is reserved to indicate an error. - ## Errors - No errors are defined. - ## Tests Untested @@ -33,6 +32,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getpid.md b/libc/functions/g/getpid.md index 00fd91c3..54eca754 100644 --- a/libc/functions/g/getpid.md +++ b/libc/functions/g/getpid.md @@ -1,10 +1,11 @@ -###Synopsis +# Synopsis + `#include ` `pid_t getpid(void);` -###Description +## Description -###Return value +## Return value -###Errors \ No newline at end of file +## Errors diff --git a/libc/functions/g/getpid.part-impl.md b/libc/functions/g/getpid.part-impl.md index 63b4cab2..80e6cc97 100644 --- a/libc/functions/g/getpid.part-impl.md +++ b/libc/functions/g/getpid.part-impl.md @@ -1,30 +1,29 @@ -# Synopsis -`#include `
+# Synopsis -` pid_t getpid(void);`
+`#include ` + +`pid_t getpid(void);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `getpid()` function shall return the process ID of the calling process. - ## Return value - The `getpid()` function shall always be successful and no return value is reserved to indicate an error. - ## Errors - No errors are defined. - ## Tests Untested @@ -33,6 +32,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getppid.md b/libc/functions/g/getppid.md index a06b8130..fb393195 100644 --- a/libc/functions/g/getppid.md +++ b/libc/functions/g/getppid.md @@ -1,10 +1,11 @@ -###Synopsis +# Synopsis + `#include ` `pid_t getppid(void);` -###Description +## Description -###Return value +## Return value -###Errors \ No newline at end of file +## Errors diff --git a/libc/functions/g/getppid.part-impl.md b/libc/functions/g/getppid.part-impl.md index 29e0c9cf..f52d0b9d 100644 --- a/libc/functions/g/getppid.part-impl.md +++ b/libc/functions/g/getppid.part-impl.md @@ -1,32 +1,29 @@ -# Synopsis -`#include `
+# Synopsis -` pid_t getppid(void);`
+`#include ` + +`pid_t getppid(void);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `getppid()` function shall return the parent process ID of the calling process. - ## Return value - The `getppid()` function shall always be successful and no return value is reserved to indicate an error. - ## Errors - No errors are defined. - - - ## Tests Untested @@ -35,6 +32,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getpwnam.md b/libc/functions/g/getpwnam.md index 8be84fdf..f614c7ef 100644 --- a/libc/functions/g/getpwnam.md +++ b/libc/functions/g/getpwnam.md @@ -1,10 +1,11 @@ -###Synopsis +# Synopsis + `#include ` `struct passwd *getpwnam(const char *name);` -###Description +## Description -###Return value +## Return value -###Errors \ No newline at end of file +## Errors diff --git a/libc/functions/g/getpwnam.part-impl.md b/libc/functions/g/getpwnam.part-impl.md index b61aa96c..64155345 100644 --- a/libc/functions/g/getpwnam.part-impl.md +++ b/libc/functions/g/getpwnam.part-impl.md @@ -1,17 +1,20 @@ -# Synopsis -`#include `
+# Synopsis -` struct passwd *getpwnam(const char *name);`
+`#include ` -` int getpwnam_r(const char *name, struct passwd *pwd, char *buffer,`
-`        size_t bufsize, struct passwd **result);`
+`struct passwd *getpwnam(const char *name);` + +`int getpwnam_r(const char *name, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `getpwnam()` function shall search the user database for an entry with a matching _name_. @@ -21,44 +24,42 @@ Applications wishing to check for error situations should set `errno` to `0` bef `getpwnam()` returns a `null` pointer and `errno` is non-zero, an error occurred. The ``getpwnam_r()`` function shall update the passwd structure pointed to by _pwd_ and store a pointer to that -structure at the location pointed to by _result_. The structure shall contain an entry from the user database with a matching -_name_. Storage referenced by the structure is allocated from the memory provided with the _buffer_ parameter, which is -_bufsize_ bytes in size. A call to `sysconf(_SC_GETPW_R_SIZE_MAX)` returns either `-1` without changing `errno` or an -initial value suggested for the size of this buffer. A `null` pointer shall be returned at the location pointed to by _result_ -on error or if the requested entry is not found. - +structure at the location pointed to by _result_. The structure shall contain an entry from the user database with a +matching _name_. Storage referenced by the structure is allocated from the memory provided with the _buffer_ parameter, +which is _bufsize_ bytes in size. A call to `sysconf(_SC_GETPW_R_SIZE_MAX)` returns either `-1` without changing `errno` +or an initial value suggested for the size of this buffer. A `null` pointer shall be returned at the location pointed to +by _result_ on error or if the requested entry is not found. ## Return value -The `getpwnam()` function shall return a pointer to a struct passwd with the structure as defined in `` with a matching entry if found. A `null` pointer shall be returned if the requested entry is not found, or an error occurs. If the requested entry was not found, `errno` shall not be changed. On error, `errno` shall be set to indicate the error. +The `getpwnam()` function shall return a pointer to a struct passwd with the structure as defined in `` with a +matching entry if found. A `null` pointer shall be returned if the requested entry is not found, or an error occurs. If +the requested entry was not found, `errno` shall not be changed. On error, `errno` shall be set to indicate the error. -The application shall not modify the structure to which the return value points, nor any storage areas pointed to by pointers within the structure. The returned pointer, and pointers within the structure, might be invalidated or the structure or the storage areas might be overwritten by a subsequent call to `getpwent()`, `getpwnam()`, or `getpwuid()`. The returned pointer, and pointers within the structure, might also be invalidated if the calling thread is terminated. +The application shall not modify the structure to which the return value points, nor any storage areas pointed to by +pointers within the structure. The returned pointer, and pointers within the structure, might be invalidated or the +structure or the storage areas might be overwritten by a subsequent call to `getpwent()`, `getpwnam()`, or `getpwuid()`. +The returned pointer, and pointers within the structure, might also be invalidated if the calling thread is terminated. -The `getpwnam_r()` function shall return zero on success or if the requested entry was not found and no error has occurred. If an error has occurred, an error number shall be returned to indicate the error. +The `getpwnam_r()` function shall return zero on success or if the requested entry was not found and no error has +occurred. If an error has occurred, an error number shall be returned to indicate the error. ## Errors - These functions may fail if: +* `EIO` - An I/O error has occurred. - * `EIO` - An I/O error has occurred. +* `EINTR` - A signal was caught during `getpwnam()`. - * `EINTR` - A signal was caught during `getpwnam()`. +* `EMFILE` - All file descriptors available to the process are currently open. - * `EMFILE` - All file descriptors available to the process are currently open. - - * `ENFILE` - The maximum allowable number of files is currently open in the system. +* `ENFILE` - The maximum allowable number of files is currently open in the system. The `getpwnam_r()` function may fail if: - - * `ERANGE` - Insufficient storage was supplied via _buffer_ and _bufsize_ to contain the data to be referenced by the resulting -`passwd` structure. - - - - +* `ERANGE` - Insufficient storage was supplied via _buffer_ and _bufsize_ to contain the data to be referenced by the + resulting `passwd` structure. ## Tests @@ -68,6 +69,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getpwuid.md b/libc/functions/g/getpwuid.md index 95ed8822..00f40424 100644 --- a/libc/functions/g/getpwuid.md +++ b/libc/functions/g/getpwuid.md @@ -1,10 +1,11 @@ -###Synopsis +# Synopsis + `#include ` `struct passwd *getpwuid(uid_t uid);` -###Description +## Description -###Return value +## Return value -###Errors \ No newline at end of file +## Errors diff --git a/libc/functions/g/getpwuid.part-impl.md b/libc/functions/g/getpwuid.part-impl.md index 68be76c5..1087c6b0 100644 --- a/libc/functions/g/getpwuid.part-impl.md +++ b/libc/functions/g/getpwuid.part-impl.md @@ -1,63 +1,66 @@ -# Synopsis -`#include `
+# Synopsis -` struct passwd *getpwuid(uid_t uid);`
+`#include ` -` int getpwuid_r(uid_t uid, struct passwd *pwd, char *buffer,`
-`        size_t bufsize, struct passwd **result);`
+`struct passwd *getpwuid(uid_t uid);` + +`int getpwuid_r(uid_t uid, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `getpwuid()` function shall search the user database for an entry with a matching _uid_. The `getpwuid()` function need not be thread-safe. -Applications wishing to check for error situations should set `errno` to `0` before calling `getpwuid()`. If -`getpwuid()` returns a `null` pointer and `errno` is set to non-zero, an error occurred. +Applications wishing to check for error situations should set `errno` to `0` before calling `getpwuid()`. +If `getpwuid()` returns a `null` pointer and `errno` is set to non-zero, an error occurred. The ``getpwuid_r()`` function shall update the passwd structure pointed to by _pwd_ and store a pointer to that -structure at the location pointed to by _result_. The structure shall contain an entry from the user database with a matching -_uid_. Storage referenced by the structure is allocated from the memory provided with the buffer parameter, which is -_bufsize_ bytes in size. A call to `sysconf(_SC_GETPW_R_SIZE_MAX)` returns either `-1` without changing `errno` or an -initial value suggested for the size of this buffer. A `null` pointer shall be returned at the location pointed to by _result_ -on error or if the requested entry is not found. - +structure at the location pointed to by _result_. The structure shall contain an entry from the user database with +a matching _uid_. Storage referenced by the structure is allocated from the memory provided with the buffer parameter, +which is _bufsize_ bytes in size. A call to `sysconf(_SC_GETPW_R_SIZE_MAX)` returns either `-1` without changing `errno` +or an initial value suggested for the size of this buffer. A `null` pointer shall be returned at the location pointed to +by _result_ on error or if the requested entry is not found. ## Return value -The getpwuid() function shall return a pointer to a struct passwd with the structure as defined in `` with a matching entry if found. A `null` pointer shall be returned if the requested entry is not found, or an error occurs. If the requested entry was not found, `errno` shall not be changed. On error, `errno` shall be set to indicate the error. +The getpwuid() function shall return a pointer to a struct passwd with the structure as defined in `` with a +matching entry if found. A `null` pointer shall be returned if the requested entry is not found, or an error occurs. +If the requested entry was not found, `errno` shall not be changed. On error, `errno` shall be set to indicate the +error. -The application shall not modify the structure to which the return value points, nor any storage areas pointed to by pointers within the structure. The returned pointer, and pointers within the structure, might be invalidated or the structure or the storage areas might be overwritten by a subsequent call to `getpwent()`, `getpwnam()`, or `getpwuid()`. The returned pointer, and pointers within the structure, might also be invalidated if the calling thread is terminated. +The application shall not modify the structure to which the return value points, nor any storage areas pointed to by +pointers within the structure. The returned pointer, and pointers within the structure, might be invalidated or the +structure or the storage areas might be overwritten by a subsequent call to `getpwent()`, `getpwnam()`, or `getpwuid()`. +The returned pointer, and pointers within the structure, might also be invalidated if the calling thread is terminated. -If successful, the `getpwuid_r()` function shall return zero, otherwise, an error number shall be returned to indicate the error. +If successful, the `getpwuid_r()` function shall return zero, otherwise, an error number shall be returned to indicate +the error. ## Errors - These functions may fail if: +* `EIO` - An I/O error has occurred. - * `EIO` - An I/O error has occurred. +* `EINTR` - A signal was caught during `getpwuid()`. - * `EINTR` - A signal was caught during `getpwuid()`. +* `EMFILE` - All file descriptors available to the process are currently open. - * `EMFILE` - All file descriptors available to the process are currently open. - - * `ENFILE` - The maximum allowable number of files is currently open in the system. +* `ENFILE` - The maximum allowable number of files is currently open in the system. The `getpwuid_r()` function may fail if: - - * `ERANGE` - Insufficient storage was supplied via buffer and _bufsize_ to contain the data to be referenced by the resulting passwd structure. - - - - +* `ERANGE` - Insufficient storage was supplied via buffer and _bufsize_ to contain the data to be referenced by the +resulting passwd structure. ## Tests @@ -67,6 +70,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/gets.md b/libc/functions/g/gets.md index 4f6ce332..fdb3753e 100644 --- a/libc/functions/g/gets.md +++ b/libc/functions/g/gets.md @@ -1,14 +1,15 @@ -###Synopsis +# Synopsis `#include ` `char *gets(char *str);` -###Description +## Description -* Reads a line from stdin and stores it into the string pointed to by, str. It stops when either the newline character is read - * or when the end-of-file is reached, whichever comes first. +* Reads a line from stdin and stores it into the string pointed to by, str. It stops when either the newline character +is read +* or when the end-of-file is reached, whichever comes first. -###Return value +## Return value -###Errors \ No newline at end of file +## Errors diff --git a/libc/functions/g/gets.part-impl.md b/libc/functions/g/gets.part-impl.md index 0eea0bf1..086f6171 100644 --- a/libc/functions/g/gets.part-impl.md +++ b/libc/functions/g/gets.part-impl.md @@ -1,37 +1,40 @@ -# Synopsis -`#include `
+# Synopsis -` char *gets(char *s); `
+`#include ` + +` char *gets(char *s); ` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The purpose is to get a string from a stdin stream. The `gets()` function shall read bytes from the standard input stream, `stdin`, into the array pointed to by _s_, -until a `` is read or an end-of-file condition is encountered. Any `` shall be discarded and a `null` byte -shall be placed immediately after the last byte read into the array. -The -`gets()` function may mark the last data access timestamp of the file associated with stream for update. The last data -access timestamp shall be marked for update by the first successful execution of `fgetc()`, `fgets()`, `fread()`, `fscanf()`, `getc()`, `getchar()`, `getdelim()`, `getline()`, `gets()`, or `scanf()` using stream that returns data not supplied by a prior call to `ungetc()`. +The purpose is to get a string from a stdin stream. The `gets()` function shall read bytes from the standard input +stream, `stdin`, into the array pointed to by _s_, until a `` is read or an end-of-file condition is +encountered. Any `` shall be discarded and a `null` byte shall be placed immediately after the last byte +read into the array. +The `gets()` function may mark the last data access timestamp of the file associated with stream for update. The last +data access timestamp shall be marked for update by the first successful execution of `fgetc()`, `fgets()`, `fread()`, +`fscanf()`, `getc()`, `getchar()`, `getdelim()`, `getline()`, `gets()`, or `scanf()` using stream that returns data not +supplied by a prior call to `ungetc()`. ## Return value - -Upon successful completion, `gets()` shall return _s_. If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end-of-file indicator for the stream shall be set and `gets()` shall return a `null` pointer. If a read error occurs, the error indicator for the stream shall be set, `gets()` shall return a `null` pointer, and set `errno` to indicate the error. - +Upon successful completion, `gets()` shall return _s_. If the end-of-file indicator for the stream is set, or if the +stream is at end-of-file, the end-of-file indicator for the stream shall be set and `gets()` shall return a `null` +pointer. If a read error occurs, the error indicator for the stream shall be set, `gets()` shall return a `null` +pointer, and set `errno` to indicate the error. ## Errors - Refer to [fgetc](../f/fgetc.part-impl.md). - - - ## Tests Untested @@ -40,6 +43,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/getsid.part-impl.md b/libc/functions/g/getsid.part-impl.md index 22a24be7..2e59c4d8 100644 --- a/libc/functions/g/getsid.part-impl.md +++ b/libc/functions/g/getsid.part-impl.md @@ -1,29 +1,35 @@ -# Synopsis -`#include `
+# Synopsis -`pid_t getsid(pid_t pid);`
+`#include ` + +`pid_t getsid(pid_t pid);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description -The `getsid()` function shall obtain the process group ID of the process that is the session leader of the process specified by _pid_. If _pid_ is `(pid_t)0`, it specifies the calling process. +The `getsid()` function shall obtain the process group ID of the process that is the session leader of the process +specified by _pid_. If _pid_ is `(pid_t)0`, it specifies the calling process. ## Return value -Upon successful completion, `getsid()` shall return the process group ID of the session leader of the specified process. Otherwise, it shall return `-1` and set `errno` to indicate the error. +Upon successful completion, `getsid()` shall return the process group ID of the session leader of the specified process. +Otherwise, it shall return `-1` and set `errno` to indicate the error. ## Errors - The getsid() function shall fail if: - * `EPERM` - The process specified by _pid_ is not in the same session as the calling process, and the implementation does not allow access to the process group ID of the session leader of that process from the calling process. - - * `ESRCH` - There is no process with a process ID equal to _pid_. +* `EPERM` - The process specified by _pid_ is not in the same session as the calling process, and the implementation + does not allow access to the process group ID of the session leader of that process from the calling process. +* `ESRCH` - There is no process with a process ID equal to _pid_. ## Tests @@ -33,6 +39,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/g/gettime.md b/libc/functions/g/gettime.md index 7946a796..d5cdcd45 100644 --- a/libc/functions/g/gettime.md +++ b/libc/functions/g/gettime.md @@ -1,11 +1,11 @@ -###Synopsis +# Synopsis `#include ` `int gettime(time_t *tp);` -###Description +## Description -###Return value +## Return value -###Errors \ No newline at end of file +## Errors diff --git a/libc/functions/g/getuid.md b/libc/functions/g/getuid.md index 3076f86b..4fa5a9de 100644 --- a/libc/functions/g/getuid.md +++ b/libc/functions/g/getuid.md @@ -1,10 +1,11 @@ -###Synopsis +# Synopsis + `#include ` `uid_t getuid(void);` -###Description +## Description -###Return value +## Return value -###Errors \ No newline at end of file +## Errors diff --git a/libc/functions/g/getuid.part-impl.md b/libc/functions/g/getuid.part-impl.md index f2d67392..f031dcd6 100644 --- a/libc/functions/g/getuid.part-impl.md +++ b/libc/functions/g/getuid.part-impl.md @@ -1,30 +1,30 @@ -# Synopsis -`#include `
+# Synopsis -` uid_t getuid(void);`
+`#include ` + +`uid_t getuid(void);` ## Status + Partially implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 -The `getuid()` function shall return the real user ID of the calling process. The `getuid()` function shall not modify `errno`. +## Description +The `getuid()` function shall return the real user ID of the calling process. The `getuid()` function shall not modify +`errno`. ## Return value - The `getuid()` function shall always be successful and no return value is reserved to indicate the error. - ## Errors - No errors are defined. - ## Tests Untested @@ -33,6 +33,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/i/ioctl.part-impl.md b/libc/functions/i/ioctl.part-impl.md index 692ac733..b6f1dbee 100644 --- a/libc/functions/i/ioctl.part-impl.md +++ b/libc/functions/i/ioctl.part-impl.md @@ -1,29 +1,38 @@ -# Synopsis -`#include `
+# Synopsis -` int ioctl(int fildes, int request, ... /* arg */);`
+`#include ` + +`int ioctl(int fildes, int request, ... /* arg */);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The `ioctl()` function shall perform a variety of control functions on devices. For _fildes_ not referring to devices, the functions performed by this call are unspecified. +The `ioctl()` function shall perform a variety of control functions on devices. For _fildes_ not referring to devices, +the functions performed by this call are unspecified. The _fildes_ argument is an open file descriptor that refers to a device. The _request_ argument selects the control function to be performed and shall depend on the device being addressed. -The _arg_ argument represents additional information that is needed by this specific device to perform the requested function. The type of _arg_ depends upon the particular control request, but it shall be either an integer or a pointer to a device-specific data structure. +The _arg_ argument represents additional information that is needed by this specific device to perform the requested +function. The type of _arg_ depends upon the particular control request, but it shall be either an integer or a pointer +to a device-specific data structure. -In order to define driver request one should use one of the macros presented below, which are available in the `ioctl.h` header file: +In order to define driver request one should use one of the macros presented below, which are available in the `ioctl.h` +header file: -- `_IOC(inout,group,num,len)` - macro which returns every possible request +- `_IOC(inout,group,num,len)` - macro which returns every possible request - `inout` - use these defines: `IOC_VOID` (no data), `IOC_OUT` (read), `IOC_IN` (write), `IOC_INOUT` (read/write) - - `group` - describe group type (collecting the ioctls in groups for a common purpose or a common driver e.g. `'S'` for sockets), 8-bit value + - `group` - describe group type (collecting the ioctls in groups for a common purpose or a common driver e.g. `'S'` + for sockets), 8-bit value - `num` - specifies serial number of request, 8 -bit value - `len` - how big is size of data, 14-bit value @@ -42,36 +51,32 @@ There are also some checking macros: - `IOCBASECMD(x)` - returns base command value (2 least significant bytes describing group and serial number) - `IOCGROUP(x)` - returns group type value -The resulting request will be in such form: 2 bits describe direction (`00`: none, `10`: write, `01`: read, `11`: read/write) followed by 14 size bits, followed by an 8-bit group type (collecting the ioctls in groups for a common purpose or a common driver) and an 8-bit serial number. +The resulting request will be in such form: 2 bits describe direction (`00`: none, `10`: write, `01`: read, `11`: +read/write) followed by 14 size bits, followed by an 8-bit group type (collecting the ioctls in groups for a common +purpose or a common driver) and an 8-bit serial number. It is worth to note that to get data sent to driver inside message, one should use `ioctl_unapck()`. -Also, if you are willing to pass structure with pointer in _arg_ argument of `ioctl()` you -should custom pack your message in `ioctl_pack()` (see ioctl_pack() implementation). - +Also, if you are willing to pass structure with pointer in _arg_ argument of `ioctl()` you should custom pack your +message in `ioctl_pack()` (see ioctl_pack() implementation). ## Return value - -Upon successful completion, `ioctl()` shall return a value other than `-1` that depends on the device control function. Otherwise, it shall return `-1` and set `errno` to indicate the error. - +Upon successful completion, `ioctl()` shall return a value other than `-1` that depends on the device control function. +Otherwise, it shall return `-1` and set `errno` to indicate the error. ## Errors - The `ioctl()` function may fail if: +- `EBADF` - The _fildes_ argument is not a valid open file descriptor. - * `EBADF` - The _fildes_ argument is not a valid open file descriptor. - - * `ENOSYS` - Couldn't get information about calling process. - - * `EINVAL` - Tried to send message to invalid port. +- `ENOSYS` - Couldn't get information about calling process. +- `EINVAL` - Tried to send message to invalid port. ## Example usage - ```C #include #include @@ -97,7 +102,6 @@ int main() { } ``` - ## Tests Tested @@ -106,6 +110,7 @@ Tested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/i/isatty.part-impl.md b/libc/functions/i/isatty.part-impl.md index a11a94d1..ff144b2a 100644 --- a/libc/functions/i/isatty.part-impl.md +++ b/libc/functions/i/isatty.part-impl.md @@ -1,39 +1,33 @@ -# Synopsis -`#include `
+# Synopsis -` int isatty(int fildes);`
+`#include ` + +`int isatty(int fildes);` ## Status + Partially implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 -The `isatty()` function shall test whether fildes, an open file descriptor, is associated with a terminal -device. +## Description +The `isatty()` function shall test whether fildes, an open file descriptor, is associated with a terminal device. ## Return value - The `isatty()` function shall return 1 if fildes is associated with a terminal; otherwise, it shall return 0 and may set errno to indicate the error. - ## Errors - The `isatty()` function may fail if: +* `EBADF` - The fildes argument is not a valid open file descriptor. - * `EBADF` - The fildes argument is not a valid open file descriptor. - - * `ENOTTY` - The file associated with the fildes argument is not a terminal. - - - - +* `ENOTTY` - The file associated with the fildes argument is not a terminal. ## Tests @@ -43,6 +37,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/k/kill.part-impl.md b/libc/functions/k/kill.part-impl.md index 23c4f021..866b9476 100644 --- a/libc/functions/k/kill.part-impl.md +++ b/libc/functions/k/kill.part-impl.md @@ -1,22 +1,27 @@ -# Synopsis -`#include `
+# Synopsis -` int kill(pid_t pid, int sig); `
+`#include ` + +` int kill(pid_t pid, int sig); ` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The `kill()` function shall send a signal to a process or a group of processes specified by _pid_. The signal to be -sent is specified by _sig_ and is either one from the list given in `` or 0. If _sig_ is `0` (the `null` signal), error checking is performed but -no signal is actually sent. The `null` signal can be used to check the validity of _pid_. +The `kill()` function shall send a signal to a process or a group of processes specified by _pid_. The signal to be sent +is specified by _sig_ and is either one from the list given in `` or 0. If _sig_ is `0` (the `null` signal), +error checking is performed but no signal is actually sent. The `null` signal can be used to check the validity of +_pid_. For a process to have permission to send a signal to a process designated by _pid_, unless the sending process has -appropriate privileges, the real or effective user ID of the sending process shall match the real or saved set-user-ID of the -receiving process. +appropriate privileges, the real or effective user ID of the sending process shall match the real or saved set-user-ID +of the receiving process. If _pid_ is greater than `0`, _sig_ shall be sent to the process whose process ID is equal to _pid_. @@ -27,45 +32,37 @@ If _pid_ is `-1`, _sig_ shall be sent to all processes (excluding an unspecified process has permission to send that signal. If _pid_ is negative, but not `-1`, _sig_ shall be sent to all processes (excluding an unspecified set of system -processes) whose process group ID is equal to the absolute value of _pid_, and for which the process has permission to send a -signal. +processes) whose process group ID is equal to the absolute value of _pid_, and for which the process has permission +to send a signal. -If the value of _pid_ causes _sig_ to be generated for the sending process, and if _sig_ is not blocked for the -calling thread and if no other thread has _sig_ unblocked or is waiting in a `sigwait()` function for _sig_, either _sig_ or at least one pending unblocked -signal shall be delivered to the sending thread before `kill()` returns. +If the value of _pid_ causes _sig_ to be generated for the sending process, and if _sig_ is not blocked for the calling +thread and if no other thread has _sig_ unblocked or is waiting in a `sigwait()` function for _sig_, either _sig_ or at +least one pending unblocked signal shall be delivered to the sending thread before `kill()` returns. -The user ID tests described above shall not be applied when sending `SIGCONT` to a process that is a member of the same session as -the sending process. +The user ID tests described above shall not be applied when sending `SIGCONT` to a process that is a member of the same +session as the sending process. -An implementation that provides extended security controls may impose further implementation-defined restrictions on the sending -of signals, including the `null` signal. In particular, the system may deny the existence of some or all of the processes specified -by _pid_. +An implementation that provides extended security controls may impose further implementation-defined restrictions on the +sending of signals, including the `null` signal. In particular, the system may deny the existence of some or all of the +processes specified by _pid_. The `kill()` function is successful if the process has permission to send _sig_ to any of the processes specified by _pid_. If `kill()` fails, no signal shall be sent. - ## Return value - -Upon successful completion, `0` shall be returned. Otherwise, `-1` shall be returned and errno set to indicate the error. - +Upon successful completion, `0` shall be returned. Otherwise, `-1` shall be returned and errno set to indicate the +error. ## Errors - The `kill()` function shall fail if: +* `EINVAL` - The value of the _sig_ argument is an invalid or unsupported signal number. - * `EINVAL` - The value of the _sig_ argument is an invalid or unsupported signal number. - - * `EPERM` - The process does not have permission to send the signal to any receiving process. - - * `ESRCH` - No process or process group can be found corresponding to that specified by _pid_. - - - +* `EPERM` - The process does not have permission to send the signal to any receiving process. +* `ESRCH` - No process or process group can be found corresponding to that specified by _pid_. ## Tests @@ -75,6 +72,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/l/labs.part-impl.md b/libc/functions/l/labs.part-impl.md index 3591ea40..4817b086 100644 --- a/libc/functions/l/labs.part-impl.md +++ b/libc/functions/l/labs.part-impl.md @@ -1,37 +1,34 @@ -# Synopsis -`#include `
+# Synopsis -` long labs(long i);`
+`#include ` -` long long llabs(long long i);`
+`long labs(long i);` + +`long long llabs(long long i);` ## Status + Partially implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 -The `llabs()` function shall compute the absolute value of the long long integer operand _i_. If the result cannot be represented, -the behavior is undefined. +## Description +The `llabs()` function shall compute the absolute value of the long long integer operand _i_. If the result cannot be +represented, the behavior is undefined. ## Return value - The `labs()` function shall return the absolute value of the long integer operand. The `llabs()` function shall return the absolute value of the long long integer operand. - ## Errors - No errors are defined. - - - ## Tests Untested @@ -40,6 +37,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/l/ldexp.part-impl.md b/libc/functions/l/ldexp.part-impl.md index 59ed1fee..261a255a 100644 --- a/libc/functions/l/ldexp.part-impl.md +++ b/libc/functions/l/ldexp.part-impl.md @@ -1,67 +1,62 @@ -# Synopsis -`#include `
+# Synopsis -` double ldexp(double x, int exp);`
+`#include ` -` float ldexpf(float x, int exp);`
+`double ldexp(double x, int exp);` -` long double ldexpl(long double x, int exp);`
+`float ldexpf(float x, int exp);` + +`long double ldexpl(long double x, int exp);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description - These functions shall compute the quantity `x * 2^exp`. -An application wishing to check for error situations should set `errno` to zero and call -`feclearexcept(FE_ALL_EXCEPT)` before calling these functions. On return, if errno is non-zero or +An application wishing to check for error situations should set `errno` to zero and call `feclearexcept(FE_ALL_EXCEPT)` +before calling these functions. On return, if errno is non-zero or `fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)` is non-zero, an error has occurred. - ## Return value - Upon successful completion, these functions shall return _x_ multiplied by `2`, raised to the power _exp_. -If these functions would cause overflow, a range error shall occur and `ldexp()`, `ldexpf()`, and `ldexpl()` -shall return `±HUGE_VAL`, `±HUGE_VALF`, and `±HUGE_VALL` (according to the sign of _x_), respectively. - -If the correct value would cause underflow,  and is not representable,  a range error may occur, and `ldexp()`, `ldexpf()`, and `ldexpl()` shall return -`0.0`, or  (if IEC 60559 Floating-Point is not supported) -an implementation-defined value no greater in magnitude than `DBL_MIN`, `FLT_MIN`, and `LDBL_MIN`, respectively. - -If _x_ is `NaN`, a `NaN` shall be returned. - -If _x_ is `±0` or `±Inf`, _x_ shall be returned. - -If _exp_ is `0`, _x_ shall be returned. -If the correct value would cause underflow, and is representable, a range error may occur and the correct value shall be returned. +If these functions would cause overflow, a range error shall occur and `ldexp()`, `ldexpf()`, and `ldexpl()` shall +return `±HUGE_VAL`, `±HUGE_VALF`, and `±HUGE_VALL` (according to the sign of _x_), respectively. +If the correct value would cause underflow,  and is not representable,  a range error may occur, and `ldexp()`, +`ldexpf()`, and `ldexpl()` shall return `0.0`, or  (if IEC 60559 Floating-Point is not supported) an +implementation-defined value no greater in magnitude than `DBL_MIN`, `FLT_MIN`, and `LDBL_MIN`, respectively. +* If _x_ is `NaN`, a `NaN` shall be returned. +* If _x_ is `±0` or `±Inf`, _x_ shall be returned. +* If _exp_ is `0`, _x_ shall be returned. +* If the correct value would cause underflow, and is representable, a range error may occur and the correct value + shall be returned. ## Errors - These functions shall fail if: - * `Range Error` - The result overflows.
+* `Range Error` - The result overflows. If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If -the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the overflow floating-point exception shall -be raised. - +the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the overflow floating-point +exception shall be raised. These functions may fail if: - * `Range Error` - The result underflows.
+* `Range Error` - The result underflows. If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then errno shall be set to `ERANGE`. If the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the underflow floating-point exception shall be raised. - ## Tests Untested @@ -70,6 +65,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/l/ldiv.part-impl.md b/libc/functions/l/ldiv.part-impl.md index 48983c65..aa6a9c58 100644 --- a/libc/functions/l/ldiv.part-impl.md +++ b/libc/functions/l/ldiv.part-impl.md @@ -1,52 +1,48 @@ -# Synopsis -`#include `
+# Synopsis -` ldiv_t ldiv(long numer, long denom);`
+`#include ` -` lldiv_t lldiv(long long numer, long long denom);`
+`ldiv_t ldiv(long numer, long denom);` + +`lldiv_t lldiv(long long numer, long long denom);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description - These functions shall compute the quotient and remainder of the division of the numerator _numer_ by the denominator -_denom_. If the division is inexact, the resulting quotient is the long integer (for the `ldiv()` function) or -long long integer (for the `lldiv()` function) of lesser magnitude that is the nearest to the algebraic quotient. If -the result cannot be represented, the behavior is undefined; otherwise, quot * denom+rem shall equal -_numer_. - +_denom_. If the division is inexact, the resulting quotient is the long integer (for the `ldiv()` function) or long +long integer (for the `lldiv()` function) of lesser magnitude that is the nearest to the algebraic quotient. If the +result cannot be represented, the behavior is undefined; otherwise, quot * denom+rem shall equal _numer_. ## Return value +The `ldiv()` function shall return a structure of type `ldiv_t`, comprising both the quotient and the remainder. +The structure shall include the following members, in any order: -The `ldiv()` function shall return a structure of type `ldiv_t`, comprising both the quotient and the remainder. The -structure shall include the following members, in any order: ```c long quot; /* Quotient */ long rem; /* Remainder */ ``` -The `lldiv()` function shall return a structure of type `lldiv_t`, comprising both the quotient and the remainder. The -structure shall include the following members, in any order: +The `lldiv()` function shall return a structure of type `lldiv_t`, comprising both the quotient and the remainder. +The structure shall include the following members, in any order: + ```c long long quot; /* Quotient */ long long rem; /* Remainder */ ``` - - ## Errors - No errors are defined. - - - ## Tests Untested @@ -55,6 +51,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/l/link.part-impl.md b/libc/functions/l/link.part-impl.md index 48612053..d5f21a64 100644 --- a/libc/functions/l/link.part-impl.md +++ b/libc/functions/l/link.part-impl.md @@ -1,34 +1,38 @@ -# Synopsis -`#include `
+# Synopsis -` int link(const char *path1, const char *path2);`
+`#include ` -`#include `
+`int link(const char *path1, const char *path2);` -` int linkat(int fd1, const char *path1, int fd2, const char *path2, int flag);`
+`#include ` + +`int linkat(int fd1, const char *path1, int fd2, const char *path2, int flag);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `link()` function shall create a new link (directory entry) for the existing file, _path1_. -The _path1_ argument points to a pathname naming an existing file. The _path2_ argument points to a pathname naming -the new directory entry to be created. The `link()` function shall atomically create a new link for the existing file and the -link count of the file shall be incremented by one. +The _path1_ argument points to a pathname naming an existing file. The _path2_ argument points to a pathname naming the +new directory entry to be created. The `link()` function shall atomically create a new link for the existing file and +the link count of the file shall be incremented by one. If _path1_ names a directory, `link()` shall fail unless the process has appropriate privileges and the implementation supports using `link()` on directories. -If _path1_ names a symbolic link, it is implementation-defined whether `link()` follows the symbolic link, or creates -a new link to the symbolic link itself. +If _path1_ names a symbolic link, it is implementation-defined whether `link()` follows the symbolic link, or creates a +new link to the symbolic link itself. Upon successful completion, `link()` shall mark for update the last file status change timestamp of the file. Also, the -last data modification and last file status change timestamps of the directory that contains the new entry shall be marked for -update. +last data modification and last file status change timestamps of the directory that contains the new entry shall be +marked for update. If `link()` fails, no link shall be created and the link count of the file shall remain unchanged. @@ -36,12 +40,12 @@ The implementation may require that the calling process has permission to access The `linkat()` function shall be equivalent to the `link()` function except that symbolic links shall be handled as specified by the value of _flag_ (see below) and except in the case where either _path1_ or _path2_ or both are -relative paths. In this case a relative path _path1_ is interpreted relative to the directory associated with the file -descriptor _fd1_ instead of the current working directory and similarly for _path2_ and the file descriptor _fd2_. +relative paths. In this case a relative path _path1_ is interpreted relative to the directory associated with the +file descriptor _fd1_ instead of the current working directory and similarly for _path2_ and the file descriptor _fd2_. -If the access mode of the open file description associated with the file descriptor is not `O_SEARCH,` the function shall check -whether directory searches are permitted using the current permissions of the directory underlying the file descriptor. If the -access mode is `O_SEARCH,` the function shall not perform the check. +If the access mode of the open file description associated with the file descriptor is not `O_SEARCH,` the function +shall check whether directory searches are permitted using the current permissions of the directory underlying the +file descriptor. If the access mode is `O_SEARCH,` the function shall not perform the check. Values for _flag_ are constructed by a bitwise-inclusive OR of flags from the following list, defined in ``: @@ -56,89 +60,76 @@ identical to a call to `link()`, except that symbolic links shall be handled as If the `AT_SYMLINK_FOLLOW` flag is clear in the _flag_ argument and the _path1_ argument names a symbolic link, a new link is created for the symbolic link _path1_ and not its target. - ## Return value - -Upon successful completion, these functions shall return `0`. Otherwise, these functions shall return `-1` and set `errno` to -indicate the error. - - +Upon successful completion, these functions shall return `0`. Otherwise, these functions shall return `-1` and set +`errno` to indicate the error. ## Errors - These functions shall fail if: +* `EACCES` - A component of either path prefix denies search permission, or the requested link requires writing in a + directory that denies write permission, or the calling process does not have permission to access the existing file + and this is required by the implementation. - * `EACCES` - A component of either path prefix denies search permission, or the requested link requires writing in a directory that denies -write permission, or the calling process does not have permission to access the existing file and this is required by the -implementation. +* `EEXIST` - The _path2_ argument resolves to an existing directory entry or refers to a symbolic link. - * `EEXIST` - The _path2_ argument resolves to an existing directory entry or refers to a symbolic link. +* `ELOOP` - A loop exists in symbolic links encountered during resolution of the _path1_ or _path2_ argument. - * `ELOOP` - A loop exists in symbolic links encountered during resolution of the _path1_ or _path2_ argument. +* `EMLINK` - The number of links to the file named by _path1_ would exceed `LINK_MAX`. - * `EMLINK` - The number of links to the file named by _path1_ would exceed `LINK_MAX`. +* `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. - * `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. +* `ENOENT` - A component of either path prefix does not exist; the file named by _path1_ does not exist; or _path1_ or + _path2_ points to an empty string. - * `ENOENT` - A component of either path prefix does not exist; the file named by _path1_ does not exist; or _path1_ or -_path2_ points to an empty string. -`ENOENT` or `ENOTDIR` +* `ENOENT` or `ENOTDIR` - The _path1_ argument names an existing non-directory file, and the _path2_ argument contains + at least one non - `` character and ends with one or more trailing `` characters. If _path2_ without the + trailing `` characters would name an existing file, an `ENOENT` error shall not occur. -The _path1_ argument names an existing non-directory file, and the _path2_ argument contains at least one non- -`` character and ends with one or more trailing `` characters. If _path2_ without the trailing -`` characters would name an existing file, an `ENOENT` error shall not occur. +* `ENOSPC` - The directory to contain the link cannot be extended. - * `ENOSPC` - The directory to contain the link cannot be extended. +* `ENOTDIR` - A component of either path prefix names an existing file that is neither a directory nor a symbolic link + to a directory, or the _path1_ argument contains at least one non- `` character and ends with one or more + trailing `` characters and the last pathname component names an existing file that is neither a directory nor a + symbolic link to a directory, or the _path1_ argument names an existing non-directory file and the _path2_ argument + names a nonexistent file, contains at least one non- `` character, and ends with one or more trailing `` + characters. - * `ENOTDIR` - A component of either path prefix names an existing file that is neither a directory nor a symbolic link to a directory, or the -_path1_ argument contains at least one non- `` character and ends with one or more trailing `` -characters and the last pathname component names an existing file that is neither a directory nor a symbolic link to a directory, -or the _path1_ argument names an existing non-directory file and the _path2_ argument names a nonexistent file, contains -at least one non- `` character, and ends with one or more trailing `` characters. +* `EPERM` - The file named by _path1_ is a directory and either the calling process does not have appropriate + privileges or the implementation prohibits using `link()` on directories. - * `EPERM` - The file named by _path1_ is a directory and either the calling process does not have appropriate privileges or the -implementation prohibits using `link()` on directories. +* `EROFS` - The requested link requires writing in a directory on a read-only file system. - * `EROFS` - The requested link requires writing in a directory on a read-only file system. - - * `EXDEV` - The link named by _path2_ and the file named by _path1_ are on different file systems and the implementation does not +* `EXDEV` - The link named by _path2_ and the file named by _path1_ are on different file systems and the + implementation does not support links between file systems. - * `EXDEV` - _path1_ refers to a named `STREAM`. +* `EXDEV` - _path1_ refers to a named `STREAM`. The `linkat()` function shall fail if: +* `EACCES` - The access mode of the open file description associated with _fd1_ or _fd2_ is not O_SEARCH and the + permissions of the directory underlying _fd1_ or _fd2_, respectively, do not permit directory searches. - * `EACCES` - The access mode of the open file description associated with _fd1_ or _fd2_ is not O_SEARCH and the permissions of -the directory underlying _fd1_ or _fd2_, respectively, do not permit directory searches. - - * `EBADF` - The _path1_ or _path2_ argument does not specify an absolute path and the _fd1_ or _fd2_ argument, -respectively, is neither AT_FDCWD nor a valid file descriptor open for reading or searching. +* `EBADF` - The _path1_ or _path2_ argument does not specify an absolute path and the _fd1_ or _fd2_ argument, + respectively, is neither AT_FDCWD nor a valid file descriptor open for reading or searching. - * `ENOTDIR` - The _path1_ or _path2_ argument is not an absolute path and _fd1_ or _fd2_, respectively, is a file -descriptor associated with a non-directory file. +* `ENOTDIR` - The _path1_ or _path2_ argument is not an absolute path and _fd1_ or _fd2_, respectively, is a file + descriptor associated with a non-directory file. These functions may fail if: +* `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the _path1_ or _path2_ + argument. - * `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the _path1_ or _path2_ argument. -`ENAMETOOLONG` - -The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an intermediate result with a -length that exceeds `PATH_MAX`. - +* `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an + intermediate result with a length that exceeds `PATH_MAX`. The `linkat()` function may fail if: - - * `EINVAL` - The value of the _flag_ argument is not valid. - - - - +* `EINVAL` - The value of the _flag_ argument is not valid. ## Tests @@ -148,6 +139,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/l/log.part-impl.md b/libc/functions/l/log.part-impl.md index 3d3134d9..e42e093d 100644 --- a/libc/functions/l/log.part-impl.md +++ b/libc/functions/l/log.part-impl.md @@ -1,20 +1,23 @@ -# Synopsis -`#include `
+# Synopsis -` double log(double x);`
+`#include ` -` float logf(float x);`
+`double log(double x);` -` long double logl(long double x);`
+`float logf(float x);` + +`long double logl(long double x);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description - These functions shall compute the natural logarithm of their argument _x_, `loge(x)`. @@ -22,39 +25,33 @@ An application wishing to check for error situations should set `errno` to zero `feclearexcept(FE_ALL_EXCEPT)` before calling these functions. On return, if `errno` is non-zero or `fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)` is non-zero, an error has occurred. - ## Return value - Upon successful completion, these functions shall return the natural logarithm of _x_. -If _x_ is `±0`, a pole error shall occur and `log()`, `logf()`, and `logl()` shall return `-HUGE_VAL`, -`-HUGE_VALF`, and `-HUGE_VALL`, respectively. +If _x_ is `±0`, a pole error shall occur and `log()`, `logf()`, and `logl()` shall return `-HUGE_VAL`, `-HUGE_VALF`, +and `-HUGE_VALL`, respectively. -For finite values of _x_ that are less than `0`,  or if _x_ is `-Inf`, a domain error shall occur, and  either a `NaN` (if supported), or  an implementation-defined value shall be returned. +For finite values of _x_ that are less than `0`,  or if _x_ is `-Inf`, a domain error shall occur, and either a +`NaN` (if supported), or  an implementation-defined value shall be returned. If _x_ is `NaN`, a `NaN` shall be returned. If _x_ is `1`, `+0` shall be returned. -If _x_ is `+Inf`, _x_ shall be returned. - +If _x_ is `+Inf`, _x_ shall be returned. ## Errors - These functions shall fail if: - * `Domain Error` - The finite value of _x_ is negative,  or _x_ is `-Inf`. -If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `EDOM`. If -the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the invalid floating-point exception shall -be raised. - - * `Pole Error` - The value of _x_ is zero. -If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If -the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the divide-by-zero floating-point exception -shall be raised. +* `Domain Error` - The finite value of _x_ is negative,  or _x_ is `-Inf`. If the integer expression + `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `EDOM`. If the integer expression + `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the invalid floating-point exception shall be raised. +* `Pole Error` - The value of _x_ is zero. If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, + then `errno` shall be set to `ERANGE`. If the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, + then the divide-by-zero floating-point exception shall be raised. ## Tests @@ -64,6 +61,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/l/log10.part-impl.md b/libc/functions/l/log10.part-impl.md index e4746934..6acd890b 100644 --- a/libc/functions/l/log10.part-impl.md +++ b/libc/functions/l/log10.part-impl.md @@ -1,64 +1,56 @@ -# Synopsis -`#include `
+# Synopsis -` double log10(double x);`
+`#include ` -` float log10f(float x);`
+`double log10(double x);` -` long double log10l(long double x);`
+`float log10f(float x);` + +`long double log10l(long double x);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description - These functions shall compute the base 10 logarithm of their argument _x_, `log10(x)`. -An application wishing to check for error situations should set `errno` to zero and call -`feclearexcept(FE_ALL_EXCEPT)` before calling these functions. On return, if `errno` is non-zero or +An application wishing to check for error situations should set `errno` to zero and call `feclearexcept(FE_ALL_EXCEPT)` +before calling these functions. On return, if `errno` is non-zero or `fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)` is non-zero, an error has occurred. - ## Return value - Upon successful completion, these functions shall return the base 10 logarithm of _x_. -If _x_ is `±0`, a pole error shall occur and `log10()`, `log10f()`, and `log10l()` shall return -`-HUGE_VAL`, `-HUGE_VALF`, and `-HUGE_VALL`, respectively. - -For finite values of _x_ that are less than `0`,  or if _x_ is `-Inf`, a domain error shall occur, and  either a `NaN` (if supported), or  an implementation-defined value shall be returned. -If -_x_ is `NaN`, a `NaN` shall be returned. - -If _x_ is `1`, `+0` shall be returned. +* If _x_ is `±0`, a pole error shall occur and `log10()`, `log10f()`, and `log10l()` shall return `-HUGE_VAL`, +`-HUGE_VALF`, and `-HUGE_VALL`, respectively. -If _x_ is `+Inf`, `+Inf` shall be returned. +For finite values of _x_ that are less than `0`,  or if _x_ is `-Inf`, a domain error shall occur, and  either a +`NaN` (if supported), or  an implementation-defined value shall be returned. +* If _x_ is `NaN`, a `NaN` shall be returned. +* If _x_ is `1`, `+0` shall be returned. +* If _x_ is `+Inf`, `+Inf` shall be returned. ## Errors - These functions shall fail if: - * `Domain Error` - The finite value of _x_ is negative,  or _x_ is -Inf.
+* `Domain Error` - The finite value of _x_ is negative,  or _x_ is -Inf. If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `EDOM`. If -the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the invalid floating-point exception shall -be raised. - - * `Pole Error` - -The value of _x_ is zero.
-If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If -the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the divide-by-zero floating-point exception +the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the invalid floating-point exception shall be raised. - - - - +* `Pole Error` - The value of _x_ is zero. +If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If +the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the divide-by-zero floating-point +exception shall be raised. ## Tests @@ -68,6 +60,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/l/longjmp.part-impl.md b/libc/functions/l/longjmp.part-impl.md index 4e158073..9b29df74 100644 --- a/libc/functions/l/longjmp.part-impl.md +++ b/libc/functions/l/longjmp.part-impl.md @@ -1,68 +1,54 @@ -# Synopsis -`#include `
+# Synopsis -` void longjmp(jmp_buf env, int val);`
+`#include ` -## Status -Partially implemented -## Conformance -IEEE Std 1003.1-2017 -## Description - - - -The `longjmp()` function shall restore the environment saved by the most recent invocation of `setjmp()` in the same process, with the corresponding `jmp_buf` argument. If the most -recent invocation of `setjmp()` with the corresponding `jmp_buf` occurred in -another thread, or if there is no such invocation, or if the function containing the invocation of `setjmp()` has terminated execution in the interim, or if the invocation of `setjmp()` was within the scope of an identifier with variably modified type and execution has -left that scope in the interim, the behavior is undefined.  It is unspecified whether `longjmp()` restores the signal -mask, leaves the signal mask unchanged, or restores it to its value at the time `setjmp()` was called. -All accessible objects have values, and all other components of the abstract machine have state (for example, floating-point -status flags and open files), as of the time `longjmp()` was called, except that the values of objects of automatic storage -duration are unspecified if they meet all the following conditions: +`void longjmp(jmp_buf env, int val);` +## Status +Partially implemented -* They are local to the function containing the corresponding `setjmp()` - invocation. +## Conformance +IEEE Std 1003.1-2017 +## Description +The `longjmp()` function shall restore the environment saved by the most recent invocation of `setjmp()` in the same +process, with the corresponding `jmp_buf` argument. If the most recent invocation of `setjmp()` with the corresponding +`jmp_buf` occurred in another thread, or if there is no such invocation, or if the function containing the invocation of +`setjmp()` has terminated execution in the interim, or if the invocation of `setjmp()` was within the scope of an +identifier with variably modified type and execution has left that scope in the interim, the behavior is undefined. +It is unspecified whether `longjmp()` restores the signal mask, leaves the signal mask unchanged, or restores it to +its value at the time `setjmp()` was called. All accessible objects have values, and all other components of the abstract +machine have state (for example, floating-point status flags and open files), as of the time `longjmp()` was called, +except that the values of objects of automatic storage duration are unspecified if they meet all the following +conditions: +* They are local to the function containing the corresponding `setjmp()` invocation. * They do not have volatile-qualified type. - - - - * They are changed between the `setjmp()` invocation and `longjmp()` call. - - - Although `longjmp()` is an async-signal-safe function, if it is invoked from a signal handler which interrupted a -non-async-signal-safe function or equivalent (such as the processing equivalent to `exit()` performed after a return from the initial call to `main()`), the behavior of any -subsequent call to a non-async-signal-safe function or equivalent is undefined. +non-async-signal-safe function or equivalent (such as the processing equivalent to `exit()` performed after a return +from the initial call to `main()`), the behavior of any subsequent call to a non-async-signal-safe function or +equivalent is undefined. The effect of a call to `longjmp()` where initialization of the `jmp_buf` structure was not performed in the calling -thread is undefined. - +thread is undefined. ## Return value - -After `longjmp()` is completed, program execution continues as if the corresponding invocation of `setjmp()` had just returned the value specified by _val_. The `longjmp()` function -shall not cause `setjmp()` to return `0`; if _val_ is `0`, `setjmp()` shall return `1`. - +After `longjmp()` is completed, program execution continues as if the corresponding invocation of `setjmp()` had just +returned the value specified by _val_. The `longjmp()` function shall not cause `setjmp()` to return `0`; if _val_ is +`0`, `setjmp()` shall return `1`. ## Errors - No errors are defined. - - - ## Tests Untested @@ -71,6 +57,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/l/lseek.part-impl.md b/libc/functions/l/lseek.part-impl.md index 71a4b072..5f52fff0 100644 --- a/libc/functions/l/lseek.part-impl.md +++ b/libc/functions/l/lseek.part-impl.md @@ -1,14 +1,18 @@ -# Synopsis -`#include `
+# Synopsis -` off_t lseek(int fildes, off_t offset, int whence);`
+`#include ` + +`off_t lseek(int fildes, off_t offset, int whence);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `lseek()` function shall set the file offset for the open file description associated with the file descriptor _fildes_, as follows: @@ -17,52 +21,42 @@ _fildes_, as follows: * If _whence_ is `SEEK_CUR,` the file offset shall be set to its current location plus _offset_. - * If _whence_ is `SEEK_END,` the file offset shall be set to the size of the file plus _offset_. - The symbolic constants `SEEK_SET,` `SEEK_CUR,` and `SEEK_END` are defined in ``. -The behavior of `lseek()` on devices which are incapable of seeking is implementation-defined. The value of the file offset -associated with such a device is undefined. +The behavior of `lseek()` on devices which are incapable of seeking is implementation-defined. The value of the file +offset associated with such a device is undefined. -The `lseek()` function shall allow the file offset to be set beyond the end of the existing data in the file. If data is -later written at this point, subsequent reads of data in the gap shall return bytes with the value 0 until data is actually written -into the gap. +The `lseek()` function shall allow the file offset to be set beyond the end of the existing data in the file. If data +is later written at this point, subsequent reads of data in the gap shall return bytes with the value 0 until data is +actually written into the gap. The `lseek()` function shall not, by itself, extend the size of a file. -If _fildes_ refers to a shared memory object, the result of the `lseek()` function is unspecified. - -If _fildes_ refers to a typed memory object, the result of the `lseek()` function is unspecified. +If _fildes_ refers to a shared memory object, the result of the `lseek()` function is unspecified. +If _fildes_ refers to a typed memory object, the result of the `lseek()` function is unspecified. ## Return value - Upon successful completion, the resulting offset, as measured in bytes from the beginning of the file, shall be returned. Otherwise, -1 shall be returned, errno shall be set to indicate the error, and the file offset shall remain unchanged. - ## Errors - The `lseek()` function shall fail if: +* `EBADF` - The _fildes_ argument is not an open file descriptor. - * `EBADF` - The _fildes_ argument is not an open file descriptor. - - * `EINVAL` - The _whence_ argument is not a proper value, or the resulting file offset would be negative for a regular file, block -special file, or directory. - - * `EOVERFLOW` - The resulting file offset would be a value which cannot be represented correctly in an object of type `off_t`. - - * `ESPIPE` - The _fildes_ argument is associated with a pipe, `FIFO`, or socket. - - +* `EINVAL` - The _whence_ argument is not a proper value, or the resulting file offset would be negative for a regular + file, block special file, or directory. +* `EOVERFLOW` - The resulting file offset would be a value which cannot be represented correctly in an object of type + `off_t`. +* `ESPIPE` - The _fildes_ argument is associated with a pipe, `FIFO`, or socket. ## Tests @@ -72,6 +66,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/malloc.part-impl.md b/libc/functions/m/malloc.part-impl.md index 9addc462..28fc1076 100644 --- a/libc/functions/m/malloc.part-impl.md +++ b/libc/functions/m/malloc.part-impl.md @@ -1,57 +1,48 @@ -# Synopsis -`#include `
+# Synopsis -` void *malloc(size_t size);`
+`#include ` + +`void *malloc(size_t size);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description The `malloc()` function shall allocate unused space for an object whose size in bytes is specified by _size_ and whose value is unspecified. -The order and contiguity of storage allocated by successive calls to `malloc()` is unspecified. The pointer returned if the -allocation succeeds shall be suitably aligned so that it may be assigned to a pointer to any type of object and then used to access -such an object in the space allocated (until the space is explicitly freed or reallocated). Each such allocation shall yield a -pointer to an object disjoint from any other object. The pointer returned points to the start (lowest byte address) of the -allocated space. If the space cannot be allocated, a null pointer shall be returned. If the _size_ of the space requested is `0`, the -behavior is implementation-defined: either a null pointer shall be returned, or the behavior shall be as if the _size_ were some -non-zero value, except that the behavior is undefined if the returned pointer is used to access an object. - +The order and contiguity of storage allocated by successive calls to `malloc()` is unspecified. The pointer returned if +the allocation succeeds shall be suitably aligned so that it may be assigned to a pointer to any type of object and then +used to access such an object in the space allocated (until the space is explicitly freed or reallocated). Each such +allocation shall yield a pointer to an object disjoint from any other object. The pointer returned points to the start +(lowest byte address) of the allocated space. If the space cannot be allocated, a null pointer shall be returned. If the +_size_ of the space requested is `0`, the behavior is implementation-defined: either a null pointer shall be returned, +or the behavior shall be as if the _size_ were some non-zero value, except that the behavior is undefined if the +returned pointer is used to access an object. ## Return value +Upon successful completion with _size_ not equal to `0`, `malloc()` shall return a pointer to the allocated space. -Upon successful completion with _size_ not equal to `0`, `malloc()` shall return a pointer to the allocated space. If -_size_ is 0, either: - - +If _size_ is 0, either: * A null pointer shall be returned  and `errno` may be set to an implementation-defined value, or +* A pointer to the allocated space shall be returned. The application shall ensure that the pointer is not used to +access an object. - - - - -* A pointer to the allocated space shall be returned. The application shall ensure that the pointer is not used to access an object. - - - - -Otherwise, it shall return a null pointer and set `errno` to indicate the error. - +Otherwise, it shall return a null pointer and set `errno` to indicate the error. ## Errors - The `malloc()` function shall fail if: - - * `ENOMEM` - Insufficient storage space is available. - - +* `ENOMEM` - Insufficient storage space is available. ## Tests @@ -61,6 +52,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/mblen.part-impl.md b/libc/functions/m/mblen.part-impl.md index 8dcabaff..fd6909a5 100644 --- a/libc/functions/m/mblen.part-impl.md +++ b/libc/functions/m/mblen.part-impl.md @@ -1,57 +1,52 @@ -# Synopsis -`#include `
+# Synopsis -` int mblen(const char *s, size_t n);`
+`#include ` + +`int mblen(const char *s, size_t n);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description -If _s_ is not a `null` pointer, `mblen()` shall determine the number of bytes constituting the character pointed to by -_s_. Except that the shift state of `mbtowc()` is not affected, it shall be -equivalent to: +If _s_ is not a `null` pointer, `mblen()` shall determine the number of bytes constituting the character pointed to +by _s_. Except that the shift state of `mbtowc()` is not affected, it shall be equivalent to: + ```c mbtowc((wchar_t *)0, s, n); ``` - The implementation shall behave as if no function defined in this volume of POSIX.1-2017 calls `mblen()`. -The behavior of this function is affected by the `LC_CTYPE` category of the current locale. For a state-dependent encoding, -this function shall be placed into its initial state by a call for which its character pointer argument, _s_, is a `null` -pointer. Subsequent calls with s as other than a `null` pointer shall cause the internal state of the function to be altered -as necessary. A call with _s_ as a `null` pointer shall cause this function to return a non-zero value if encodings have state -dependency, and 0 otherwise. If the implementation employs special bytes to change the shift state, these bytes shall not produce -separate wide-character codes, but shall be grouped with an adjacent character. Changing the `LC_CTYPE` category causes the -shift state of this function to be unspecified. -The -`mblen()` function need not be thread-safe. +The behavior of this function is affected by the `LC_CTYPE` category of the current locale. For a state-dependent +encoding, this function shall be placed into its initial state by a call for which its character pointer argument, +_s_, is a `null` pointer. Subsequent calls with s as other than a `null` pointer shall cause the internal state of +the function to be altered as necessary. A call with _s_ as a `null` pointer shall cause this function to return a +non-zero value if encodings have state dependency, and 0 otherwise. If the implementation employs special bytes to +change the shift state, these bytes shall not produce separate wide-character codes, but shall be grouped with an +adjacent character. Changing the `LC_CTYPE` category causes the shift state of this function to be unspecified. +The `mblen()` function need not be thread-safe. ## Return value - -If _s_ is a `null` pointer, `mblen()` shall return a non-zero or `0` value, if character encodings, respectively, do or do -not have state-dependent encodings. If _s_ is not a `null` pointer, `mblen()` shall either return `0` (if s points to -the `null` byte), or return the number of bytes that constitute the character (if the next n or fewer bytes form a valid -character), or return `-1` (if they do not form a valid character)  and may set `errno` to indicate the error. In no case shall the value returned be greater than n or the value of -the `MB_CUR_MAX` macro. - +If _s_ is a `null` pointer, `mblen()` shall return a non-zero or `0` value, if character encodings, respectively, +do or do not have state-dependent encodings. If _s_ is not a `null` pointer, `mblen()` shall either return `0` +(if s points to the `null` byte), or return the number of bytes that constitute the character (if the next n or +fewer bytes form a valid character), or return `-1` (if they do not form a valid character)  and may set `errno` +to indicate the error. In no case shall the value returned be greater than n or the value of the `MB_CUR_MAX` macro. ## Errors - The `mblen()` function may fail if: - - * `EILSEQ` - An invalid character sequence is detected. In the POSIX locale an `EILSEQ` error cannot occur since all byte values are valid -characters. - - - - +* `EILSEQ` - An invalid character sequence is detected. In the POSIX locale an `EILSEQ` error cannot occur since all +byte values are valid characters. ## Tests @@ -61,6 +56,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/mbtowc.part-impl.md b/libc/functions/m/mbtowc.part-impl.md index 986de8a6..f7b27ff2 100644 --- a/libc/functions/m/mbtowc.part-impl.md +++ b/libc/functions/m/mbtowc.part-impl.md @@ -1,57 +1,55 @@ -# Synopsis -`#include `
+# Synopsis -` int mbtowc(wchar_t *restrict pwc, const char *restrict s, size_t n);`
+`#include ` + +`int mbtowc(wchar_t *restrict pwc, const char *restrict s, size_t n);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description If _s_ is not a _null_ pointer, `mbtowc()` shall determine the number of bytes that constitute the character pointed to by _s_. It shall then determine the wide-character code for the value of type `wchar_t` that corresponds to that -character. (The value of the wide-character code corresponding to the _null_ byte is `0`.) If the character is valid and _pwc_ is -not a _null_ pointer, `mbtowc()` shall store the wide-character code in the object pointed to by _pwc_. +character. (The value of the wide-character code corresponding to the _null_ byte is `0`.) If the character is valid +and _pwc_ is not a _null_ pointer, `mbtowc()` shall store the wide-character code in the object pointed to by _pwc_. -The behavior of this function is affected by the `LC_CTYPE` category of the current locale. For a state-dependent encoding, -this function is placed into its initial state by a call for which its character pointer argument, _s_, is a _null_ pointer. +The behavior of this function is affected by the `LC_CTYPE` category of the current locale. For a state-dependent +encoding, this function is placed into its initial state by a call for which its character pointer argument, _s_, is +a _null_ pointer. -Subsequent calls with _s_ as other than a _null_ pointer shall cause the internal state of the function to be altered as -necessary. A call with _s_ as a _null_ pointer shall cause this function to return a non-zero value if encodings have state -dependency, and `0` otherwise. If the implementation employs special bytes to change the shift state, these bytes shall not produce -separate wide-character codes, but shall be grouped with an adjacent character. Changing the `LC_CTYPE` category causes the -shift state of this function to be unspecified. At most _n_ bytes of the array pointed to by _s_ shall be examined. +Subsequent calls with _s_ as other than a _null_ pointer shall cause the internal state of the function to be altered +as necessary. A call with _s_ as a _null_ pointer shall cause this function to return a non-zero value if encodings +have state dependency, and `0` otherwise. If the implementation employs special bytes to change the shift state, these +bytes shall not produce separate wide-character codes, but shall be grouped with an adjacent character. Changing the +`LC_CTYPE` category causes the shift state of this function to be unspecified. At most _n_ bytes of the array pointed +to by _s_ shall be examined. The implementation shall behave as if no function defined in this volume of POSIX.1-2017 calls `mbtowc()`. -The -`mbtowc()` function need not be thread-safe. - +The `mbtowc()` function need not be thread-safe. ## Return value - -If _s_ is a _null_ pointer, `mbtowc()` shall return a non-zero or 0 value, if character encodings, respectively, do or -do not have state-dependent encodings. If _s_ is not a _null_ pointer, `mbtowc()` shall either return `0` (if _s_ points -to the _null_ byte), or return the number of bytes that constitute the converted character (if the next _n_ or fewer bytes form -a valid character), or return `-1`  and shall set `errno` to indicate the error (if they do not form a valid character). +If _s_ is a _null_ pointer, `mbtowc()` shall return a non-zero or 0 value, if character encodings, respectively, do +or do not have state-dependent encodings. If _s_ is not a _null_ pointer, `mbtowc()` shall either return `0` +(if _s_ points to the _null_ byte), or return the number of bytes that constitute the converted character +(if the next _n_ or fewer bytes form a valid character), or return `-1`  and shall set `errno` to indicate +the error (if they do not form a valid character). In no case shall the value returned be greater than n or the value of the `MB_CUR_MAX` macro. - ## Errors - The `mbtowc()` function shall fail if: - - * `EILSEQ` - An invalid character sequence is detected. In the POSIX locale an `EILSEQ` error cannot occur since all byte values are valid -characters. - - - - +* `EILSEQ` - An invalid character sequence is detected. In the POSIX locale an `EILSEQ` error cannot occur since all + byte values are valid characters. ## Tests @@ -61,6 +59,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/memccpy.not-impl.md b/libc/functions/m/memccpy.not-impl.md index 806565ee..06a0bdd4 100644 --- a/libc/functions/m/memccpy.not-impl.md +++ b/libc/functions/m/memccpy.not-impl.md @@ -1,22 +1,27 @@ -# Synopsis +# Synopsis + `#include ` -`void *memccpy(void *restrict s1, const void *restrict s2, int c, size_t n)`; +`void *memccpy(void *restrict s1, const void *restrict s2, int c, size_t n)`; ## Status + Not implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 -The `memccpy()` function shall copy bytes from memory area _s2_ into _s1_, stopping after the first occurrence of byte _c_ (converted to an `unsigned char`) is copied, or after _n_ bytes are copied, whichever comes first. If copying takes place between objects that overlap, the behavior is undefined. +## Description +The `memccpy()` function shall copy bytes from memory area _s2_ into _s1_, stopping after the first occurrence of byte +_c_ (converted to an `unsigned char`) is copied, or after _n_ bytes are copied, whichever comes first. If copying takes +place between objects that overlap, the behavior is undefined. ## Return value - -The `memccpy()` function shall return a pointer to the byte after the copy of _c_ in _s1_, or a `null` pointer if _c_ was not found in the first _n_ bytes of _s2_. +The `memccpy()` function shall return a pointer to the byte after the copy of _c_ in _s1_, or a `null` pointer if _c_ +was not found in the first _n_ bytes of _s2_. ## Errors @@ -30,6 +35,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/memchr.part-impl.md b/libc/functions/m/memchr.part-impl.md index 925a10a0..430223f2 100644 --- a/libc/functions/m/memchr.part-impl.md +++ b/libc/functions/m/memchr.part-impl.md @@ -1,36 +1,33 @@ -# Synopsis -`#include `
+# Synopsis -`void *memchr(const void *s, int c, size_t n);`
+`#include ` + +`void *memchr(const void *s, int c, size_t n);` ## Status + Partially implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 -The `memchr()` function shall locate the first occurrence of _c_ (converted to an unsigned char) in the initial -_n_ bytes (each interpreted as unsigned char) pointed to by s. +## Description -Implementations shall behave as if they read the memory byte by byte from the beginning of the bytes pointed to by s and -stop at the first occurrence of _c_ (if it is found in the initial n bytes). +The `memchr()` function shall locate the first occurrence of _c_ (converted to an unsigned char) in the initial _n_ +bytes (each interpreted as unsigned char) pointed to by s. +Implementations shall behave as if they read the memory byte by byte from the beginning of the bytes pointed to by s +and stop at the first occurrence of _c_ (if it is found in the initial n bytes). ## Return value - The `memchr()` function shall return a pointer to the located byte, or a `null` pointer if the byte is not found. - ## Errors - No errors are defined. - - - ## Tests Untested @@ -39,6 +36,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/memcmp.part-impl.md b/libc/functions/m/memcmp.part-impl.md index f7122138..6bdc547d 100644 --- a/libc/functions/m/memcmp.part-impl.md +++ b/libc/functions/m/memcmp.part-impl.md @@ -1,36 +1,34 @@ -# Synopsis -`#include `
+# Synopsis -`int memcmp(const void *s1, const void *s2, size_t n);`
+`#include ` + +`int memcmp(const void *s1, const void *s2, size_t n);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description -The `memcmp()` function shall compare the first _n_ bytes (each interpreted as unsigned char) of the object -pointed to by _s1_ to the first _n_ bytes of the object pointed to by _s2_. +## Description -The sign of a non-zero return value shall be determined by the sign of the difference between the values of the first pair of -bytes (both interpreted as type unsigned char) that differ in the objects being compared. +The `memcmp()` function shall compare the first _n_ bytes (each interpreted as unsigned char) of the object pointed to +by _s1_ to the first _n_ bytes of the object pointed to by _s2_. +The sign of a non-zero return value shall be determined by the sign of the difference between the values of the first +pair of bytes (both interpreted as type unsigned char) that differ in the objects being compared. ## Return value - The `memcmp()` function shall return an integer greater than, equal to, or less than `0`, if the object pointed to by _s1_ is greater than, equal to, or less than the object pointed to by _s2_, respectively. - ## Errors - No errors are defined. - - - ## Tests Untested @@ -39,6 +37,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/memcpy.part-impl.md b/libc/functions/m/memcpy.part-impl.md index d93e05ff..0c04e38c 100644 --- a/libc/functions/m/memcpy.part-impl.md +++ b/libc/functions/m/memcpy.part-impl.md @@ -1,32 +1,30 @@ -# Synopsis -`#include `
+# Synopsis -`void *memcpy(void *restrict s1, const void *restrict s2, size_t n);`
+`#include ` + +`void *memcpy(void *restrict s1, const void *restrict s2, size_t n);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description -The `memcpy()` function shall copy _n_ bytes from the object pointed to by _s2_ into the object pointed to by -_s1_. If copying takes place between objects that overlap, the behavior is undefined. +## Description +The `memcpy()` function shall copy _n_ bytes from the object pointed to by _s2_ into the object pointed to by _s1_. If +copying takes place between objects that overlap, the behavior is undefined. ## Return value - The `memcpy()` function shall return _s1_; no return value is reserved to indicate an error. - ## Errors - No errors are defined. - - - ## Tests Untested @@ -35,6 +33,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/meminfo.impl.md b/libc/functions/m/meminfo.impl.md index ca1a586a..a84244dd 100644 --- a/libc/functions/m/meminfo.impl.md +++ b/libc/functions/m/meminfo.impl.md @@ -1,11 +1,13 @@ -# Synopsis -`#include `
+# Synopsis -`void meminfo(meminfo_t *info);`
+`#include ` + +`void meminfo(meminfo_t *info);` ## Description -The `meminfo()` function shall assign values for a `meminfo_t` structure. The `meminfo_t` implementation is presented below. +The `meminfo()` function shall assign values for a `meminfo_t` structure. The `meminfo_t` implementation is presented +below. ```C typedef struct _meminfo_t { @@ -25,7 +27,9 @@ typedef struct _meminfo_t { The structure consists of two following parts: `page` and `entry`. -The page, in general, is a representation of RAM physical memory's part. For more information about paging technique please refer to the [`Memory management chapter`](../../../kernel/vm/README.md) and [`Page allocator chapter`](../../../kernel/vm/page.md). +The page, in general, is a representation of RAM physical memory's part. For more information about paging technique +please refer to the [`Memory management chapter`](../../../kernel/vm/README.md) and +[`Page allocator chapter`](../../../kernel/vm/page.md). Each of the structure's elements has been briefly described: @@ -33,12 +37,15 @@ Each of the structure's elements has been briefly described: * `free` - Size of free pages in bytes, * `boot` - Size of pages reserved by the internal boot firmware in bytes, * `sz` - Size of the `page_t` structure which describes each physical page available, -* `mapsz` - Number of all available pages, both free and allocated. It only applies to target architectures with `MMU` (memory management unit). +* `mapsz` - Number of all available pages, both free and allocated. It only applies to target architectures with `MMU` +(memory management unit). * `map` - Array (in fact pointer to an array) with information about each of the available pages in `pageinfo_t` format. If `mapsz` has been passed to the `meminfo()` function with `-1` value `mapsz` and `map` won't be changed. -An entry describes one memory segment and it's one abstraction layer higher than a page. Entries compose a memory map which is address space, for example, intended for kernel. Read more about memory mapping in [`Memory mapper chapter`](../../../kernel/vm/mapper.md). +An entry describes one memory segment and it's one abstraction layer higher than a page. Entries compose a memory map +which is address space, for example, intended for kernel. Read more about memory mapping in +[`Memory mapper chapter`](../../../kernel/vm/mapper.md). The `entry` structure consists of following elements: @@ -48,12 +55,15 @@ The `entry` structure consists of following elements: * `sz` - Size of the `map_entry_t` structure which describes an entry, * `mapsz` - Number of all available entries, * `kmapsz` - Number of entries associated with kernel, -* `kmap` - Array (in fact pointer to an array) with information about each of the entry associated with kernel in `entryinfo_t` format. -* `map` - Array (in fact pointer to an array) with information about each of the available entries in `entryinfo_t` format. +* `kmap` - Array (in fact pointer to an array) with information about each of the entry associated with kernel in +`entryinfo_t` format. +* `map` - Array (in fact pointer to an array) with information about each of the available entries in `entryinfo_t` +format. If `mapsz` has been passed to the `meminfo()` function with `-1` value `mapsz` and `map` won't be changed. -Similarly to `mapsz`, if `kmapsz` has been passed to the `meminfo()` function with `-1` value `kmapsz` and `kmap` won't be changed. +Similarly to `mapsz`, if `kmapsz` has been passed to the `meminfo()` function with `-1` value `kmapsz` and `kmap` +won't be changed. ## Return value @@ -71,6 +81,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/memmove.part-impl.md b/libc/functions/m/memmove.part-impl.md index 88e0104d..57a4faa9 100644 --- a/libc/functions/m/memmove.part-impl.md +++ b/libc/functions/m/memmove.part-impl.md @@ -1,35 +1,32 @@ -# Synopsis -`#include `
+# Synopsis -` void *memmove(void *s1, const void *s2, size_t n);`
+`#include ` + +`void *memmove(void *s1, const void *s2, size_t n);` ## Status + Partially implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 -The `memmove()` function shall copy _n_ bytes from the object pointed to by _s2_ into the object pointed to by -_s1_. Copying takes place as if the _n_ bytes from the object pointed to by _s2_ are first copied into a temporary -array of _n_ bytes that does not overlap the objects pointed to by _s1_ and _s2_, and then the _n_ bytes from -the temporary array are copied into the object pointed to by _s1_. +## Description +The `memmove()` function shall copy _n_ bytes from the object pointed to by _s2_ into the object pointed to by _s1_. +Copying takes place as if the _n_ bytes from the object pointed to by _s2_ are first copied into a temporary array of +_n_ bytes that does not overlap the objects pointed to by _s1_ and _s2_, and then the _n_ bytes from the temporary +array are copied into the object pointed to by _s1_. ## Return value - The `memmove()` function shall return _s1_; no return value is reserved to indicate an error. - ## Errors - No errors are defined. - - - ## Tests Untested @@ -38,6 +35,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/memset.part-impl.md b/libc/functions/m/memset.part-impl.md index 4054b0e9..4a4ffa63 100644 --- a/libc/functions/m/memset.part-impl.md +++ b/libc/functions/m/memset.part-impl.md @@ -1,33 +1,30 @@ -# Synopsis -`#include `
+# Synopsis -` void *memset(void *s, int c, size_t n);`
+`#include ` + +`void *memset(void *s, int c, size_t n);` ## Status + Partially implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 -The `memset()` function shall copy _c_ (converted to an unsigned char) into each of the first _n_ bytes of -the object pointed to by _s_. +## Description +The `memset()` function shall copy _c_ (converted to an unsigned char) into each of the first _n_ bytes of the object +pointed to by _s_. ## Return value - The `memset()` function shall return _s_; no return value is reserved to indicate an error. - ## Errors - No errors are defined. - - - ## Tests Untested @@ -36,6 +33,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/mkdir.part-impl.md b/libc/functions/m/mkdir.part-impl.md index 6e5e15c0..a5a67b87 100644 --- a/libc/functions/m/mkdir.part-impl.md +++ b/libc/functions/m/mkdir.part-impl.md @@ -1,18 +1,22 @@ -# Synopsis -`#include `
+# Synopsis -` int mkdir(const char *path, mode_t mode);`
+`#include ` -`#include `
+`int mkdir(const char *path, mode_t mode);` -` int mkdirat(int fd, const char *path, mode_t mode);`
+`#include ` + +`int mkdirat(int fd, const char *path, mode_t mode);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `mkdir()` function shall create a new directory with name _path_. The file permission bits of the new directory shall be initialized from mode. These file permission bits of the mode argument shall be modified by the process' @@ -21,85 +25,77 @@ file creation mask. When bits in mode other than the file permission bits are set, the meaning of these additional bits is implementation-defined. -The directory's user ID shall be set to the process' effective user ID. The directory's group ID shall be set to the group ID of -the parent directory or to the effective group ID of the process. Implementations shall provide a way to initialize the directory's -group ID to the group ID of the parent directory. Implementations may, but need not, provide an implementation-defined way to -initialize the directory's group ID to the effective group ID of the calling process. +The directory's user ID shall be set to the process' effective user ID. The directory's group ID shall be set to the +group ID of the parent directory or to the effective group ID of the process. Implementations shall provide a way to +initialize the directory's group ID to the group ID of the parent directory. Implementations may, but need not, provide +an implementation-defined way to initialize the directory's group ID to the effective group ID of the calling process. The newly created directory shall be an empty directory. If _path_ names a symbolic link, `mkdir()` shall fail and set errno to `EEXIST`. Upon successful completion, `mkdir()` shall mark for update the last data access, last data modification, and last file -status change timestamps of the directory. Also, the last data modification and last file status change timestamps of the directory -that contains the new entry shall be marked for update. +status change timestamps of the directory. Also, the last data modification and last file status change timestamps of +the directory that contains the new entry shall be marked for update. -The `mkdirat()` function shall be equivalent to the `mkdir()` function except in the case where _path_ specifies -a relative path. In this case the newly created directory is created relative to the directory associated with the file descriptor -_fd_ instead of the current working directory. If the access mode of the open file description associated with the file -descriptor is not `O_SEARCH,` the function shall check whether directory searches are permitted using the current permissions of the -directory underlying the file descriptor. If the access mode is `O_SEARCH,` the function shall not perform the check. +The `mkdirat()` function shall be equivalent to the `mkdir()` function except in the case where _path_ specifies a +relative path. In this case the newly created directory is created relative to the directory associated with the file +descriptor _fd_ instead of the current working directory. If the access mode of the open file description associated +with the file descriptor is not `O_SEARCH,` the function shall check whether directory searches are permitted using the +current permissions of the directory underlying the file descriptor. If the access mode is `O_SEARCH,` the function +shall not perform the check. If `mkdirat()` is passed the special value `AT_FDCWD` in the _fd_ parameter, the current working directory shall be used and the behavior shall be identical to a call to `mkdir()`. - ## Return value - -Upon successful completion, these functions shall return `0`. Otherwise, these functions shall return `-1` and set `errno` to -indicate the error. If `-1` is returned, no directory shall be created. - +Upon successful completion, these functions shall return `0`. Otherwise, these functions shall return `-1` and set +`errno` to indicate the error. If `-1` is returned, no directory shall be created. ## Errors - These functions shall fail if: +* `EACCES` - Search permission is denied on a component of the path prefix, or write permission is denied on the parent + directory of the directory to be created. - * `EACCES` - Search permission is denied on a component of the path prefix, or write permission is denied on the parent directory of the -directory to be created. - - * `EEXIST` - The named file exists. +* `EEXIST` - The named file exists. - * `ELOOP` - A loop exists in symbolic links encountered during resolution of the path argument. +* `ELOOP` - A loop exists in symbolic links encountered during resolution of the path argument. - * `EMLINK` - The link count of the parent directory would exceed `LINK_MAX`. +* `EMLINK` - The link count of the parent directory would exceed `LINK_MAX`. - * `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. +* `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. - * `ENOENT` - A component of the path prefix specified by path does not name an existing directory or path is an empty -string. +* `ENOENT` - A component of the path prefix specified by path does not name an existing directory or path is an empty + string. - * `ENOSPC` - The file system does not contain enough space to hold the contents of the new directory or to extend the parent directory of -the new directory. +* `ENOSPC` - The file system does not contain enough space to hold the contents of the new directory or to extend the + parent directory of the new directory. - * `ENOTDIR` - A component of the path prefix names an existing file that is neither a directory nor a symbolic link to a directory. +* `ENOTDIR` - A component of the path prefix names an existing file that is neither a directory nor a symbolic link to + a directory. - * `EROFS` - The parent directory resides on a read-only file system. +* `EROFS` - The parent directory resides on a read-only file system. In addition, the `mkdirat()` function shall fail if: +* `EACCES` - The access mode of the open file description associated with _fd_ is not O_SEARCH and the permissions of + the directory underlying _fd_ do not permit directory searches. - * `EACCES` - The access mode of the open file description associated with _fd_ is not O_SEARCH and the permissions of the directory -underlying _fd_ do not permit directory searches. - - * `EBADF` - The path argument does not specify an absolute path and the _fd_ argument is neither `AT_FDCWD` nor a valid file -descriptor open for reading or searching. +* `EBADF` - The path argument does not specify an absolute path and the _fd_ argument is neither `AT_FDCWD` nor a valid + file descriptor open for reading or searching. - * `ENOTDIR` - The path argument is not an absolute path and _fd_ is a file descriptor associated with a non-directory file. +* `ENOTDIR` - The path argument is not an absolute path and _fd_ is a file descriptor associated with a non-directory + file. These functions may fail if: +* `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the path argument. - * `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the path argument. - - * `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an intermediate result with a -length that exceeds `PATH_MAX`. - - - - +* `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an + intermediate result with a length that exceeds `PATH_MAX`. ## Tests @@ -109,6 +105,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/mkfifo.part-impl.md b/libc/functions/m/mkfifo.part-impl.md index 69b8661c..a62aac39 100644 --- a/libc/functions/m/mkfifo.part-impl.md +++ b/libc/functions/m/mkfifo.part-impl.md @@ -1,98 +1,99 @@ -# Synopsis -`#include `
+# Synopsis -` int mkfifo(const char *path, mode_t mode);`
+`#include ` -`#include `
+`int mkfifo(const char *path, mode_t mode);` -` int mkfifoat(int fd, const char *path, mode_t mode);`
+`#include ` + +`int mkfifoat(int fd, const char *path, mode_t mode);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `mkfifo()` function shall create a new `FIFO` special file named by the pathname pointed to by _path_. The file -permission bits of the new `FIFO` shall be initialized from _mode_. The file permission bits of the _mode_ argument shall -be modified by the process' file creation mask. +permission bits of the new `FIFO` shall be initialized from _mode_. The file permission bits of the _mode_ argument +shall be modified by the process' file creation mask. When bits in _mode_ other than the file permission bits are set, the effect is implementation-defined. If _path_ names a symbolic link, `mkfifo()` shall fail and set `errno` to `EEXIST`. -The `FIFO`'s user ID shall be set to the process' effective user ID. The `FIFO`'s group ID shall be set to the group ID of the -parent directory or to the effective group ID of the process. Implementations shall provide a way to initialize the `FIFO`'s group ID -to the group ID of the parent directory. Implementations may, but need not, provide an implementation-defined way to initialize the -FIFO's group ID to the effective group ID of the calling process. +The `FIFO`'s user ID shall be set to the process' effective user ID. The `FIFO`'s group ID shall be set to the group ID +of the parent directory or to the effective group ID of the process. Implementations shall provide a way to initialize +the `FIFO`'s group ID to the group ID of the parent directory. Implementations may, but need not, provide an +implementation-defined way to initialize the FIFO's group ID to the effective group ID of the calling process. -Upon successful completion, `mkfifo()` shall mark for update the last data access, last data modification, and last file -status change timestamps of the file. Also, the last data modification and last file status change timestamps of the directory that -contains the new entry shall be marked for update. +Upon successful completion, `mkfifo()` shall mark for update the last data access, last data modification, and last +file status change timestamps of the file. Also, the last data modification and last file status change timestamps of +the directory that contains the new entry shall be marked for update. -The `mkfifoat()` function shall be equivalent to the `mkfifo()` function except in the case where _path_ -specifies a relative path. In this case the newly created `FIFO` is created relative to the directory associated with the file -descriptor _fd_ instead of the current working directory. If the access mode of the open file description associated with the -file descriptor is not `O_SEARCH`, the function shall check whether directory searches are permitted using the current permissions of -the directory underlying the file descriptor. If the access mode is `O_SEARCH`, the function shall not perform the check. +The `mkfifoat()` function shall be equivalent to the `mkfifo()` function except in the case where _path_ specifies a +relative path. In this case the newly created `FIFO` is created relative to the directory associated with the file +descriptor _fd_ instead of the current working directory. If the access mode of the open file description associated +with the file descriptor is not `O_SEARCH`, the function shall check whether directory searches are permitted using the +current permissions of the directory underlying the file descriptor. If the access mode is `O_SEARCH`, the function +shall not perform the check. If `mkfifoat()` is passed the special value `AT_FDCWD` in the _fd_ parameter, the current working directory shall be used and the behavior shall be identical to a call to `mkfifo()`. - ## Return value - -Upon successful completion, these functions shall return `0`. Otherwise, these functions shall return `-1` and set `errno` to -indicate the error. If `-1` is returned, no FIFO shall be created. - +Upon successful completion, these functions shall return `0`. Otherwise, these functions shall return `-1` and set +`errno` to indicate the error. If `-1` is returned, no FIFO shall be created. ## Errors - These functions shall fail if: +* `EACCES` - A component of the _path_ prefix denies search permission, or write permission is denied on the parent +directory of the `FIFO` to be created. - * `EACCES` - A component of the _path_ prefix denies search permission, or write permission is denied on the parent directory of the `FIFO` to -be created. - - * `EEXIST` - The named file already exists. +* `EEXIST` - The named file already exists. - * `ELOOP` - A loop exists in symbolic links encountered during resolution of the _path_ argument. +* `ELOOP` - A loop exists in symbolic links encountered during resolution of the _path_ argument. - * `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. +* `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. - * `ENOENT` - A component of the path prefix of _path_ does not name an existing file or _path_ is an empty string. +* `ENOENT` - A component of the path prefix of _path_ does not name an existing file or _path_ is an empty string. - * `ENOENT` or `ENOTDIR` - The _path_ argument contains at least one non- `` character and ends with one or more trailing `` -characters. If _path_ without the trailing `` characters would name an existing file, an `ENOENT` error shall not -occur. +* `ENOENT` or `ENOTDIR` - The _path_ argument contains at least one non- `` character and ends with one or more +trailing `` characters. If _path_ without the trailing `` characters would name an existing file, an +`ENOENT` error shall not occur. - * `ENOSPC` - The directory that would contain the new file cannot be extended or the file system is out of file-allocation resources. +* `ENOSPC` - The directory that would contain the new file cannot be extended or the file system is out of +file-allocation resources. - * `ENOTDIR` - A component of the _path_ prefix names an existing file that is neither a directory nor a symbolic link to a directory. +* `ENOTDIR` - A component of the _path_ prefix names an existing file that is neither a directory nor a symbolic link +to a directory. - * `EROFS` - The named file resides on a read-only file system. +* `EROFS` - The named file resides on a read-only file system. The `mkfifoat()` function shall fail if: +* `EACCES` - The access mode of the open file description associated with _fd_ is not `O_SEARCH` and the permissions +of the directory underlying _fd_ do not permit directory searches. - * `EACCES` - The access mode of the open file description associated with _fd_ is not `O_SEARCH` and the permissions of the directory -underlying _fd_ do not permit directory searches. +* `EBADF` - The _path_ argument does not specify an absolute path and the _fd_ argument is neither `AT_FDCWD` +nor a valid file descriptor open for reading or searching. - * `EBADF` - The _path_ argument does not specify an absolute path and the _fd_ argument is neither `AT_FDCWD` nor a valid file -descriptor open for reading or searching. - - * `ENOTDIR` - The _path_ argument is not an absolute path and _fd_ is a file descriptor associated with a non-directory file. +* `ENOTDIR` - The _path_ argument is not an absolute path and _fd_ is a file descriptor associated with a +non-directory file. These functions may fail if: - * `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the _path_ argument. - - * `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an intermediate result with a -length that exceeds `PATH_MAX`. +* `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the _path_ argument. +* `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an +intermediate result with a length that exceeds `PATH_MAX`. ## Tests @@ -102,6 +103,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/mmap.part-impl.md b/libc/functions/m/mmap.part-impl.md index 0d1cf781..db3c13cf 100644 --- a/libc/functions/m/mmap.part-impl.md +++ b/libc/functions/m/mmap.part-impl.md @@ -1,14 +1,18 @@ -# Synopsis -`#include `
+# Synopsis -` void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);`
+`#include ` + +`void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `mmap()` function shall establish a mapping between an address space of a process and a memory object. @@ -16,13 +20,14 @@ The `mmap()` function shall be supported for the following memory objects: * Regular files -* Shared memory objects +* Shared memory objects -* Typed memory objects +* Typed memory objects Support for any other type of file is unspecified. The format of the call is as follows: + ```c pa=mmap(addr, len, prot, flags, fildes, off); ``` @@ -32,29 +37,26 @@ _len_ bytes to the memory object represented by the file descriptor fildes at of The value of pa is an implementation-defined function of the parameter _addr_ and the values of _flags_, further described below. A successful `mmap()` call shall return pa as its result. The address range starting at pa and -continuing for _len_ bytes shall be legitimate for the possible (not necessarily current) address space of the process. The -range of bytes starting at off and continuing for _len_ bytes shall be legitimate for the possible (not necessarily +continuing for _len_ bytes shall be legitimate for the possible (not necessarily current) address space of the process. +The range of bytes starting at off and continuing for _len_ bytes shall be legitimate for the possible (not necessarily current) offsets in the memory object represented by fildes. If fildes represents a typed memory object opened with either the `POSIX_TYPED_MEM_ALLOCATE` flag or the -`POSIX_TYPED_MEM_ALLOCATE_CONTIG` flag, the memory object to be mapped shall be that portion of the typed memory object allocated by -the implementation as specified below. In this case, if off is non-zero, the behavior of `mmap()` is undefined. If -fildes refers to a valid typed memory object that is not accessible from the calling process, `mmap()` shall fail. -The mapping established by `mmap()` shall replace any previous mappings for those whole pages containing any part of the -address space of the process starting at pa and continuing for _len_ bytes. +`POSIX_TYPED_MEM_ALLOCATE_CONTIG` flag, the memory object to be mapped shall be that portion of the typed memory object +allocated by the implementation as specified below. In this case, if off is non-zero, the behavior of `mmap()` is +undefined. If fildes refers to a valid typed memory object that is not accessible from the calling process, `mmap()` +shall fail. The mapping established by `mmap()` shall replace any previous mappings for those whole pages containing any +part of the address space of the process starting at pa and continuing for _len_ bytes. -If the size of the mapped file changes after the call to `mmap()` as a result of some other operation on the mapped file, +If the size of the mapped file changes after the call to `mmap()` as a result of some other operation on the mapped file the effect of references to portions of the mapped region that correspond to added or removed portions of the file is unspecified. If _len_ is zero, `mmap()` shall fail and no mapping shall be established. The parameter _prot_ determines whether read, write, execute, or some combination of accesses are permitted to the data -being mapped. The _prot_ shall be either `PROT_NONE` or the bitwise-inclusive OR of one or more of the other flags in the -following table, defined in the `` header. - - - +being mapped. The _prot_ shall be either `PROT_NONE` or the bitwise-inclusive OR of one or more of the other flags in +the following table, defined in the `` header. | __Symbolic Constant__ | __Description__ | |-------------------|----------------------------| @@ -63,18 +65,16 @@ following table, defined in the `` header. | `PROT_EXEC` | Data can be executed. | | `PROT_NONE` | Data cannot be accessed. | - - If an implementation cannot support the combination of access types specified by _prot_, the call to `mmap()` shall fail. -An implementation may permit accesses other than those specified by _prot_; however, the implementation shall not permit a -write to succeed where `PROT_WRITE` has not been set and shall not permit any access where `PROT_NONE` alone has been set. The -implementation shall support at least the following values of _prot_: `PROT_NONE,` `PROT_READ,` `PROT_WRITE,` and the -bitwise-inclusive OR of `PROT_READ` and `PROT_WRITE`. The file descriptor fildes shall have been opened with read permission, -regardless of the protection options specified. If `PROT_WRITE` is specified, the application shall ensure that it has opened the -file descriptor fildes with write permission unless `MAP_PRIVATE` is specified in the _flags_ parameter as described -below. +An implementation may permit accesses other than those specified by _prot_; however, the implementation shall not permit +a write to succeed where `PROT_WRITE` has not been set and shall not permit any access where `PROT_NONE` alone has been +set. The implementation shall support at least the following values of _prot_: `PROT_NONE,` `PROT_READ,` `PROT_WRITE,` +and the bitwise-inclusive OR of `PROT_READ` and `PROT_WRITE`. The file descriptor fildes shall have been opened with +read permission, regardless of the protection options specified. If `PROT_WRITE` is specified, the application shall +ensure that it has opened the file descriptor fildes with write permission unless `MAP_PRIVATE` is specified in the +_flags_ parameter as described below. The parameter _flags_ provides other information about the handling of the mapped data. The value of _flags_ is the bitwise-inclusive OR of these options, defined in ``: @@ -86,143 +86,136 @@ bitwise-inclusive OR of these options, defined in ``: | `MAP_FIXED` | Interpret _addr_ exactly. | | `PROT_NONE` | Data cannot be accessed. | - - - -It is implementation-defined whether `MAP_FIXED` shall be supported. +It is implementation-defined whether `MAP_FIXED` shall be supported. `MAP_FIXED` shall be supported on XSI-conformant systems. -`MAP_SHARED` and `MAP_PRIVATE` describe the disposition of write references to the memory object. If `MAP_SHARED` is specified, write -references shall change the underlying object. If `MAP_PRIVATE` is specified, modifications to the mapped data by the calling process -shall be visible only to the calling process and shall not change the underlying object. It is unspecified whether modifications to -the underlying object done after the `MAP_PRIVATE` mapping is established are visible through the `MAP_PRIVATE` mapping. Either -`MAP_SHARED` or `MAP_PRIVATE` can be specified, but not both. The mapping type is retained across `fork()`. +`MAP_SHARED` and `MAP_PRIVATE` describe the disposition of write references to the memory object. If `MAP_SHARED` is +specified, write references shall change the underlying object. If `MAP_PRIVATE` is specified, modifications to the +mapped data by the calling process shall be visible only to the calling process and shall not change the underlying +object. It is unspecified whether modifications to the underlying object done after the `MAP_PRIVATE` mapping is +established are visible through the `MAP_PRIVATE` mapping. Either `MAP_SHARED` or `MAP_PRIVATE` can be specified, +but not both. The mapping type is retained across `fork()`. -The state of synchronization objects such as mutexes, semaphores, barriers, and conditional variables placed in shared memory -mapped with `MAP_SHARED` becomes undefined when the last region in any process containing the synchronization object is unmapped. +The state of synchronization objects such as mutexes, semaphores, barriers, and conditional variables placed in shared +memory mapped with `MAP_SHARED` becomes undefined when the last region in any process containing the synchronization +object is unmapped. When fildes represents a typed memory object opened with either the `POSIX_TYPED_MEM_ALLOCATE` flag or the -`POSIX_TYPED_MEM_ALLOCATE_CONTIG` flag, `mmap()` shall, if there are enough resources available, map _len_ bytes allocated -from the corresponding typed memory object which were not previously allocated to any process in any processor that may access that -typed memory object. If there are not enough resources available, the function shall fail. If fildes represents a typed -memory object opened with the `POSIX_TYPED_MEM_ALLOCATE_CONTIG` flag, these allocated bytes shall be contiguous within the typed -memory object. If fildes represents a typed memory object opened with the `POSIX_TYPED_MEM_ALLOCATE` flag, these allocated -bytes may be composed of non-contiguous fragments within the typed memory object. If fildes represents a typed memory object -opened with neither the `POSIX_TYPED_MEM_ALLOCATE_CONTIG` flag nor the `POSIX_TYPED_MEM_ALLOCATE` flag, _len_ bytes starting at -offset off within the typed memory object are mapped, exactly as when mapping a file or shared memory object. In this case, -if two processes map an area of typed memory using the same off and _len_ values and using file descriptors that refer -to the same memory pool (either from the same port or from a different port), both processes shall map the same region of storage. - -When `MAP_FIXED` is set in the _flags_ argument, the implementation is informed that the value of pa shall be -_addr_, exactly. If `MAP_FIXED` is set, `mmap()` may return `MAP_FAILED` and set errno to `EINVAL`. If a `MAP_FIXED` -request is successful, then any previous mappings [ML|MLR]  or memory locks  for those whole pages containing any part of the address range [pa,pa+_len_) -shall be removed, as if by an appropriate call to `munmap()`, before the new mapping is +`POSIX_TYPED_MEM_ALLOCATE_CONTIG` flag, `mmap()` shall, if there are enough resources available, map _len_ bytes +allocated from the corresponding typed memory object which were not previously allocated to any process in any +processor that may access that typed memory object. If there are not enough resources available, the function shall +fail. If fildes represents a typed memory object opened with the `POSIX_TYPED_MEM_ALLOCATE_CONTIG` flag, these allocated +bytes shall be contiguous within the typed memory object. If fildes represents a typed memory object opened with the +`POSIX_TYPED_MEM_ALLOCATE` flag, these allocated bytes may be composed of non-contiguous fragments within the typed +memory object. If fildes represents a typed memory object opened with neither the `POSIX_TYPED_MEM_ALLOCATE_CONTIG` +flag nor the `POSIX_TYPED_MEM_ALLOCATE` flag, _len_ bytes starting at offset off within the typed memory object are +mapped, exactly as when mapping a file or shared memory object. In this case, if two processes map an area of typed +memory using the same off and _len_ values and using file descriptors that refer to the same memory pool (either from +the same port or from a different port), both processes shall map the same region of storage. + +When `MAP_FIXED` is set in the _flags_ argument, the implementation is informed that the value of pa shall be _addr_, +exactly. If `MAP_FIXED` is set, `mmap()` may return `MAP_FAILED` and set errno to `EINVAL`. If a `MAP_FIXED` request is +successful, then any previous mappings [ML|MLR]  or memory locks  for those whole pages containing any part of the +address range (pa,pa+_len_) shall be removed, as if by an appropriate call to `munmap()`, before the new mapping is established. When `MAP_FIXED` is not set, the implementation uses _addr_ in an implementation-defined manner to arrive at pa. The pa so chosen shall be an area of the address space that the implementation deems suitable for a mapping of _len_ bytes -to the file. All implementations interpret an _addr_ value of 0 as granting the implementation complete freedom in selecting -pa, subject to constraints described below. A non-zero value of _addr_ is taken to be a suggestion of a process address -near which the mapping should be placed. When the implementation selects a value for pa, it never places a mapping at -address 0, nor does it replace any extant mapping. +to the file. All implementations interpret an _addr_ value of 0 as granting the implementation complete freedom in +selecting pa, subject to constraints described below. A non-zero value of _addr_ is taken to be a suggestion of a +process address near which the mapping should be placed. When the implementation selects a value for pa, it never +places a mapping at address 0, nor does it replace any extant mapping. If `MAP_FIXED` is specified and _addr_ is non-zero, it shall have the same remainder as the off parameter, modulo the -page size as returned by `sysconf()` when passed `_SC_PAGESIZE` or `_SC_PAGE_SIZE`. The -implementation may require that off is a multiple of the page size. If `MAP_FIXED` is specified, the implementation may require that -_addr_ is a multiple of the page size. The system performs mapping operations over whole pages. Thus, while the parameter -_len_ need not meet a size or alignment constraint, the system shall include, in any mapping operation, any partial page +page size as returned by `sysconf()` when passed `_SC_PAGESIZE` or `_SC_PAGE_SIZE`. The implementation may require that +off is a multiple of the page size. If `MAP_FIXED` is specified, the implementation may require that _addr_ is a +multiple of the page size. The system performs mapping operations over whole pages. Thus, while the parameter _len_ +need not meet a size or alignment constraint, the system shall include, in any mapping operation, any partial page specified by the address range starting at pa and continuing for _len_ bytes. -The system shall always zero-fill any partial page at the end of an object. Further, the system shall never write out any -modified portions of the last page of an object which are beyond its end. References within the address range starting at pa -and continuing for _len_ bytes to whole pages following the end of an object shall result in delivery of a SIGBUS signal. +The system shall always zero-fill any partial page at the end of an object. Further, the system shall never write out +any modified portions of the last page of an object which are beyond its end. References within the address range +starting at pa and continuing for _len_ bytes to whole pages following the end of an object shall result in delivery of +a SIGBUS signal. -An implementation may generate SIGBUS signals when a reference would cause an error in the mapped object, such as out-of-space -condition. +An implementation may generate SIGBUS signals when a reference would cause an error in the mapped object, such as +out-of-space condition. -The `mmap()` function shall add an extra reference to the file associated with the file descriptor fildes which is -not removed by a subsequent `close()` on that file descriptor. This reference shall be -removed when there are no more mappings to the file. +The `mmap()` function shall add an extra reference to the file associated with the file descriptor fildes which is not +removed by a subsequent `close()` on that file descriptor. This reference shall be removed when there are no more +mappings to the file. -The last data access timestamp of the mapped file may be marked for update at any time between the `mmap()` call and the -corresponding `munmap()` call. The initial read or write reference to a mapped region -shall cause the file's last data access timestamp to be marked for update if it has not already been marked for update. +The last data access timestamp of the mapped file may be marked for update at any time between the `mmap()` call and +the corresponding `munmap()` call. The initial read or write reference to a mapped region shall cause the file's last +data access timestamp to be marked for update if it has not already been marked for update. -The last data modification and last file status change timestamps of a file that is mapped with `MAP_SHARED` and `PROT_WRITE` shall -be marked for update at some point in the interval between a write reference to the mapped region and the next call to `msync()` with `MS_ASYNC` or `MS_SYNC` for that portion of the file by any process. If there is no -such call and if the underlying file is modified as a result of a write reference, then these timestamps shall be marked for update -at some time after the write reference. +The last data modification and last file status change timestamps of a file that is mapped with `MAP_SHARED` and +`PROT_WRITE` shall be marked for update at some point in the interval between a write reference to the mapped region +and the next call to `msync()` with `MS_ASYNC` or `MS_SYNC` for that portion of the file by any process. If there is +no such call and if the underlying file is modified as a result of a write reference, then these timestamps shall be +marked for update at some time after the write reference. -There may be implementation-defined limits on the number of memory regions that can be mapped (per process or per system). +There may be implementation-defined limits on the number of memory regions that can be mapped +(per process or per system). + +If such a limit is imposed, whether the number of memory regions that can be mapped by a process is decreased by the +use of `shmat()` is implementation-defined. -If such a limit is imposed, whether the number of memory regions that can be mapped by a process is decreased by the use of `shmat()` is implementation-defined. If `mmap()` fails for reasons other than `EBADF`, `EINVAL`, or `ENOTSUP`, some of the mappings in the address range starting at _addr_ and continuing for _len_ bytes may have been unmapped. - ## Return value - Upon successful completion, the `mmap()` function shall return the address at which the mapping was placed (pa); -otherwise, it shall return a value of `MAP_FAILED` and set `errno` to indicate the error. The symbol `MAP_FAILED` is defined in -the `` header. No successful return from `mmap()` shall -return the value `MAP_FAILED`. - +otherwise, it shall return a value of `MAP_FAILED` and set `errno` to indicate the error. The symbol `MAP_FAILED` is +defined in the `` header. No successful return from `mmap()` shall return the value `MAP_FAILED`. ## Errors - The `mmap()` function shall fail if: +* `EACCES` - The fildes argument is not open for read, regardless of the protection specified, or fildes is not open +for write and `PROT_WRITE` was specified for a `MAP_SHARED` type mapping. - * `EACCES` - The fildes argument is not open for read, regardless of the protection specified, or fildes is not open for write -and `PROT_WRITE` was specified for a `MAP_SHARED` type mapping. - - * `EAGAIN` - The mapping could not be locked in memory, if required by `mlockall()`, due to a lack -of resources. - - * `EBADF` - The fildes argument is not a valid open file descriptor. - - * `EINVAL` - The value of _len_ is zero. +* `EAGAIN` - The mapping could not be locked in memory, if required by `mlockall()`, due to a lack of resources. - * `EINVAL` - The value of _flags_ is invalid (neither `MAP_PRIVATE` nor `MAP_SHARED` is set). +* `EBADF` - The fildes argument is not a valid open file descriptor. - * `EMFILE` - The number of mapped regions would exceed an implementation-defined limit (per process or per system). +* `EINVAL` - The value of _len_ is zero. - * `ENODEV` - The fildes argument refers to a file whose type is not supported by `mmap()`. +* `EINVAL` - The value of _flags_ is invalid (neither `MAP_PRIVATE` nor `MAP_SHARED` is set). - * `ENOMEM` - `MAP_FIXED` was specified, and the range [_addr_,_addr_+_len_) exceeds that allowed for the address space of a -process; or, if `MAP_FIXED` was not specified and there is insufficient room in the address space to effect the mapping. +* `EMFILE` - The number of mapped regions would exceed an implementation-defined limit (per process or per system). - * `ENOMEM` - The mapping could not be locked in memory, if required by `mlockall()`, because it -would require more space than the system is able to supply. +* `ENODEV` - The fildes argument refers to a file whose type is not supported by `mmap()`. - * `ENOMEM` - Not enough unallocated memory resources remain in the typed memory object designated by fildes to allocate _len_ bytes. +* `ENOMEM` - `MAP_FIXED` was specified, and the range (_addr_,_addr_+_len_) exceeds that allowed for the address space +of a process; or, if `MAP_FIXED` was not specified and there is insufficient room in the address space to effect the +mapping. +* `ENOMEM` - The mapping could not be locked in memory, if required by `mlockall()`, because it would require more space +than the system is able to supply. - * `ENOTSUP` - `MAP_FIXED` or `MAP_PRIVATE` was specified in the _flags_ argument and the implementation does not support this functionality.
- The implementation does not support the combination of accesses requested in the _prot_ argument. +* `ENOMEM` - Not enough unallocated memory resources remain in the typed memory object designated by fildes to allocate +_len_ bytes. +* `ENOTSUP` - `MAP_FIXED` or `MAP_PRIVATE` was specified in the _flags_ argument and the implementation does not support +this functionality. The implementation does not support the combination of accesses requested in the _prot_ argument. - * `ENXIO` - Addresses in the range [off,off+_len_) are invalid for the object specified by fildes. +* `ENXIO` - Addresses in the range (off,off+_len_) are invalid for the object specified by fildes. - * `ENXIO` - `MAP_FIXED` was specified in _flags_ and the combination of _addr_, _len_, and off is invalid for the -object specified by fildes. +* `ENXIO` - `MAP_FIXED` was specified in _flags_ and the combination of _addr_, _len_, and off is invalid for the object +specified by fildes. - * `ENXIO` - The fildes argument refers to a typed memory object that is not accessible from the calling process. - - * `EOVERFLOW` - The file is a regular file and the value of off plus _len_ exceeds the offset maximum established in the open file -description associated with fildes. +* `ENXIO` - The fildes argument refers to a typed memory object that is not accessible from the calling process. +* `EOVERFLOW` - The file is a regular file and the value of off plus _len_ exceeds the offset maximum established in the +open file description associated with fildes. The `mmap()` function may fail if: - - - `EINVAL` - The _addr_ argument (if `MAP_FIXED` was specified) or off is not a multiple of the page size as returned by `sysconf()`, or is considered invalid by the implementation.
- - - - +* `EINVAL` - The _addr_ argument (if `MAP_FIXED` was specified) or off is not a multiple of the page size as returned by +`sysconf()`, or is considered invalid by the implementation. ## Tests @@ -232,6 +225,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/modf.part-impl.md b/libc/functions/m/modf.part-impl.md index 8a9f2be4..96033bbd 100644 --- a/libc/functions/m/modf.part-impl.md +++ b/libc/functions/m/modf.part-impl.md @@ -1,42 +1,38 @@ -# Synopsis -`#include `
+# Synopsis -` double modf(double x, double *iptr);`
+`#include ` -` float modff(float value, float *iptr);`
+`double modf(double x, double *iptr);` -` long double modfl(long double value, long double *iptr);`
+`float modff(float value, float *iptr);` + +`long double modfl(long double value, long double *iptr);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description These functions shall break the argument _x_ into integral and fractional parts, each of which has the same sign as the -argument. It stores the integral part as a double (for the `modf()` function), a float (for the `modff()` -function), or a long double (for the `modfl()` function), in the object pointed to by _iptr_. - +argument. It stores the integral part as a double (for the `modf()` function), a float (for the `modff()` function), or +a long double (for the `modfl()` function), in the object pointed to by _iptr_. ## Return value - Upon successful completion, these functions shall return the signed fractional part of _x_. -If -_x_ is `NaN`, a `NaN` shall be returned, and _*iptr_ shall be set to a `NaN`. - -If _x_ is `±Inf`, `±0` shall be returned, and _*iptr_ shall be set to `±Inf`. +* If _x_ is `NaN`, a `NaN` shall be returned, and _*iptr_ shall be set to a `NaN`. +* If _x_ is `±Inf`, `±0` shall be returned, and _*iptr_ shall be set to `±Inf`. ## Errors - No errors are defined. - - - ## Tests Untested @@ -45,6 +41,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/msgrecv.phrtos.md b/libc/functions/m/msgrecv.phrtos.md index 994fb4fa..30a46e6f 100644 --- a/libc/functions/m/msgrecv.phrtos.md +++ b/libc/functions/m/msgrecv.phrtos.md @@ -1,27 +1,36 @@ -# Synopsis +# Synopsis + `#include ` `int msgRecv(uint32_t port, msg_t *m, unsigned long int *rid);` ## Status + Implemented + ## Conformance + Phoenix-RTOS specific + ## Description -This function should read a message from _port_ and store its contents in `msg_t` structure pointed by _m_. _rid_ parameter specifies receiving context and should be passed to `msgRespond()`. +This function should read a message from _port_ and store its contents in `msg_t` structure pointed by _m_. _rid_ +parameter specifies receiving context and should be passed to `msgRespond()`. Upon calling `msgRecv()` the receiving thread is suspended until one of the following occurs: - - a new message is received - - port is closed - - an error occurs - - signal is received - - `msgRecv()` does not finish the communication between sender and receiver and is only used to get contents of a message. To properly finish the communication `msgRespond()` shall be called with appropriate `*rid` value to respond to the message and end communication between processes. If no `msgRespond()` is called the message sender will wait indefinetely for a response. +- a new message is received +- port is closed +- an error occurs +- signal is received -This function is part of interprocess communicaition mechanisms in Phoenix-RTOS. For more information about messaging process and `msg_t` message structure please refer to [Message Passing](../../../kernel/proc/msg.md). + `msgRecv()` does not finish the communication between sender and receiver and is only used to get contents of a + message. To properly finish the communication `msgRespond()` shall be called with appropriate `*rid` value to + respond to the message and end communication between processes. If no `msgRespond()` is called the message sender + will wait indefinetely for a response. +This function is part of interprocess communicaition mechanisms in Phoenix-RTOS. For more information about messaging +process and `msg_t` message structure please refer to [Message Passing](../../../kernel/proc/msg.md). ## Return value @@ -31,11 +40,11 @@ If an error occurred during a function call an error value shall be returned. Ot This function shall fall if: - * `-EINVAL` - _port_ does not name an existing port, or _port_ is closed +- `-EINVAL` - _port_ does not name an existing port, or _port_ is closed - * `-EINTR` - thread was woken up by signal during waiting for messages in `msgRecv()` +- `-EINTR` - thread was woken up by signal during waiting for messages in `msgRecv()` - * `-ENOMEM` - insufficient memory is available for allocating incoming message +- `-ENOMEM` - insufficient memory is available for allocating incoming message ## Tests @@ -45,7 +54,8 @@ Untested None -## See Also -1. [IPC mechanisms in Phoenix-RTOS](../../../architecture.md#interprocess-communication) +## See Also + +1. [IPC mechanisms in Phoenix-RTOS](../../../architecture.md#interprocess-communication) 2. [Standard library functions](../README.md) 3. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/msgrespond.phrtos.md b/libc/functions/m/msgrespond.phrtos.md index 5625ce40..866422c1 100644 --- a/libc/functions/m/msgrespond.phrtos.md +++ b/libc/functions/m/msgrespond.phrtos.md @@ -1,18 +1,25 @@ -# Synopsis +# Synopsis + `#include ` `int msgRespond(uint32_t port, msg_t *m, unsigned long int rid);` ## Status + Implemented + ## Conformance + Phoenix-RTOS specific -## Description -Finishes the communication between processes by responding to sender of initial message _msg_ with modified output buffer to _port_ from which the message was read. Response ID _rid_ specifies message context and should be passed from _rid_ acquired via `msgRecv()` call. +## Description -This function is part of interprocess communicaition mechanisms in Phoenix-RTOS. For more information about messaging process and `msg_t` message structure please refer to [Message Passing](../../../kernel/proc/msg.md). +Finishes the communication between processes by responding to sender of initial message _msg_ with modified output +buffer to _port_ from which the message was read. Response ID _rid_ specifies message context and should be passed from +_rid_ acquired via `msgRecv()` call. +This function is part of interprocess communicaition mechanisms in Phoenix-RTOS. For more information about messaging +process and `msg_t` message structure please refer to [Message Passing](../../../kernel/proc/msg.md). ## Return value @@ -22,7 +29,7 @@ If an error occurs during a function call an error value shall be returned. Othe This function shall fall if: - * `-EINVAL` - _port_ does not name an existing port, or _port_ is closed +* `-EINVAL` - _port_ does not name an existing port, or _port_ is closed ## Tests @@ -30,9 +37,10 @@ Untested ## Known bugs - - Does not check if message pointer _m_ is not `NULL`. +* Does not check if message pointer _m_ is not `NULL`. + +## See Also -## See Also -1. [IPC mechanisms in Phoenix-RTOS](../../../architecture.md#interprocess-communication) +1. [IPC mechanisms in Phoenix-RTOS](../../../architecture.md#interprocess-communication) 2. [Standard library functions](../README.md) 3. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/msgsend.phrtos.md b/libc/functions/m/msgsend.phrtos.md index e1f65154..4eec1ee1 100644 --- a/libc/functions/m/msgsend.phrtos.md +++ b/libc/functions/m/msgsend.phrtos.md @@ -1,21 +1,29 @@ -# Synopsis +# Synopsis + `#include ` `int msgSend(uint32_t port, msg_t *m);` ## Status + Implemented + ## Conformance + Phoenix-RTOS specific + ## Description -This function sends a message _m_ to specified _port_. _m_ should point to an `msg_t` structure that stores message data. +This function sends a message _m_ to specified _port_. _m_ should point to an `msg_t` structure that stores +message data. -After calling the `msgSend()` function the sending thread is suspended until the receiving thread executes `msgRecv()` function, reads data from input buffer, writes the final answer to the output buffer and executes `msgRespond()`. +After calling the `msgSend()` function the sending thread is suspended until the receiving thread executes `msgRecv()` +function, reads data from input buffer, writes the final answer to the output buffer and executes `msgRespond()`. This function ensures that either message was processed by a recipient or that it was not sent at all. -This function is part of interprocess communication mechanisms in Phoenix-RTOS. For more information about messaging process and `msg_t` message structure please refer to [Message Passing](../../../kernel/proc/msg.md). +This function is part of interprocess communication mechanisms in Phoenix-RTOS. For more information about messaging +process and `msg_t` message structure please refer to [Message Passing](../../../kernel/proc/msg.md). ## Return value @@ -25,11 +33,12 @@ If an error occurred during a function call an error value shall be returned. Ot This function shall fall if: - * `-EINVAL` - _port_ does not name an existing port, or _port_ is closed, or _m_ points to an uninitialized message structure. +* `-EINVAL` - _port_ does not name an existing port, or _port_ is closed, or _m_ points to an uninitialized message + structure. This function may fall if: - * `-EINTR` - calling thread was woken up by signal before the message was received by the server. +* `-EINTR` - calling thread was woken up by signal before the message was received by the server. ## Tests @@ -39,7 +48,8 @@ Untested None -## See Also -1. [IPC mechanisms in Phoenix-RTOS](../../../architecture.md#interprocess-communication) +## See Also + +1. [IPC mechanisms in Phoenix-RTOS](../../../architecture.md#interprocess-communication) 2. [Standard library functions](../README.md) 3. [Table of Contents](../../../README.md) diff --git a/libc/functions/m/munmap.part-impl.md b/libc/functions/m/munmap.part-impl.md index 97817a21..f62d5fcc 100644 --- a/libc/functions/m/munmap.part-impl.md +++ b/libc/functions/m/munmap.part-impl.md @@ -1,62 +1,57 @@ -# Synopsis -`#include `
+# Synopsis -` int munmap(void *addr, size_t len);`
+`#include ` + +`int munmap(void *addr, size_t len);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `munmap()` function shall remove any mappings for those entire pages containing any part of the address space of the process starting at _addr_ and continuing for _len_ bytes. Further references to these pages shall result in the -generation of a `SIGSEGV` signal to the process. If there are no mappings in the specified address range, then `munmap()` has no -effect. +generation of a `SIGSEGV` signal to the process. If there are no mappings in the specified address range, then +`munmap()` has no effect. The implementation may require that _addr_ be a multiple of the page size as returned by `sysconf()`. If a mapping to be removed was private, any modifications made in this address range shall be discarded. -Any memory locks (see `mlock()` and `mlockall()`) associated with this address range shall be removed, as if by an appropriate -call to `munlock()`. +Any memory locks (see `mlock()` and `mlockall()`) associated with this address range shall be removed, as if by an +appropriate call to `munlock()`. -If a mapping removed from a typed memory object causes the corresponding address range of the memory pool to be inaccessible by any -process in the system except through allocatable mappings (that is, mappings of typed memory objects opened with the -`POSIX_TYPED_MEM_MAP_ALLOCATABLE` flag), then that range of the memory pool shall become deallocated and may become available to -satisfy future typed memory allocation requests. +If a mapping removed from a typed memory object causes the corresponding address range of the memory pool to be +inaccessible by any process in the system except through allocatable mappings (that is, mappings of typed memory objects +opened with the `POSIX_TYPED_MEM_MAP_ALLOCATABLE` flag), then that range of the memory pool shall become deallocated and +may become available to satisfy future typed memory allocation requests. -A mapping removed from a typed memory object opened with the `POSIX_TYPED_MEM_MAP_ALLOCATABLE` flag shall not affect in any way -the availability of that typed memory for allocation. +A mapping removed from a typed memory object opened with the `POSIX_TYPED_MEM_MAP_ALLOCATABLE` flag shall not affect in +any way the availability of that typed memory for allocation. The behavior of this function is unspecified if the mapping was not established by a call to `mmap()`. - ## Return value - Upon successful completion, `munmap()` shall return `0`; otherwise, it shall return `-1` and set `errno` to indicate the error. - ## Errors - The `munmap()` function shall fail if: - - * `EINVAL` - Addresses in the range [_addr_,_addr_+_len_) are outside the valid range for the address space of a +* `EINVAL` - Addresses in the range (_addr_,_addr_+_len_) are outside the valid range for the address space of a process. - * `EINVAL` - The _len_ argument is `0`.
- -The `munmap()` function may fail if:
- - * `EINVAL` - The _addr_ argument is not a multiple of the page size as returned by `sysconf()`.
- - +* `EINVAL` - The _len_ argument is `0`. +The `munmap()` function may fail if: +* `EINVAL` - The _addr_ argument is not a multiple of the page size as returned by `sysconf()`. ## Tests @@ -66,6 +61,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/o/open.part-impl.md b/libc/functions/o/open.part-impl.md index b817ae27..3a7df3a5 100644 --- a/libc/functions/o/open.part-impl.md +++ b/libc/functions/o/open.part-impl.md @@ -1,248 +1,255 @@ -# Synopsis -`#include `
+# Synopsis -`#include `
+`#include ` -` int open(const char *path, int oflag, ...);`
+`#include ` -` int openat(int fd, const char *path, int oflag, ...);`
+`int open(const char *path, int oflag, ...);` + +`int openat(int fd, const char *path, int oflag, ...);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `open()` function shall establish the connection between a file and a file descriptor. It shall create an open file -description that refers to a file and a file descriptor that refers to that open file description. The file descriptor is used by -other I/O functions to refer to that file. The _path_ argument points to a pathname naming the file. +description that refers to a file and a file descriptor that refers to that open file description. The file descriptor +is used by other I/O functions to refer to that file. The _path_ argument points to a pathname naming the file. -The `open()` function shall return a file descriptor for the named file, allocated as described in File Descriptor Allocation. The open file description is new, and therefore the -file descriptor shall not share it with any other process in the system. The `FD_CLOEXEC` file descriptor flag associated with the -new file descriptor shall be cleared unless the `O_CLOEXEC` flag is set in _oflag_. +The `open()` function shall return a file descriptor for the named file, allocated as described in File Descriptor +Allocation. The open file description is new, and therefore the file descriptor shall not share it with any other +process in the system. The `FD_CLOEXEC` file descriptor flag associated with the new file descriptor shall be +cleared unless the `O_CLOEXEC` flag is set in _oflag_. The file offset used to mark the current position within the file shall be set to the beginning of the file. -The file status flags and file access modes of the open file description shall be set according to the value of -_oflag_. - -Values for _oflag_ are constructed by a bitwise-inclusive OR of flags from the following list, defined in ``. Applications shall specify exactly one of the first five values (file access -modes) below in the value of _oflag_: - - * `O_EXEC` - Open for execute only (non-directory files). The result is unspecified if this flag is applied to a directory. +The file status flags and file access modes of the open file description shall be set according to the value of _oflag_. - * `O_RDONLY` - Open for reading only. +Values for _oflag_ are constructed by a bitwise-inclusive OR of flags from the following list, defined in ``. +Applications shall specify exactly one of the first five values (file access modes) below in the value of _oflag_: - * `O_RDWR` - Open for reading and writing. The result is undefined if this flag is applied to a `FIFO`. - - * `O_SEARCH` - Open directory for search only. The result is unspecified if this flag is applied to a non-directory file. - - * `O_WRONLY` - Open for writing only. +* `O_EXEC` - Open for execute only (non-directory files). The result is unspecified if this flag is applied to a +directory. +* `O_RDONLY` - Open for reading only. +* `O_RDWR` - Open for reading and writing. The result is undefined if this flag is applied to a `FIFO`. +* `O_SEARCH` - Open directory for search only. The result is unspecified if this flag is applied to a non-directory +file. +* `O_WRONLY` - Open for writing only. Any combination of the following may be used: - * `O_APPEND` - If set, the file offset shall be set to the end of the file prior to each write. - - * `O_CLOEXEC` - If set, the `FD_CLOEXEC` flag for the new file descriptor shall be set. - - * `O_CREAT` - If the file exists, this flag has no effect except as noted under `O_EXCL` below. Otherwise, if `O_DIRECTORY` is not set the file -shall be created as a regular file; the user ID of the file shall be set to the effective user ID of the process; the group ID of -the file shall be set to the group ID of the file's parent directory or to the effective group ID of the process; and the access -permission bits (see ``) of the file mode shall be set to the -value of the argument following the _oflag_ argument taken as type `mode_t` modified as follows: a bitwise `AND` is -performed on the file-mode bits and the corresponding bits in the complement of the process' file mode creation mask. Thus, all -bits in the file mode whose corresponding bit in the file mode creation mask is set are cleared. When bits other than the file -permission bits are set, the effect is unspecified. The argument following the _oflag_ argument does not affect whether the -file is open for reading, writing, or for both. Implementations shall provide a way to initialize the file's group ID to the group -ID of the parent directory. Implementations may, but need not, provide an implementation-defined way to initialize the file's group -ID to the effective group ID of the calling process. - - * `O_DIRECTORY` - If _path_ resolves to a non-directory file, fail and set `errno` to `ENOTDIR`. +* `O_APPEND` - If set, the file offset shall be set to the end of the file prior to each write. +* `O_CLOEXEC` - If set, the `FD_CLOEXEC` flag for the new file descriptor shall be set. +* `O_CREAT` - If the file exists, this flag has no effect except as noted under `O_EXCL` below. Otherwise, if +`O_DIRECTORY` is not set the file shall be created as a regular file; the user ID of the file shall be set to the +effective user ID of the process; the group ID of the file shall be set to the group ID of the file's parent directory +or to the effective group ID of the process; and the access permission bits (see ``) of the file mode shall +be set to the value of the argument following the _oflag_ argument taken as type `mode_t` modified as follows: a bitwise +`AND` is performed on the file-mode bits and the corresponding bits in the complement of the process' file mode creation +mask. Thus, all bits in the file mode whose corresponding bit in the file mode creation mask is set are cleared. When +bits other than the file permission bits are set, the effect is unspecified. The argument following the _oflag_ argument +does not affect whether the file is open for reading, writing, or for both. Implementations shall provide a way to +initialize the file's group ID to the group ID of the parent directory. Implementations may, but need not, provide +an implementation-defined way to initialize the file's group ID to the effective group ID of the calling process. + +* `O_DIRECTORY` - If _path_ resolves to a non-directory file, fail and set `errno` to `ENOTDIR`. + +* `O_DSYNC` - Write I/O operations on the file descriptor shall complete as defined by synchronized I/O data integrity +completion. + +* `O_EXCL` - If `O_CREAT` and `O_EXCL` are set, `open()` shall fail if the file exists. The check for the existence of +the file and the +creation of the file if it does not exist shall be atomic with respect to other threads executing `open()` naming the +same filename in the same directory with `O_EXCL` and `O_CREAT` set. If `O_EXCL` and `O_CREAT` are set, and _path_ names +a symbolic link, `open()` shall fail and set `errno` to `EEXIST`, regardless of the contents of the symbolic link. If +`O_EXCL` is set and `O_CREAT` is not set, the result is undefined. + +* `O_NOCTTY` - If set and path identifies a terminal device, `open()` shall not cause the terminal device to become the +controlling terminal for the process. If _path_ does not identify a terminal device, `O_NOCTTY` shall be ignored. - * `O_DSYNC` - Write I/O operations on the file descriptor shall complete as defined by synchronized I/O data integrity completion. +* `O_NOFOLLOW` - If _path_ names a symbolic link, fail and set `errno` to `ELOOP`. - * `O_EXCL` - If `O_CREAT` and `O_EXCL` are set, `open()` shall fail if the file exists. The check for the existence of the file and the -creation of the file if it does not exist shall be atomic with respect to other threads executing `open()` naming the same -filename in the same directory with `O_EXCL` and `O_CREAT` set. If `O_EXCL` and `O_CREAT` are set, and _path_ names a symbolic link, -`open()` shall fail and set `errno` to `EEXIST`, regardless of the contents of the symbolic link. If `O_EXCL` is set and -`O_CREAT` is not set, the result is undefined. +* `O_NONBLOCK` + * When opening a `FIFO` with `O_RDONLY` or `O_WRONLY` set: - * `O_NOCTTY` - If set and path identifies a terminal device, `open()` shall not cause the terminal device to become the -controlling terminal for the process. If _path_ does not identify a terminal device, `O_NOCTTY` shall be ignored. + * If `O_NONBLOCK` is set, an `open()` for reading-only shall return without delay. An `open()` for writing-only + shall return an error if no process currently has the file open for reading. - * `O_NOFOLLOW` - If _path_ names a symbolic link, fail and set `errno` to `ELOOP`. + * If `O_NONBLOCK` is clear, an `open()` for reading-only shall block the calling thread until a thread opens the + file for writing. An `open()` for writing-only shall block the calling thread until a thread opens the file for + reading. - * `O_NONBLOCK` - * When opening a `FIFO` with `O_RDONLY` or `O_WRONLY` set: + * When opening a block special or character special file that supports non-blocking opens: - * If `O_NONBLOCK` is set, an `open()` for reading-only shall return without delay. An `open()` for writing-only shall return an error if no process currently has the file open for reading. + * If `O_NONBLOCK` is set, the `open()` function shall return without blocking for the device to be ready or + available. Subsequent behavior of the device is device-specific. - * If `O_NONBLOCK` is clear, an `open()` for reading-only shall block the calling thread until a thread opens the file for writing. An `open()` for writing-only shall block the calling thread until a thread opens the file for reading. + * If `O_NONBLOCK` is clear, the `open()` function shall block the calling thread until the device is ready or + available before returning. - * When opening a block special or character special file that supports non-blocking opens: + * Otherwise, the `O_NONBLOCK` flag shall not cause an error, but it is unspecified whether the file status flags will + include the `O_NONBLOCK` flag. - * If `O_NONBLOCK` is set, the `open()` function shall return without blocking for the device to be ready or available. Subsequent behavior of the device is device-specific. +* `O_RSYNC` - Read I/O operations on the file descriptor shall complete at the same level of integrity as specified by +the `O_DSYNC` and `O_SYNC` flags. If both `O_DSYNC` and `O_RSYNC` are set in _oflag_, all I/O operations on the file +descriptor shall complete as defined by synchronized I/O data integrity completion. If both `O_SYNC` and `O_RSYNC` are +set in flags, all I/O operations on the file descriptor shall complete as defined by synchronized I/O file integrity +completion. - * If `O_NONBLOCK` is clear, the `open()` function shall block the calling thread until the device is ready or available before returning. +* `O_SYNC` - Write I/O operations on the file descriptor shall complete as defined by synchronized I/O file integrity +completion. The `O_SYNC` flag shall be supported for regular files, even if the Synchronized Input and Output option +is not supported. - * Otherwise, the `O_NONBLOCK` flag shall not cause an error, but it is unspecified whether the file status flags will include the -`O_NONBLOCK` flag. +* `O_TRUNC` - If the file exists and is a regular file, and the file is successfully opened `O_RDWR` or `O_WRONLY,` its +length shall be truncated to `0`, and the mode and owner shall be unchanged. It shall have no effect on `FIFO` special +files or terminal device files. Its effect on other file types is implementation-defined. The result of using `O_TRUNC` +without either `O_RDWR` or `O_WRONLY` is undefined. - * `O_RSYNC` - Read I/O operations on the file descriptor shall complete at the same level of integrity as specified by the `O_DSYNC` and `O_SYNC` -flags. If both `O_DSYNC` and `O_RSYNC` are set in _oflag_, all I/O operations on the file descriptor shall complete as defined by -synchronized I/O data integrity completion. If both `O_SYNC` and `O_RSYNC` are set in flags, all I/O operations on the file descriptor -shall complete as defined by synchronized I/O file integrity completion. +* `O_TTY_INIT` - If path identifies a terminal device other than a pseudo-terminal, the device is not already open in +any process, and either `O_TTY_INIT` is set in _oflag_ or `O_TTY_INIT` has the value zero, `open()` shall set any +non-standard termios structure terminal parameters to a state that provides conforming behavior; see XBD Parameters +that Can be Set. It is unspecified whether `O_TTY_INIT` has any effect if the device is already open in any process. If +_path_ identifies the slave side of a pseudo-terminal that is not already open in any process, `open()` shall set any +non-standard termios structure terminal parameters to a state that provides conforming behavior, regardless of whether +`O_TTY_INIT` is set. If _path_ does not identify a terminal device, `O_TTY_INIT` shall be ignored. - * `O_SYNC` - Write I/O operations on the file descriptor shall complete as defined by synchronized I/O file integrity completion. The `O_SYNC` flag shall be supported for regular files, even if the Synchronized Input and Output option is not supported. +If `O_CREAT` and `O_DIRECTORY` are set and the requested access mode is neither `O_WRONLY` nor `O_RDWR,` the result is +unspecified. - * `O_TRUNC` - If the file exists and is a regular file, and the file is successfully opened `O_RDWR` or `O_WRONLY,` its length shall be truncated -to `0`, and the mode and owner shall be unchanged. It shall have no effect on `FIFO` special files or terminal device files. Its effect -on other file types is implementation-defined. The result of using `O_TRUNC` without either `O_RDWR` or `O_WRONLY` is undefined. +If `O_CREAT` is set and the file did not previously exist, upon successful completion, `open()` shall mark for update +the last data access, last data modification, and last file status change timestamps of the file and the last data +modification and last file status change timestamps of the parent directory. - * `O_TTY_INIT` - If path identifies a terminal device other than a pseudo-terminal, the device is not already open in any process, and -either `O_TTY_INIT` is set in _oflag_ or `O_TTY_INIT` has the value zero, `open()` shall set any non-standard termios -structure terminal parameters to a state that provides conforming behavior; see XBD Parameters that Can be Set. It is unspecified whether `O_TTY_INIT` has any effect -if the device is already open in any process. If _path_ identifies the slave side of a pseudo-terminal that is not already -open in any process, `open()` shall set any non-standard termios structure terminal parameters to a state that provides -conforming behavior, regardless of whether `O_TTY_INIT` is set. If _path_ does not identify a terminal device, `O_TTY_INIT` shall -be ignored. +If `O_TRUNC` is set and the file did previously exist, upon successful completion, `open()` shall mark for update the +last data modification and last file status change timestamps of the file. -If `O_CREAT` and `O_DIRECTORY` are set and the requested access mode is neither `O_WRONLY` nor `O_RDWR,` the result is unspecified. +If both the `O_SYNC` and `O_DSYNC` flags are set, the effect is as if only the `O_SYNC` flag was set. -If `O_CREAT` is set and the file did not previously exist, upon successful completion, `open()` shall mark for update the -last data access, last data modification, and last file status change timestamps of the file and the last data modification and -last file status change timestamps of the parent directory. +If path refers to a `STREAMS` file, _oflag_ may be constructed from `O_NONBLOCK` OR'ed with either `O_RDONLY,` +`O_WRONLY,` or `O_RDWR`. Other flag values are not applicable to `STREAMS` devices and shall have no effect on them. +The value `O_NONBLOCK` affects the operation of `STREAMS` drivers and certain functions applied to file descriptors +associated with `STREAMS` files. For `STREAMS` drivers, the implementation of `O_NONBLOCK` is device-specific. -If `O_TRUNC` is set and the file did previously exist, upon successful completion, `open()` shall mark for update the last -data modification and last file status change timestamps of the file. +The application shall ensure that it specifies the `O_TTY_INIT` flag on the first open of a terminal device since +system boot or since the device was closed by the process that last had it open. The application need not specify the +`O_TTY_INIT` flag when opening pseudo-terminals.  If _path_ names the master side of a pseudo-terminal device, then it +is unspecified whether `open()` locks the slave side so that it cannot be opened. Conforming applications shall call +`unlockpt()` before opening the slave side. -If both the `O_SYNC` and `O_DSYNC` flags are set, the effect is as if only the `O_SYNC` flag was set. - -If path refers to a `STREAMS` file, _oflag_ may be constructed from `O_NONBLOCK` OR'ed with either `O_RDONLY,` `O_WRONLY,` -or `O_RDWR`. Other flag values are not applicable to `STREAMS` devices and shall have no effect on them. The value `O_NONBLOCK` affects -the operation of `STREAMS` drivers and certain functions applied to file descriptors associated with `STREAMS` files. For `STREAMS` -drivers, the implementation of `O_NONBLOCK` is device-specific. -The application shall ensure that it specifies the `O_TTY_INIT` flag on the first open of a terminal device since system boot or -since the device was closed by the process that last had it open. The application need not specify the `O_TTY_INIT` flag when opening -pseudo-terminals.  If _path_ names the master side of a pseudo-terminal device, then it is unspecified whether -`open()` locks the slave side so that it cannot be opened. Conforming applications shall call `unlockpt()` before opening the slave side. -The largest value that can be represented correctly in an object of type `off_t` shall be established as the offset maximum -in the open file description. +The largest value that can be represented correctly in an object of type `off_t` shall be established as the offset +maximum in the open file description. The `openat()` function shall be equivalent to the `open()` function except in the case where _path_ specifies a -relative path. In this case the file to be opened is determined relative to the directory associated with the file descriptor -_fd_ instead of the current working directory. If the access mode of the open file description associated with the file -descriptor is not `O_SEARCH,` the function shall check whether directory searches are permitted using the current permissions of the -directory underlying the file descriptor. If the access mode is `O_SEARCH,` the function shall not perform the check. +relative path. In this case the file to be opened is determined relative to the directory associated with the file +descriptor _fd_ instead of the current working directory. If the access mode of the open file description associated +with the file descriptor is not `O_SEARCH,` the function shall check whether directory searches are permitted using +the current permissions of the directory underlying the file descriptor. If the access mode is `O_SEARCH,` the function +shall not perform the check. The _oflag_ parameter and the optional fourth parameter correspond exactly to the parameters of `open()`. If `openat()` is passed the special value `AT_FDCWD` in the _fd_ parameter, the current working directory shall be used and the behavior shall be identical to a call to `open()`. - ## Return value - Upon successful completion, these functions shall open the file and return a non-negative integer representing the file -descriptor. Otherwise, these functions shall return `-1` and set `errno` to indicate the error. If `-1` is returned, no files -shall be created or modified. - - +descriptor. Otherwise, these functions shall return `-1` and set `errno` to indicate the error. If `-1` is returned, no +files shall be created or modified. ## Errors - These functions shall fail if: +* `EACCES` - Search permission is denied on a component of the _path_ prefix, or the file exists and the permissions +specified by _oflag_ are denied, or the file does not exist and write permission is denied for the parent directory of +the file to be created, or `O_TRUNC` is specified and write permission is denied. - * `EACCES` - Search permission is denied on a component of the _path_ prefix, or the file exists and the permissions specified by _oflag_ -are denied, or the file does not exist and write permission is denied for the parent directory of the file to be created, or -`O_TRUNC` is specified and write permission is denied. - - * `EEXIST` - `O_CREAT` and `O_EXCL` are set, and the named file exists. +* `EEXIST` - `O_CREAT` and `O_EXCL` are set, and the named file exists. - * `EINTR` - A signal was caught during `open()`. +* `EINTR` - A signal was caught during `open()`. - * `EINVAL` - The implementation does not support synchronized I/O for this file. +* `EINVAL` - The implementation does not support synchronized I/O for this file. - * `EIO` - The _path_ argument names a `STREAMS` file and a hangup or error occurred during the `open()`. +* `EIO` - The _path_ argument names a `STREAMS` file and a hangup or error occurred during the `open()`. - * `EISDIR` - The named file is a directory and _oflag_ includes O_WRONLY or `O_RDWR`, or includes `O_CREAT` without `O_DIRECTORY`. +* `EISDIR` - The named file is a directory and _oflag_ includes O_WRONLY or `O_RDWR`, or includes `O_CREAT` without +`O_DIRECTORY`. - * `ELOOP` - A loop exists in symbolic links encountered during resolution of the _path_ argument, or `O_NOFOLLOW` was specified and the -_path_ argument names a symbolic link. +* `ELOOP` - A loop exists in symbolic links encountered during resolution of the _path_ argument, or `O_NOFOLLOW` was +specified and the _path_ argument names a symbolic link. - * `EMFILE` - All file descriptors available to the process are currently open. -`ENAMETOOLONG` +* `EMFILE` - All file descriptors available to the process are currently open. -The length of a component of a pathname is longer than `NAME_MAX`. +* `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. - * `ENFILE` - The maximum allowable number of files is currently open in the system. +* `ENFILE` - The maximum allowable number of files is currently open in the system. - * `ENOENT` - `O_CREAT` is not set and a component of _path_ does not name an existing file, or `O_CREAT` is set and a component of the _path_ +* `ENOENT` - `O_CREAT` is not set and a component of _path_ does not name an existing file, or `O_CREAT` is set and a +component of the _path_ prefix of _path_ does not name an existing file, or _path_ points to an empty string. - * `ENOENT` or `ENOTDIR` - `O_CREAT` is set, and the path argument contains at least one non- `` character and ends with one or more trailing -`` characters. If path without the trailing `` characters would name an existing file, an `ENOENT` -error shall not occur. +* `ENOENT` or `ENOTDIR` - `O_CREAT` is set, and the path argument contains at least one non- `` character and +ends with one or more trailing `` characters. If path without the trailing `` characters would name an +existing file, an `ENOENT` error shall not occur. - * `ENOSR` - The path argument names a `STREAMS`-based file and the system is unable to allocate a `STREAM`. +* `ENOSR` - The path argument names a `STREAMS`-based file and the system is unable to allocate a `STREAM`. - * `ENOSPC` - The directory or file system that would contain the new file cannot be expanded, the file does not exist, and `O_CREAT` is -specified. +* `ENOSPC` - The directory or file system that would contain the new file cannot be expanded, the file does not exist, +and `O_CREAT` is specified. - * `ENOTDIR` - A component of the path prefix names an existing file that is neither a directory nor a symbolic link to a directory; or -`O_CREAT` and `O_EXCL` are not specified, the path argument contains at least one non- `` character and ends with one -or more trailing `` characters, and the last pathname component names an existing file that is neither a directory nor a -symbolic link to a directory; or `O_DIRECTORY` was specified and the path argument resolves to a non-directory file. +* `ENOTDIR` - A component of the path prefix names an existing file that is neither a directory nor a symbolic link to a +directory; or `O_CREAT` and `O_EXCL` are not specified, the path argument contains at least one non- `` character +and ends with one or more trailing `` characters, and the last pathname component names an existing file that is +neither a directory nor a symbolic link to a directory; or `O_DIRECTORY` was specified and the path argument resolves +to a non-directory file. - * `ENXIO` - `O_NONBLOCK` is set, the named file is a `FIFO`, `O_WRONLY` is set, and no process has the file open for reading. +* `ENXIO` - `O_NONBLOCK` is set, the named file is a `FIFO`, `O_WRONLY` is set, and no process has the file open for +reading. - * `ENXIO` - The named file is a character special or block special file, and the device associated with this special file does not -exist. +* `ENXIO` - The named file is a character special or block special file, and the device associated with this special +file does not exist. - * `EOVERFLOW` - The named file is a regular file and the size of the file cannot be represented correctly in an object of type -off_t. +* `EOVERFLOW` - The named file is a regular file and the size of the file cannot be represented correctly in an object +of type off_t. - * `EROFS` - The named file resides on a read-only file system and either `O_WRONLY`, `O_RDWR`, `O_CREAT` (if the file does not exist), or `O_TRUNC` -is set in the _oflag_ argument. +* `EROFS` - The named file resides on a read-only file system and either `O_WRONLY`, `O_RDWR`, `O_CREAT` (if the file +does not exist), or `O_TRUNC` is set in the _oflag_ argument. The `openat()` function shall fail if: +* `EACCES` - The access mode of the open file description associated with _fd_ is not `O_SEARCH` and the permissions of +the directory underlying _fd_ do not permit directory searches. - * `EACCES` - The access mode of the open file description associated with _fd_ is not `O_SEARCH` and the permissions of the directory -underlying _fd_ do not permit directory searches. +* `EBADF` - The path argument does not specify an absolute path and the _fd_ argument is neither `AT_FDCWD` nor a valid +file descriptor open for reading or searching. - * `EBADF` - The path argument does not specify an absolute path and the _fd_ argument is neither `AT_FDCWD` nor a valid file -descriptor open for reading or searching. - - * `ENOTDIR` - The path argument is not an absolute path and _fd_ is a file descriptor associated with a non-directory file. +* `ENOTDIR` - The path argument is not an absolute path and _fd_ is a file descriptor associated with a non-directory +file. These functions may fail if: +* `EAGAIN` - The path argument names the slave side of a pseudo-terminal device that is locked. - * `EAGAIN` - -The path argument names the slave side of a pseudo-terminal device that is locked. - - * `EINVAL` - The value of the _oflag_ argument is not valid. - - * `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the path argument. -`ENAMETOOLONG` - -The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an intermediate result with a -length that exceeds `PATH_MAX`. +* `EINVAL` - The value of the _oflag_ argument is not valid. - * `ENOMEM` - The path argument names a `STREAMS` file and the system is unable to allocate resources. - - * `EOPNOTSUPP` - The path argument names a socket. - - * `ETXTBSY` - The file is a pure procedure (shared text) file that is being executed and _oflag_ is `O_WRONLY` or `O_RDWR`. +* `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the path argument. +* `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an +intermediate result with a length that exceeds `PATH_MAX`. +* `ENOMEM` - The path argument names a `STREAMS` file and the system is unable to allocate resources. +* `EOPNOTSUPP` - The path argument names a socket. +* `ETXTBSY` - The file is a pure procedure (shared text) file that is being executed and _oflag_ is `O_WRONLY` or +`O_RDWR`. ## Tests @@ -252,6 +259,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/o/opendir.part-impl.md b/libc/functions/o/opendir.part-impl.md index a2a766bf..c631e1bc 100644 --- a/libc/functions/o/opendir.part-impl.md +++ b/libc/functions/o/opendir.part-impl.md @@ -1,80 +1,78 @@ -# Synopsis -`#include `
+# Synopsis -` DIR *fdopendir(int fd);`
+`#include ` -` DIR *opendir(const char *dirname);`
+`DIR *fdopendir(int fd);` + +`DIR *opendir(const char *dirname);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `fdopendir()` function shall be equivalent to the `opendir()` function except that the directory is specified by a -file descriptor rather than by a name. The file offset associated with the file descriptor at the time of the call determines which -entries are returned. +file descriptor rather than by a name. The file offset associated with the file descriptor at the time of the call +determines which entries are returned. Upon successful return from `fdopendir()`, the file descriptor is under the control of the system, and if any attempt is -made to close the file descriptor, or to modify the state of the associated description, other than by means of `closedir()`, `readdir()`, `readdir_r()`, `rewinddir()`, or `seekdir()`, the behavior is -undefined. Upon calling `closedir()` the file descriptor shall be closed. +made to close the file descriptor, or to modify the state of the associated description, other than by means of +`closedir()`, `readdir()`, `readdir_r()`, `rewinddir()`, or `seekdir()`, the behavior is undefined. Upon calling +`closedir()` the file descriptor shall be closed. -It is unspecified whether the `FD_CLOEXEC` flag will be set on the file descriptor by a successful call to `fdopendir()`. +It is unspecified whether the `FD_CLOEXEC` flag will be set on the file descriptor by a successful call to +`fdopendir()`. The `opendir()` function shall open a directory stream corresponding to the directory named by the _dirname_ argument. -The directory stream is positioned at the first entry. If the type `DIR` is implemented using a file descriptor, applications -shall only be able to open up to a total of ``OPEN_MAX`` files and directories. - -If the type `DIR` is implemented using a file descriptor, the descriptor shall be obtained as if the `O_DIRECTORY` flag was -passed to `open()`. +The directory stream is positioned at the first entry. If the type `DIR` is implemented using a file descriptor, +applications shall only be able to open up to a total of ``OPEN_MAX`` files and directories. +If the type `DIR` is implemented using a file descriptor, the descriptor shall be obtained as if the `O_DIRECTORY` +flag was passed to `open()`. ## Return value - -Upon successful completion, these functions shall return a pointer to an object of type `DIR`. Otherwise, these functions -shall return a `null` pointer and set errno to indicate the error. - +Upon successful completion, these functions shall return a pointer to an object of type `DIR`. Otherwise, these +functions shall return a `null` pointer and set errno to indicate the error. ## Errors - The `fdopendir()` function shall fail if: +* `EBADF` - The _fd_ argument is not a valid file descriptor open for reading. - * `EBADF` - The _fd_ argument is not a valid file descriptor open for reading. - - * `ENOTDIR` - The descriptor _fd_ is not associated with a directory. +* `ENOTDIR` - The descriptor _fd_ is not associated with a directory. The `opendir()` function shall fail if: - * `EACCES` - Search permission is denied for the component of the path prefix of _dirname_ or read permission is denied for -_dirname_. - - * `ELOOP` - A loop exists in symbolic links encountered during resolution of the _dirname_ argument. +* `EACCES` - Search permission is denied for the component of the path prefix of _dirname_ or read permission is denied +for _dirname_. - * `ENAMETOOLONG` -The length of a component of a pathname is longer than `NAME_MAX`. +* `ELOOP` - A loop exists in symbolic links encountered during resolution of the _dirname_ argument. - * `ENOENT` - A component of _dirname_ does not name an existing directory or _dirname_ is an empty string. +* `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. - * `ENOTDIR` - A component of _dirname_ names an existing file that is neither a directory nor a symbolic link to a directory. +* `ENOENT` - A component of _dirname_ does not name an existing directory or _dirname_ is an empty string. +* `ENOTDIR` - A component of _dirname_ names an existing file that is neither a directory nor a symbolic link to a +directory. The `opendir()` function may fail if: +* `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the _dirname_ argument. - * `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the _dirname_ argument. +* `EMFILE` - All file descriptors available to the process are currently open. - * `EMFILE` - All file descriptors available to the process are currently open. - - * `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an intermediate result with a -length that exceeds `PATH_MAX`. - - * `ENFILE` - Too many files are currently open in the system. +* `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an +intermediate result with a length that exceeds `PATH_MAX`. +* `ENFILE` - Too many files are currently open in the system. ## Tests @@ -84,6 +82,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/o/openlog.part-impl.md b/libc/functions/o/openlog.part-impl.md index 0e21f22a..bc67c755 100644 --- a/libc/functions/o/openlog.part-impl.md +++ b/libc/functions/o/openlog.part-impl.md @@ -1,92 +1,97 @@ -# Synopsis -`#include `
+# Synopsis -` void closelog(void);`
+`#include ` -` void openlog(const char *ident, int logopt, int facility);`
+`void closelog(void);` -` int setlogmask(int maskpri);`
+`void openlog(const char *ident, int logopt, int facility);` -` void syslog(int priority, const char *message, ... /* arguments */); `
+`int setlogmask(int maskpri);` + +` void syslog(int priority, const char *message, ... /* arguments */); ` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `syslog()` function shall send a message to an implementation-defined logging facility, which may log it in an -implementation-defined system log, write it to the system console, forward it to a list of users, or forward it to the logging -facility on another host over the network. The logged message shall include a message header and a message body. The message header -contains at least a timestamp and a tag string. +implementation-defined system log, write it to the system console, forward it to a list of users, or forward it to the +logging facility on another host over the network. The logged message shall include a message header and a message body. +The message header contains at least a timestamp and a tag string. The message body is generated from the message and following arguments in the same manner as if these were arguments to -`printf()`, except that the additional conversion specification `%m` shall be -recognized; it shall convert no arguments, shall cause the output of the error message string associated with the value of -`errno` on entry to `syslog()`, and may be mixed with argument specifications of the `%n$` form. +`printf()`, except that the additional conversion specification `%m` shall be recognized; it shall convert no arguments, +shall cause the output of the error message string associated with the value of `errno` on entry to `syslog()`, and may +be mixed with argument specifications of the `%n$` form. If a complete conversion specification with the m conversion specifier character is not just `%m`, the behavior is undefined. A trailing `` may be added if needed. -Values of the _priority_ argument are formed by OR'ing together a severity-level value and an optional _facility_ value. If -no _facility_ value is specified, the current default facility value is used. +Values of the _priority_ argument are formed by OR'ing together a severity-level value and an optional _facility_ value. +If no _facility_ value is specified, the current default facility value is used. Possible values of severity level include: - * `LOG_EMERG` - A panic condition. +* `LOG_EMERG` - A panic condition. - * `LOG_ALERT`A condition that should be corrected immediately, such as a corrupted system database. +* `LOG_ALERT`A condition that should be corrected immediately, such as a corrupted system database. - * `LOG_CRIT` - Critical conditions, such as hard device errors. +* `LOG_CRIT` - Critical conditions, such as hard device errors. - * `LOG_ERR` - Errors. +* `LOG_ERR` - Errors. - * `LOG_WARNING` - Warning messages. +* `LOG_WARNING` - Warning messages. - * `LOG_NOTICE` - Conditions that are not error conditions, but that may require special handling. +* `LOG_NOTICE` - Conditions that are not error conditions, but that may require special handling. - * `LOG_INFO` - Informational messages. +* `LOG_INFO` - Informational messages. - * `LOG_DEBUG` - Messages that contain information normally of use only when debugging a program. +* `LOG_DEBUG` - Messages that contain information normally of use only when debugging a program. The _facility_ indicates the application or system component generating the message. Possible _facility_ values include: - * `LOG_USER` - Messages generated by arbitrary processes. This is the default facility identifier if none is specified. +* `LOG_USER` - Messages generated by arbitrary processes. This is the default facility identifier if none is specified. - * `LOG_LOCAL0` - Reserved for local use. +* `LOG_LOCAL0` - Reserved for local use. - * `LOG_LOCAL1` - Reserved for local use. +* `LOG_LOCAL1` - Reserved for local use. - * `LOG_LOCAL2` - Reserved for local use. +* `LOG_LOCAL2` - Reserved for local use. - * `LOG_LOCAL3` - Reserved for local use. +* `LOG_LOCAL3` - Reserved for local use. - * `LOG_LOCAL4` - Reserved for local use. +* `LOG_LOCAL4` - Reserved for local use. - * `LOG_LOCAL5` - Reserved for local use. +* `LOG_LOCAL5` - Reserved for local use. - * `LOG_LOCAL6` - Reserved for local use. +* `LOG_LOCAL6` - Reserved for local use. - * `LOG_LOCAL7` - Reserved for local use. +* `LOG_LOCAL7` - Reserved for local use. -The `openlog()` function shall set process attributes that affect subsequent calls to `syslog()`. The _ident_ -argument is a string that is prepended to every message. The _logopt_ argument indicates logging options. Values for -_logopt_ are constructed by a bitwise-inclusive OR of zero or more of the following: +The `openlog()` function shall set process attributes that affect subsequent calls to `syslog()`. The _ident_ argument +is a string that is prepended to every message. The _logopt_ argument indicates logging options. Values for _logopt_ are +constructed by a bitwise-inclusive OR of zero or more of the following: - * `LOG_PID` - Log the process ID with each message. This is useful for identifying specific processes. +* `LOG_PID` - Log the process ID with each message. This is useful for identifying specific processes. - * `LOG_CONS` - Write messages to the system console if they cannot be sent to the logging facility. The `syslog()` function ensures that +* `LOG_CONS` - Write messages to the system console if they cannot be sent to the logging facility. The `syslog()` + function ensures that the process does not acquire the console as a controlling terminal in the process of writing the message. - * `LOG_NDELAY` - Open the connection to the logging facility immediately. Normally the open is delayed until the first message is logged. This -is useful for programs that need to manage the order in which file descriptors are allocated. +* `LOG_NDELAY` - Open the connection to the logging facility immediately. Normally the open is delayed until the first + message is logged. This is useful for programs that need to manage the order in which file descriptors are allocated. - * `LOG_ODELAY` - Delay open until `syslog()` is called. +* `LOG_ODELAY` - Delay open until `syslog()` is called. - * `LOG_NOWAIT` - Do not wait for child processes that may have been created during the course of logging the message. This option should be used -by processes that enable notification of child termination using `SIGCHLD`, since `syslog()` may otherwise block waiting for a -child whose exit status has already been collected. +* `LOG_NOWAIT` - Do not wait for child processes that may have been created during the course of logging the message. + This option should be used by processes that enable notification of child termination using `SIGCHLD`, since `syslog()` + may otherwise block waiting for a child whose exit status has already been collected. The _facility_ argument encodes a default facility to be assigned to all messages that do not have an explicit facility already encoded. The initial default facility is `LOG_USER`. @@ -97,21 +102,18 @@ prior to calling `syslog()`. The `closelog()` function shall close any open file descriptors allocated by previous calls to `openlog()` or `syslog()`. -The `setlogmask()` function shall set the log priority mask for the current process to _maskpri_ and return the -previous mask. If the _maskpri_ argument is 0, the current log mask is not modified. Calls by the current process to -`syslog()` with a priority not set in _maskpri_ shall be rejected. The default log mask allows all priorities to be -logged. A call to `openlog()` is not required prior to calling `setlogmask()`. - -Symbolic constants for use as values of the _logopt_, _facility_, _priority_, and _maskpri_ arguments are -defined in the `` header. +The `setlogmask()` function shall set the log priority mask for the current process to _maskpri_ and return the previous +mask. If the _maskpri_ argument is 0, the current log mask is not modified. Calls by the current process to `syslog()` +with a priority not set in _maskpri_ shall be rejected. The default log mask allows all priorities to be logged. A call +to `openlog()` is not required prior to calling `setlogmask()`. +Symbolic constants for use as values of the _logopt_, _facility_, _priority_, and _maskpri_ arguments are defined in the +`` header. ## Return value - -The `setlogmask()` function shall return the previous log _priority_ mask. The `closelog()`, `openlog()`, and -`syslog()` functions shall not return a value. - +The `setlogmask()` function shall return the previous log _priority_ mask. The `closelog()`, `openlog()`, and `syslog()` +functions shall not return a value. ## Errors @@ -125,6 +127,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/p/pclose.part-impl.md b/libc/functions/p/pclose.part-impl.md index f07dd99a..7b09a3e6 100644 --- a/libc/functions/p/pclose.part-impl.md +++ b/libc/functions/p/pclose.part-impl.md @@ -1,15 +1,23 @@ -# Synopsis -`#include `
+# Synopsis -`int pclose(FILE *stream);`
+`#include ` + +`int pclose(FILE *stream);` ## Status + Implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description -The `pclose()` function shall close a stream that was opened by `popen()`, wait for the command to terminate, and return the termination status of the process that was running the command language interpreter. However, if a call caused the termination status to be unavailable to `pclose()`, then `pclose()` shall return `-1` with `errno` set to `ECHILD` to report this situation. This can happen if the application calls one of the following functions: +The `pclose()` function shall close a stream that was opened by `popen()`, wait for the command to terminate, and return +the termination status of the process that was running the command language interpreter. However, if a call caused the +termination status to be unavailable to `pclose()`, then `pclose()` shall return `-1` with `errno` set to `ECHILD` to +report this situation. This can happen if the application calls one of the following functions: * `wait()` @@ -19,28 +27,27 @@ The `pclose()` function shall close a stream that was opened by `popen()`, wait In any case, `pclose()` shall not return before the child process created by `popen()` has terminated. -If the command language interpreter cannot be executed, the child termination status returned by `pclose()` shall be as if the command language interpreter terminated using `exit(127)` or `_exit(127)`. +If the command language interpreter cannot be executed, the child termination status returned by `pclose()` shall be as +if the command language interpreter terminated using `exit(127)` or `_exit(127)`. -The `pclose()` function shall not affect the termination status of any child of the calling process other than the one created by `popen()` for the associated stream. +The `pclose()` function shall not affect the termination status of any child of the calling process other than the one +created by `popen()` for the associated stream. -If the argument _stream_ to `pclose()` is not a pointer to a stream created by `popen()`, the result of `pclose()` is undefined. +If the argument _stream_ to `pclose()` is not a pointer to a stream created by `popen()`, the result of `pclose()` is +undefined. If a thread is canceled during execution of `pclose()`, the behavior is undefined. - ## Return value - -Upon successful return, `pclose()` shall return the termination status of the command language interpreter. Otherwise, `pclose()` shall return `-1` and set `errno` to indicate the error. - +Upon successful return, `pclose()` shall return the termination status of the command language interpreter. Otherwise, +`pclose()` shall return `-1` and set `errno` to indicate the error. ## Errors - The `pclose()` function shall fail if: - * `ECHILD` - The status of the child process could not be obtained, as described above. - +* `ECHILD` - The status of the child process could not be obtained, as described above. ## Tests @@ -50,6 +57,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/p/perror.part-impl.md b/libc/functions/p/perror.part-impl.md index 88d47517..d078f616 100644 --- a/libc/functions/p/perror.part-impl.md +++ b/libc/functions/p/perror.part-impl.md @@ -1,53 +1,48 @@ -# Synopsis -`#include `
+# Synopsis -` void perror(const char *s);`
+`#include ` + +`void perror(const char *s);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description The `perror()` function shall map the error number accessed through the symbol `errno` to a language-dependent error message, which shall be written to the standard error stream as follows: - - -* First (if _s_ is not a `null` pointer and the character pointed to by _s_ is not the `null` byte), the string pointed to by _s_ followed by a `` and a ``. +* First (if _s_ is not a `null` pointer and the character pointed to by _s_ is not the `null` byte), the string pointed +to by _s_ followed by a `` and a ``. * Then an error message string followed by a ``. - The contents of the error message strings shall be the same as those returned by `strerror()` with argument `errno`. The `perror()` function shall mark for update the last data modification and last file status change timestamps of the file -associated with the standard error stream at some time between its successful completion and `exit()`, `abort()`, or the completion of `fflush()` or `fclose()` on stderr. +associated with the standard error stream at some time between its successful completion and `exit()`, `abort()`, or the +completion of `fflush()` or `fclose()` on stderr. The `perror()` function shall not change the orientation of the standard error stream. -On error, `perror()` shall set the error indicator for the stream to which stderr points, and shall set `errno` -to indicate the error. - -Since no value is returned, an application wishing to check for error situations should call `clearerr(stderr)` -before calling `perror()`, then if `ferror(stderr)` returns non-zero, the value of `errno` indicates which -error occurred. +On error, `perror()` shall set the error indicator for the stream to which stderr points, and shall set `errno` to +indicate the error. +Since no value is returned, an application wishing to check for error situations should call `clearerr(stderr)` before +calling `perror()`, then if `ferror(stderr)` returns non-zero, the value of `errno` indicates which error occurred. ## Return value - The `perror()` function shall not return a value. - ## Errors - - -Refer to `fputc()`. - - - +Refer to `fputc()` ## Tests @@ -57,6 +52,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/p/pipe.part-impl.md b/libc/functions/p/pipe.part-impl.md index 6ffb38c0..36e2caac 100644 --- a/libc/functions/p/pipe.part-impl.md +++ b/libc/functions/p/pipe.part-impl.md @@ -1,27 +1,31 @@ -# Synopsis -`#include `
+# Synopsis -`int pipe(int fildes[2]);`
+`#include ` + +`int pipe(int fildes[2]);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `pipe()` function shall create a pipe and place two file descriptors, one each into the arguments _fildes[0]_ and -_fildes[1]_, that refer to the open file descriptions for the read and write ends of the pipe. The file descriptors shall be -allocated as described in File Descriptor Allocation. The `O_NONBLOCK` -and `FD_CLOEXEC` flags shall be clear on both file descriptors. (The `fcntl()` function can be used to set both these flags.) +_fildes[1]_, that refer to the open file descriptions for the read and write ends of the pipe. The file descriptors +shall be allocated as described in File Descriptor Allocation. The `O_NONBLOCK` and `FD_CLOEXEC` flags shall be clear +on both file descriptors. (The `fcntl()` function can be used to set both these flags.) -Data can be written to the file descriptor _fildes[1]_ and read from the file descriptor _fildes[0]_. A read on the -file descriptor _fildes[0]_ shall access data written to the file descriptor _fildes[1]_ on a first-in-first-out basis. +Data can be written to the file descriptor _fildes[1]_ and read from the file descriptor _fildes[0]_. A read on the file +descriptor _fildes[0]_ shall access data written to the file descriptor _fildes[1]_ on a first-in-first-out basis. It is unspecified whether _fildes[0]_ is also open for writing and whether _fildes[1]_ is also open for reading. -A process has the pipe open for reading (correspondingly writing) if it has a file descriptor open that refers to the read end, -_fildes[0]_ (write end, _fildes[1]_). +A process has the pipe open for reading (correspondingly writing) if it has a file descriptor open that refers to the +read end, _fildes[0]_ (write end, _fildes[1]_). The pipe's user ID shall be set to the effective user ID of the calling process. @@ -30,26 +34,17 @@ The pipe's group ID shall be set to the effective group ID of the calling proces Upon successful completion, `pipe()` shall mark for update the last data access, last data modification, and last file status change timestamps of the pipe. - ## Return value - -Upon successful completion, `0` shall be returned; otherwise, `-1` shall be returned and `errno` set to indicate the error, no -file descriptors shall be allocated and the contents of fildes shall be left unmodified. - +Upon successful completion, `0` shall be returned; otherwise, `-1` shall be returned and `errno` set to indicate the +error, no file descriptors shall be allocated and the contents of fildes shall be left unmodified. ## Errors - The `pipe()` function shall fail if: - - * `EMFILE` - All, or all but one, of the file descriptors available to the process are currently open. - - * `ENFILE` - The number of simultaneously open files in the system would exceed a system-imposed limit. - - - +* `EMFILE` - All, or all but one, of the file descriptors available to the process are currently open. +* `ENFILE` - The number of simultaneously open files in the system would exceed a system-imposed limit. ## Tests @@ -59,6 +54,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/p/popen.part-impl.md b/libc/functions/p/popen.part-impl.md index ba3019a6..94d64f6d 100644 --- a/libc/functions/p/popen.part-impl.md +++ b/libc/functions/p/popen.part-impl.md @@ -1,59 +1,68 @@ -# Synopsis -`#include `
+# Synopsis -`FILE *popen(const char *command, const char *mode);`
+`#include ` + +`FILE *popen(const char *command, const char *mode);` ## Status + Implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description -The `popen()` function shall execute the command specified by the string _command_. It shall create a pipe between the calling program and the executed command, and shall return a pointer to a stream that can be used to either read from or write to the pipe. +The `popen()` function shall execute the command specified by the string _command_. It shall create a pipe between the +calling program and the executed command, and shall return a pointer to a stream that can be used to either read from or +write to the pipe. -The environment of the executed command shall be as if a child process were created within the `popen()` call using the `fork()` function, and the child invoked the `sh` utility using the call: +The environment of the executed command shall be as if a child process were created within the `popen()` call using the +`fork()` function, and the child invoked the `sh` utility using the call: `execl(shell path, "sh", "-c", command, (char *)0);` where shell path is an unspecified pathname for the `sh` utility. -The `popen()` function shall ensure that any streams from previous `popen()` calls that remain open in the parent process are closed in the new child process. +The `popen()` function shall ensure that any streams from previous `popen()` calls that remain open in the parent +process are closed in the new child process. The _mode_ argument to `popen()` is a string that specifies `I/O` mode: - * If _mode_ is `r`, when the child process is started, its file descriptor `STDOUT_FILENO` shall be the writable end of the pipe, and the file descriptor `fileno(stream)` in the calling process, where stream is the stream pointer returned by `popen()`, shall be the readable end of the pipe. +* If _mode_ is `r`, when the child process is started, its file descriptor `STDOUT_FILENO` shall be the writable end of + the pipe, and the file descriptor `fileno(stream)` in the calling process, where stream is the stream pointer returned + by `popen()`, shall be the readable end of the pipe. - * If _mode_ is `w`, when the child process is started its file descriptor `STDIN_FILENO` shall be the readable end of the pipe, and the file descriptor `fileno(stream)` in the calling process, where stream is the stream pointer returned by `popen()`, shall be the writable end of the pipe. +* If _mode_ is `w`, when the child process is started its file descriptor `STDIN_FILENO` shall be the readable end of + the pipe, and the file descriptor `fileno(stream)` in the calling process, where stream is the stream pointer returned + by `popen()`, shall be the writable end of the pipe. - * If _mode_ is any other value, the result is unspecified. +* If _mode_ is any other value, the result is unspecified. -After `popen()`, both the parent and the child process shall be capable of executing independently before either terminates. +After `popen()`, both the parent and the child process shall be capable of executing independently before either +terminates. Pipe streams are byte-oriented. - ## Return value - -Upon successful completion, `popen()` shall return a pointer to an open stream that can be used to read or write to the pipe. Otherwise, it shall return a null pointer and may set `errno` to indicate the error. - +Upon successful completion, `popen()` shall return a pointer to an open stream that can be used to read or write to the +pipe. Otherwise, it shall return a null pointer and may set `errno` to indicate the error. ## Errors - The `popen()` function shall fail if: - * `EMFILE` - `{STREAM_MAX}` streams are currently open in the calling process. +* `EMFILE` - `{STREAM_MAX}` streams are currently open in the calling process. The popen() function may fail if: - * `EMFILE` - `{FOPEN_MAX}` streams are currently open in the calling process. - - * `EINVAL` - The mode argument is invalid. +* `EMFILE` - `{FOPEN_MAX}` streams are currently open in the calling process. +* `EINVAL` - The mode argument is invalid. The `popen()` function may also set `errno` values as described by `fork` or `pipe`. - ## Tests Untested @@ -62,6 +71,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/p/pow.part-impl.md b/libc/functions/p/pow.part-impl.md index 22242ab0..1e98e91a 100644 --- a/libc/functions/p/pow.part-impl.md +++ b/libc/functions/p/pow.part-impl.md @@ -1,120 +1,104 @@ -# Synopsis -`#include `
+# Synopsis -` double pow(double x, double y);`
+`#include ` -` float powf(float x, float y);`
+`double pow(double x, double y);` -` long double powl(long double x, long double y);`
+`float powf(float x, float y);` + +`long double powl(long double x, long double y);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -These functions shall compute the value of `x` raised to the power `y`. If -`x` is negative, the application shall ensure that `y` is an integer value. +These functions shall compute the value of `x` raised to the power `y`. If `x` is negative, the application shall ensure +that `y` is an integer value. -An application wishing to check for error situations should set `errno` to zero and call -`feclearexcept(FE_ALL_EXCEPT)` before calling these functions. On return, if `errno` is non-zero or +An application wishing to check for error situations should set `errno` to zero and call `feclearexcept(FE_ALL_EXCEPT)` +before calling these functions. On return, if `errno` is non-zero or `fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)` is non-zero, an error has occurred. - ## Return value - Upon successful completion, these functions shall return the value of _x_ raised to the power _y_. For finite values of `x < 0`, and finite non-integer values of `y`, a domain error shall occur and  either a `NaN` -(if representable), or an implementation-defined value shall be -returned. +(if representable), or an implementation-defined value shall be returned. -If the correct value would cause overflow, a range error shall occur and `pow()`, `powf()`, and `powl()` shall -return `±HUGE_VAL`, `±HUGE_VALF`, and `±HUGE_VALL`, respectively, with the same sign as the correct value of the -function. +If the correct value would cause overflow, a range error shall occur and `pow()`, `powf()`, and `powl()` shall return +`±HUGE_VAL`, `±HUGE_VALF`, and `±HUGE_VALL`, respectively, with the same sign as the correct value of the function. -If the correct value would cause underflow,  and is not representable,  a range error may occur, and `pow()`, `powf()`, and `powl()` shall return  `0.0`, or -(if IEC 60559 Floating-Point is not supported) an +If the correct value would cause underflow,  and is not representable,  a range error may occur, and `pow()`, +`powf()`, and `powl()` shall return  `0.0`, or (if IEC 60559 Floating-Point is not supported) an implementation-defined value no greater in magnitude than `DBL_MIN`, `FLT_MIN`, and `LDBL_MIN`, respectively. -For `y < 0`, if _x_ is zero, a  pole  error may occur and `pow()`, `powf()`, and `powl()` shall return `±HUGE_VAL`, `±HUGE_VALF`, and -`±HUGE_VALL`, respectively.  On systems that support the IEC 60559 Floating-Point option, if _x_ is `±0`, a pole -error shall occur and `pow()`, `powf()`, and `powl()` shall return `±HUGE_VAL`, `±HUGE_VALF`, and -`±HUGE_VALL`, respectively if _y_ is an odd integer, or `HUGE_VAL`, `HUGE_VALF`, and `HUGE_VALL`, respectively if _y_ is -not an odd integer. +For `y < 0`, if _x_ is zero, a  pole  error may occur and `pow()`, `powf()`, and `powl()` shall return `±HUGE_VAL`, +`±HUGE_VALF`, and `±HUGE_VALL`, respectively.  On systems that support the IEC 60559 Floating-Point option, if _x_ is +`±0`, a pole error shall occur and `pow()`, `powf()`, and `powl()` shall return `±HUGE_VAL`, `±HUGE_VALF`, and +`±HUGE_VALL`, respectively if _y_ is an odd integer, or `HUGE_VAL`, `HUGE_VALF`, and `HUGE_VALL`, respectively if _y_ +is not an odd integer. -If_x_ or _y_ is a `NaN`, a `NaN` shall be returned (unless specified elsewhere in this description). +If_x_or_y_ is a `NaN`, a `NaN` shall be returned (unless specified elsewhere in this description). -For any value of _y_ (including `NaN`), if _x_ is `+1`, `1.0` shall be returned. - -For any value of _x_ (including `NaN`), if _y_ is `±0`, `1.0` shall be returned. - -For any odd integer value of `y > 0`, if _x_ is `±0`, `±0` shall be returned. - -For `y > 0` and not an odd integer, if_ x_ is `±0`, `+0` shall be returned. +* For any value of _y_ (including `NaN`), if _x_ is `+1`, `1.0` shall be returned. +* For any value of _x_ (including `NaN`), if _y_ is `±0`, `1.0` shall be returned. +* For any odd integer value of `y > 0`, if _x_ is `±0`, `±0` shall be returned. +* For `y > 0` and not an odd integer, if_x_ is `±0`, `+0` shall be returned. If x is `-1`, and _y_ is `±Inf`, `1.0` shall be returned. -For `|x| < 1`, if _y_ is `-Inf`, `+Inf` shall be returned. - -For `|x| > 1`, if _y_ is `-Inf`, `+0` shall be returned. - -For `|x| < 1`, if _y_ is `+Inf`, `+0` shall be returned. - -For `|x| > 1`, if _y_ is `+Inf`, `+Inf` shall be returned. - -For _y_ an odd integer `< 0`, if _x_ is `-Inf`, `-0` shall be returned. - -For `y < 0` and not an odd integer, if _x_ is `-Inf`, `+0` shall be returned. - -For _y_ an odd integer `> 0`, if _x_ is `-Inf`, `-Inf` shall be returned. - -For `y > 0` and not an odd integer, if _x_ is `-Inf`, `+Inf` shall be returned. - -For `y < 0`, if _x_ is `+Inf`, `+0` shall be returned. - -For `y > 0`, if _x_ is `+Inf`, `+Inf` shall be returned. - -If the correct value would cause underflow, and is representable, a range error may occur and the correct value shall be returned. - +* For `|x| < 1`, if _y_ is `-Inf`, `+Inf` shall be returned. +* For `|x| > 1`, if _y_ is `-Inf`, `+0` shall be returned. +* For `|x| < 1`, if _y_ is `+Inf`, `+0` shall be returned. +* For `|x| > 1`, if _y_ is `+Inf`, `+Inf` shall be returned. +* For _y_ an odd integer `< 0`, if _x_ is `-Inf`, `-0` shall be returned. +* For `y < 0` and not an odd integer, if _x_ is `-Inf`, `+0` shall be returned. +* For _y_ an odd integer `> 0`, if _x_ is `-Inf`, `-Inf` shall be returned. +* For `y > 0` and not an odd integer, if _x_ is `-Inf`, `+Inf` shall be returned. +* For `y < 0`, if _x_ is `+Inf`, `+0` shall be returned. +* For `y > 0`, if _x_ is `+Inf`, `+Inf` shall be returned. +If the correct value would cause underflow, and is representable, a range error may occur and the correct value shall +be returned. ## Errors - These functions shall fail if: - * `Domain Error` - The value of _x_ is negative and _y_ is a finite non-integer.
+* `Domain Error` - The value of _x_ is negative and _y_ is a finite non-integer. If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `EDOM`. If -the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the invalid floating-point exception shall -be raised. +the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the invalid floating-point exception +shall be raised. - * `Pole Error` - The value of _x_ is zero and _y_ is negative.
+* `Pole Error` - The value of _x_ is zero and _y_ is negative. If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If -the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the divide-by-zero floating-point exception -shall be raised. +the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the divide-by-zero floating-point +exception shall be raised. - * `Range Error` - The result overflows.
+* `Range Error` - The result overflows. If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If -the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the overflow floating-point exception shall -be raised. - +the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the overflow floating-point exception +shall be raised. These functions may fail if: - * `Pole Error` - The value of _x_ is zero and _y_ is negative.
+* `Pole Error` - The value of _x_ is zero and _y_ is negative. If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If -the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the divide-by-zero floating-point exception -shall be raised. +the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the divide-by-zero floating-point +exception shall be raised. - * `Range Error` - The result underflows.
+* `Range Error` - The result underflows. If the integer expression `(math_errhandling & MATH_ERRNO)` is non-zero, then `errno` shall be set to `ERANGE`. If the integer expression `(math_errhandling & MATH_ERREXCEPT)` is non-zero, then the underflow floating-point exception shall be raised. - ## Tests Untested @@ -123,6 +107,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/p/printf.part-impl.md b/libc/functions/p/printf.part-impl.md index 51bc0a0e..dacfb214 100644 --- a/libc/functions/p/printf.part-impl.md +++ b/libc/functions/p/printf.part-impl.md @@ -1,222 +1,368 @@ -# Synopsis -`#include `
+# Synopsis -`int dprintf(int _fildes_, const char *restrict format, ...); `
+`#include ` -`int fprintf(FILE *restrict stream, const char *restrict format, ...);`
+`int dprintf(int _fildes_, const char *restrict format, ...);` -`int printf(const char *restrict format, ...);`
+`int fprintf(FILE *restrict stream, const char *restrict format, ...);` -`int snprintf(char *restrict s, size_t n,`
+`int printf(const char *restrict format, ...);` -`const char *restrict format, ...);`
+`int snprintf(char *restrict s, size_t n,` -`int sprintf(char *restrict s, const char *restrict format, ...);`
+`const char *restrict format, ...);` -## Status -Partially implemented -## Conformance -IEEE Std 1003.1-2017 -## Description - -The `fprintf()` function shall place output on the named output stream. The `printf()` function shall place output on the standard output stream stdout. The `sprintf()` function shall place output followed by the null byte, `\0`, in consecutive bytes starting at *s; it is the user's responsibility to ensure that enough space is available. - - The `dprintf()` function shall be equivalent to the `fprintf()` function, except that `dprintf()` shall write output to the file associated with the file descriptor specified by the _fildes_ argument rather than place output on a stream. - -The `snprintf()` function shall be equivalent to `sprintf()`, with the addition of the `n` argument which states the size of the buffer referred to by s. If `n` is zero, nothing shall be written and `s` may be a null pointer. Otherwise, output bytes beyond the `n-1st` shall be discarded instead of being written to the array, and a `null` byte is written at the end of the bytes actually written into the array. - -If copying takes place between objects that overlap as a result of a call to `sprintf()` or `snprintf()`, the results are undefined. - -Each of these functions converts, formats, and prints its arguments under control of the _format_. The _format_ is a character string, beginning and ending in its initial shift state, if any. The _format_ is composed of zero or more directives: ordinary characters, which are simply copied to the output stream, and conversion specifications, each of which shall result in the fetching of zero or more arguments. The results are undefined if there are insufficient arguments for the _format_. If the _format_ is exhausted while arguments remain, the excess arguments shall be evaluated but are otherwise ignored. - - Conversions can be applied to the `nth` argument after the _format_ in the argument list, rather than to the next unused argument. In this case, the conversion specifier character `%` (see below) is replaced by the sequence `%n$`, where `n` is a decimal integer in the range `[1,NL_ARGMA]`, giving the position of the argument in the argument list. This feature provides for the definition of format strings that select arguments in an order appropriate to specific languages. - -The format can contain either numbered argument conversion specifications (that is, `%n$` and `*m$`), or unnumbered argument conversion specifications (that is, `%` and `*` ), but not both. The only exception to this is that `%%` can be mixed with the `%n$` form. The results of mixing numbered and unnumbered argument specifications in a format string are undefined. When numbered argument specifications are used, specifying the `Nth` argument requires that all the leading arguments, from the first to the `(N-1)th`, are specified in the format string. +`int sprintf(char *restrict s, const char *restrict format, ...);` -In format strings containing the `%n$` form of conversion specification, numbered arguments in the argument list can be referenced from the format string as many times as required. - -In format strings containing the `%` form of conversion specification, each conversion specification uses the first unused argument in the argument list. +## Status - All forms of the `fprintf()` functions allow for the insertion of a language-dependent `radix` character in the output string. The `radix` character is defined in the current locale (category `LC_NUMERIC)`. In the POSIX locale, or in a locale where the `radix` character is not defined, the `radix` character shall default to a `` ( `.` ). +Partially implemented -Each conversion specification is introduced by the `%` character or by the character sequence `%n$`, after which the following appear in sequence: +## Conformance - * Zero or more flags (in any order), which modify the meaning of the conversion specification. +IEEE Std 1003.1-2017 - * An optional minimum field width. If the converted value has fewer bytes than the field width, it shall be padded with `` characters by default on the left; it shall be padded on the right if the left-adjustment flag ( `-` ), described below, is given to the field width. The field width takes the form of an `` ( `*` ), described below, or a decimal integer. +## Description -An optional precision that gives the minimum number of digits to appear for the `d`, `i`, `o`, `u`, `x`, and `X` conversion specifiers; the number of digits to appear after the `radix` character for the `a`, `A`, `e`, `E`, `f`, and `F` conversion specifiers; the maximum number of significant digits for the `g` and `G` conversion specifiers; or the maximum number of bytes to be printed from a string in the `s` and `S` conversion specifiers. The precision takes the form of a `` ( `.` ) followed either by an `` ( `*` ), described below, or an optional decimal digit string, where a `null` digit string is treated as zero. If a precision appears with any other conversion specifier, the behavior is undefined. +The `fprintf()` function shall place output on the named output stream. The `printf()` function shall place output on +the standard output stream stdout. The `sprintf()` function shall place output followed by the null byte, `\0`, in +consecutive bytes starting at *s; it is the user's responsibility to ensure that enough space is available. + + The `dprintf()` function shall be equivalent to the `fprintf()` function, except that `dprintf()` shall write output + to the file associated with the file descriptor specified by the _fildes_ argument rather than place output on a + stream. + +The `snprintf()` function shall be equivalent to `sprintf()`, with the addition of the `n` argument which states the +size of the buffer referred to by s. If `n` is zero, nothing shall be written and `s` may be a null pointer. Otherwise, +output bytes beyond the `n-1st` shall be discarded instead of being written to the array, and a `null` byte is written +at the end of the bytes actually written into the array. + +If copying takes place between objects that overlap as a result of a call to `sprintf()` or `snprintf()`, the results +are undefined. + +Each of these functions converts, formats, and prints its arguments under control of the _format_. The _format_ is a +character string, beginning and ending in its initial shift state, if any. The _format_ is composed of zero or more +directives: ordinary characters, which are simply copied to the output stream, and conversion specifications, each of +which shall result in the fetching of zero or more arguments. The results are undefined if there are insufficient +arguments for the _format_. If the _format_ is exhausted while arguments remain, the excess arguments shall be evaluated +but are otherwise ignored. + + Conversions can be applied to the `nth` argument after the _format_ in the argument list, rather than to the next + unused argument. In this case, the conversion specifier character `%` (see below) is replaced by the sequence `%n$`, + where `n` is a decimal integer in the range `[1,NL_ARGMA]`, giving the position of the argument in the argument list. + This feature provides for the definition of format strings that select arguments in an order appropriate to specific + languages. + +The format can contain either numbered argument conversion specifications (that is, `%n$` and `*m$`), or unnumbered +argument conversion specifications (that is, `%` and `*` ), but not both. The only exception to this is that `%%` can +be mixed with the `%n$` form. The results of mixing numbered and unnumbered argument specifications in a format string +are undefined. When numbered argument specifications are used, specifying the `Nth` argument requires that all the +leading arguments, from the first to the `(N-1)th`, are specified in the format string. + +In format strings containing the `%n$` form of conversion specification, numbered arguments in the argument list can be +referenced from the format string as many times as required. + +In format strings containing the `%` form of conversion specification, each conversion specification uses the first +unused argument in the argument list. + + All forms of the `fprintf()` functions allow for the insertion of a language-dependent `radix` character in the output + string. The `radix` character is defined in the current locale (category `LC_NUMERIC)`. In the POSIX locale, or in a + locale where the `radix` character is not defined, the `radix` character shall default to a `` ( `.` ). + +Each conversion specification is introduced by the `%` character or by the character sequence `%n$`, after which +the following appear in sequence: + +* Zero or more flags (in any order), which modify the meaning of the conversion specification. + +* An optional minimum field width. If the converted value has fewer bytes than the field width, it shall be padded with + `` characters by default on the left; it shall be padded on the right if the left-adjustment flag ( `-` ), + described below, is given to the field width. The field width takes the form of an `` ( `*` ), described + below, or a decimal integer. + +An optional precision that gives the minimum number of digits to appear for the `d`, `i`, `o`, `u`, `x`, and `X` +conversion specifiers; the number of digits to appear after the `radix` character for the `a`, `A`, `e`, `E`, `f`, and +`F` conversion specifiers; the maximum number of significant digits for the `g` and `G` conversion specifiers; or the +maximum number of bytes to be printed from a string in the `s` and `S` conversion specifiers. The precision takes +the form of a `` ( `.` ) followed either by an `` ( `*` ), described below, or an optional decimal +digit string, where a `null` digit string is treated as zero. If a precision appears with any other conversion +specifier, the behavior is undefined. An optional length modifier that specifies the size of the argument. A conversion specifier character that indicates the type of conversion to be applied. -A field width, or precision, or both, may be indicated by an `` ( `*` ). In this case an argument of type int supplies the field width or precision. Applications shall ensure that arguments specifying field width, or precision, or both appear in that order before the argument, if any, to be converted. A negative field width is taken as a `-` flag followed by a positive field width. A negative precision is taken as if the precision were omitted. In format strings containing the `%n$` form of a conversion specification, a field width or precision may be indicated by the sequence `*m$`, where `m` is a decimal integer in the range `[1,NL_ARGMA]` giving the position in the argument list (after the format argument) of an integer argument containing the field width or precision, for example: +A field width, or precision, or both, may be indicated by an `` ( `*` ). In this case an argument of type int +supplies the field width or precision. Applications shall ensure that arguments specifying field width, or precision, +or both appear in that order before the argument, if any, to be converted. A negative field width is taken as a `-` +flag followed by a positive field width. A negative precision is taken as if the precision were omitted. In format +strings containing the `%n$` form of a conversion specification, a field width or precision may be indicated by the +sequence `*m$`, where `m` is a decimal integer in the range `[1,NL_ARGMA]` giving the position in the argument list +(after the format argument) of an integer argument containing the field width or precision, for example: `printf("%1$d:%2$.*3$d:%4$.*3$d\n", hour, min, precision, sec);` The flag characters and their meanings are: - * __`'`__ \(The ``\) -The integer portion of the result of a decimal conversion ( `%i`, `%d`, `%u`, `%f`, `%F`, `%g`, or `%G` ) shall be formatted with thousands' grouping characters. For other conversions the behavior is undefined. The non-monetary grouping character is used. - - * __`-`__ - -The result of the conversion shall be left-justified within the field. The conversion is right-justified if this flag is not specified. - - * __`+`__ - -The result of a signed conversion shall always begin with a sign ( `+` or `-` ). The conversion shall begin with a sign only when a negative value is converted if this flag is not specified. - - * __``__ -If the first character of a signed conversion is not a sign or if a signed conversion results in no characters, a `` shall be prefixed to the result. This means that if the `` and `+` flags both appear, the flag shall be ignored. - - * __`#`__ -Specifies that the value is to be converted to an alternative form. For `o` conversion, it shall increase the precision, if and only if necessary, to force the first digit of the result to be a zero (if the value and precision are both `0`, a single `0` is printed). For `x` or `X` conversion specifiers, a non-zero result shall have `0x` (or `0X`) prefixed to it. For `a`, `A`, `e`, `E`, `f`, `F`, `g`, and `G` conversion specifiers, the result shall always contain a `radix` character, even if no digits follow the `radix` character. Without this flag, a `radix` character appears in the result of these conversions only if a digit follows it. For `g` and `G` conversion specifiers, trailing zeros shall not be removed from the result as they normally are. For other conversion specifiers, the behavior is undefined. - - * __`0`__ -For `d`, `i`, `o`, `u`, `x`, `X`, `a`, `A`, `e`, `E`, `f`, `F`, `g`, and `G` conversion specifiers, leading zeros (following any indication of sign or base) are used to pad to the field width rather than performing space padding, except when converting an infinity or `NaN`. If the `0` and `-` flags both appear, the `0` flag is ignored. For `d`, `i`, `o`, `u`, `x`, and `X` conversion specifiers, if a precision is specified, the `0` flag shall be ignored. If the `0` and `` flags both appear, the grouping characters are inserted before zero padding. For other conversions, the behavior is undefined. +* __`'`__ \(The ``\) +The integer portion of the result of a decimal conversion ( `%i`, `%d`, `%u`, `%f`, `%F`, `%g`, or `%G` ) shall be +formatted with thousands' grouping characters. For other conversions the behavior is undefined. The non-monetary +grouping character is used. + +* __`-`__ - +The result of the conversion shall be left-justified within the field. The conversion is right-justified if this flag is +not specified. + +* __`+`__ - +The result of a signed conversion shall always begin with a sign ( `+` or `-` ). The conversion shall begin with a sign +only when a negative value is converted if this flag is not specified. + +* __``__ +If the first character of a signed conversion is not a sign or if a signed conversion results in no characters, a +`` shall be prefixed to the result. This means that if the `` and `+` flags both appear, the `` +flag shall be ignored. + +* __`#`__ +Specifies that the value is to be converted to an alternative form. For `o` conversion, it shall increase the precision, +if and only if necessary, to force the first digit of the result to be a zero (if the value and precision are both `0`, +a single `0` is printed). For `x` or `X` conversion specifiers, a non-zero result shall have `0x` (or `0X`) prefixed to +it. For `a`, `A`, `e`, `E`, `f`, `F`, `g`, and `G` conversion specifiers, the result shall always contain a `radix` +character, even if no digits follow the `radix` character. Without this flag, a `radix` character appears in the result +of these conversions only if a digit follows it. For `g` and `G` conversion specifiers, trailing zeros shall not be +removed from the result as they normally are. For other conversion specifiers, the behavior is undefined. + +* __`0`__ +For `d`, `i`, `o`, `u`, `x`, `X`, `a`, `A`, `e`, `E`, `f`, `F`, `g`, and `G` conversion specifiers, leading zeros +(following any indication of sign or base) are used to pad to the field width rather than performing space padding, +except when converting an infinity or `NaN`. If the `0` and `-` flags both appear, the `0` flag is ignored. For `d`, +`i`, `o`, `u`, `x`, and `X` conversion specifiers, if a precision is specified, the `0` flag shall be ignored.If the `0` +and `` flags both appear, the grouping characters are inserted before zero padding. For other conversions, +the behavior is undefined. The length modifiers and their meanings are: - * `hh` - -Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a signed char or unsigned char argument (the argument will have been promoted according to the integer promotions, but its value shall be converted to signed char or unsigned char before printing); or that a following `n` conversion specifier applies to a pointer to a signed char argument. - - * `h` - -Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a short or unsigned short argument (the argument will have been promoted according to the integer promotions, but its value shall be converted to short or unsigned short before printing); or that a following `n` conversion specifier applies to a pointer to a short argument. - - * `l (ell)` - -Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a long or unsigned long argument; that a following `n` conversion specifier applies to a pointer to a long argument; that a following `c` conversion specifier applies to a `wint_t` argument; that a following `s` conversion specifier applies to a pointer to a `wchar_t` argument; or has no effect on a following `a`, `A`, `e`, `E`, `f`, `F`, `g`, or `G` conversion specifier. - - * `ll (ell-ell)` - -Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `long long` or `unsigned long long` argument; or that a following `n` conversion specifier applies to a pointer to a `long long` argument. - - * `j` - -Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to an `intmax_t` or `uintmax_t` argument; or that a following `n` conversion specifier applies to a pointer to an `intmax_t` argument. - - * `z` - -Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `size_t` or the corresponding signed integer type argument; or that a following `n` conversion specifier applies to a pointer to a signed integer type corresponding to a `size_t` argument. - - * `t` - -Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `ptrdiff_t` or the corresponding unsigned type argument; or that a following `n` conversion specifier applies to a pointer to a `ptrdiff_t` argument. - - * `L` - -Specifies that a following `a`, `A`, `e`, `E`, `f`, `F`, `g`, or `G` conversion specifier applies to a long double argument. +* `hh` - +Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a signed char or unsigned +char argument (the argument will have been promoted according to the integer promotions, but its value shall be +converted to signed char or unsigned char before printing); or that a following `n` conversion specifier applies +to a pointer to a signed char argument. + +* `h` - +Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a short or unsigned short +argument (the argument will have been promoted according to the integer promotions, but its value shall be converted +to short or unsigned short before printing); or that a following `n` conversion specifier applies to a pointer to a +short argument. + +* `l (ell)` - +Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a long or unsigned long +argument; that a following `n` conversion specifier applies to a pointer to a long argument; that a following `c` +conversion specifier applies to a `wint_t` argument; that a following `s` conversion specifier applies to a pointer +to a `wchar_t` argument; or has no effect on a following `a`, `A`, `e`, `E`, `f`, `F`, `g`, or `G` conversion specifier. + +* `ll (ell-ell)` - +Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `long long` or `unsigned +long long` argument; or that a following `n` conversion specifier applies to a pointer to a `long long` argument. + +* `j` - +Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to an `intmax_t` or `uintmax_t` +argument; or that a following `n` conversion specifier applies to a pointer to an `intmax_t` argument. + +* `z` - +Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `size_t` or the +corresponding signed integer type argument; or that a following `n` conversion specifier applies to a pointer to a +signed integer type corresponding to a `size_t` argument. + +* `t` - +Specifies that a following `d`, `i`, `o`, `u`, `x`, or `X` conversion specifier applies to a `ptrdiff_t` or the +corresponding unsigned type argument; or that a following `n` conversion specifier applies to a pointer to a +`ptrdiff_t` argument. + +* `L` - +Specifies that a following `a`, `A`, `e`, `E`, `f`, `F`, `g`, or `G` conversion specifier applies to a long double +argument. If a length modifier appears with any conversion specifier other than as specified above, the behavior is undefined. The conversion specifiers and their meanings are: - * `d`, `i` - -The int argument shall be converted to a signed decimal in the style `[-]dddd`. The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it shall be expanded with leading zeros. The default precision is `1`. The result of converting zero with an explicit precision of zero shall be no characters. - - * `o` - -The unsigned argument shall be converted to unsigned octal format in the style `dddd`. The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it shall be expanded with leading zeros. The default precision is `1`. The result of converting zero with an explicit precision of zero shall be no characters. - - * `u` - -The unsigned argument shall be converted to unsigned decimal format in the style `dddd`. The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it shall be expanded with leading zeros. The default precision is `1`. The result of converting zero with an explicit precision of zero shall be no characters. - - * `x` - -The unsigned argument shall be converted to unsigned hexadecimal format in the style `dddd`; the letters `abcdef` are used. The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it shall be expanded with leading zeros. The default precision is `1`. The result of converting zero with an explicit precision of zero shall be no characters. - - * `X` - +* `d`, `i` - +The int argument shall be converted to a signed decimal in the style `[-]dddd`. The precision specifies the minimum +number of digits to appear; if the value being converted can be represented in fewer digits, it shall be expanded with +leading zeros. The default precision is `1`. The result of converting zero with an explicit precision of zero shall be +no characters. + +* `o` - +The unsigned argument shall be converted to unsigned octal format in the style `dddd`. The precision specifies the +minimum number of digits to appear; if the value being converted can be represented in fewer digits, it shall be +expanded with leading zeros. The default precision is `1`. The result of converting zero with an explicit precision +of zero shall be no characters. + +* `u` - +The unsigned argument shall be converted to unsigned decimal format in the style `dddd`. The precision specifies the +minimum number of digits to appear; if the value being converted can be represented in fewer digits, it shall be +expanded with leading zeros. The default precision is `1`. The result of converting zero with an explicit precision of +zero shall be no characters. + +* `x` - +The unsigned argument shall be converted to unsigned hexadecimal format in the style `dddd`; the letters `abcdef` are +used. The precision specifies the minimum number of digits to appear; if the value being converted can be represented +in fewer digits, it shall be expanded with leading zeros. The default precision is `1`. The result of converting zero +with an explicit precision of zero shall be no characters. + +* `X` - Equivalent to the x conversion specifier, except that letters `ABCDEF` are used instead of `abcdef` . - * `f`, `F` - -The double argument shall be converted to decimal notation in the style `[-]ddd.ddd`, where the number of digits after the `radix` character is equal to the precision specification. If the precision is missing, it shall be taken as `6`; if the precision is explicitly zero and no `#` flag is present, no `radix` character shall appear. If a `radix` character appears, at least one digit appears before it. The low-order digit shall be rounded in an implementation-defined manner.

-A double argument representing an infinity shall be converted in one of the styles `[-]inf` or `[-]infinity`; which style is implementation-defined. A double argument representing a NaN shall be converted in one of the styles `[-]nan(n-char-sequence)` or `[-]nan`; which style, and the meaning of any n-char-sequence, is implementation-defined. The `F` conversion specifier produces `INF`, `INFINITY`, or `NAN` instead of `inf`, `infinity`, or `nan`, respectively. - - - * `e, E` - -The double argument shall be converted in the style `[-]d.ddde±dd`, where there is one digit before the `radix` character (which is non-zero if the argument is non-zero) and the number of digits after it is equal to the precision; if the precision is missing, it shall be taken as `6`; if the precision is zero and no '#' flag is present, no `radix` character shall appear. The low-order digit shall be rounded in an implementation-defined manner. The `E` conversion specifier shall produce a number with `E` instead of `e` introducing the exponent. The exponent shall always contain at least two digits. If the value is zero, the exponent shall be zero.

-A double argument representing an infinity or `NaN` shall be converted in the style of an `f` or `F` conversion specifier. - - * `g`, `G` -The double argument representing a floating-point number shall be converted in the style `f` or `e` (or in the style `F` or `E` in the case of a `G` conversion specifier), depending on the value converted and the precision. Let `P` equal the precision if non-zero, `6` if the precision is omitted, or `1` if the precision is zero. Then, if a conversion with style `E` would have an exponent of `X`:
-\- If `P > X>=-4`, the conversion shall be with style `f` (or `F` ) and precision `P-(X+1)`.
-\- Otherwise, the conversion shall be with style `e` (or `E` ) and precision `P-1`.

-Finally, unless the `#` flag is used, any trailing zeros shall be removed from the fractional portion of the result and the decimal-point character shall be removed if there is no fractional portion remaining.

-A double argument representing an infinity or `NaN` shall be converted in the style of an `f` or `F` conversion specifier. - - * `a`, `A` - -A double argument representing a floating-point number shall be converted in the style `[-]0xh.hhhhp±d`, where there is one hexadecimal digit (which shall be non-zero if the argument is a normalized floating-point number and is otherwise unspecified) before the decimal-point character and the number of hexadecimal digits after it is equal to the precision; if the precision is missing and `FLT_RADIX` is a power of `2`, then the precision shall be sufficient for an exact representation of the value; if the precision is missing and `FLT_RADIX` is not a power of `2`, then the precision shall be sufficient to distinguish values of type double, except that trailing zeros may be omitted; if the precision is zero and the `#` flag is not specified, no decimal-point character shall appear. The letters `abcdef` shall be used for a conversion and the letters `ABCDEF` for A conversion. The `A` conversion specifier produces a number with `X` and `P` instead of `x` and `p`. The exponent shall always contain at least one digit, and only as many more digits as necessary to represent the decimal exponent of `2`. If the value is zero, the exponent shall be zero.

+* `f`, `F` - +The double argument shall be converted to decimal notation in the style `[-]ddd.ddd`, where the number of digits after +the `radix` character is equal to the precision specification. If the precision is missing, it shall be taken as `6`; if +the precision is explicitly zero and no `#` flag is present, no `radix` character shall appear. If a `radix` character +appears, at least one digit appears before it. The low-order digit shall be rounded in an implementation-defined manner. +A double argument representing an infinity shall be converted in one of the styles `[-]inf` or `[-]infinity`; which +style is implementation-defined. A double argument representing a NaN shall be converted in one of the styles +`[-]nan(n-char-sequence)` or `[-]nan`; which style, and the meaning of any n-char-sequence, is implementation-defined. +The `F` conversion specifier produces `INF`, `INFINITY`, or `NAN` instead of `inf`, `infinity`, or `nan`, respectively. + +* `e, E` - +The double argument shall be converted in the style `[-]d.ddde±dd`, where there is one digit before the `radix` +character (which is non-zero if the argument is non-zero) and the number of digits after it is equal to the precision; +if the precision is missing, it shall be taken as `6`; if the precision is zero and no '#' flag is present, no `radix` +character shall appear. The low-order digit shall be rounded in an implementation-defined manner. The `E` conversion +specifier shall produce a number with `E` instead of `e` introducing the exponent. The exponent shall always contain +at least two digits. If the value is zero, the exponent shall be zero. +A double argument representing an infinity or `NaN` shall be converted in the style of an `f` or `F` conversion +specifier. + +* `g`, `G` +The double argument representing a floating-point number shall be converted in the style `f` or `e` (or in the style `F` +or `E` in the case of a `G` conversion specifier), depending on the value converted and the precision. Let `P` equal the +precision if non-zero, `6` if the precision is omitted, or `1` if the precision is zero. Then, if a conversion with +style `E` would have an exponent of `X`: +\- If `P > X>=-4`, the conversion shall be with style `f` (or `F` ) and precision `P-(X+1)`. +\- Otherwise, the conversion shall be with style `e` (or `E` ) and precision `P-1`. +Finally, unless the `#` flag is used, any trailing zeros shall be removed from the fractional portion of the result and +the decimal-point character shall be removed if there is no fractional portion remaining. +A double argument representing an infinity or `NaN` shall be converted in the style of an `f` or `F` conversion +specifier. + +* `a`, `A` - +A double argument representing a floating-point number shall be converted in the style `[-]0xh.hhhhp±d`, where there is +one hexadecimal digit (which shall be non-zero if the argument is a normalized floating-point number and is otherwise +unspecified) before the decimal-point character and the number of hexadecimal digits after it is equal to the precision; +if the precision is missing and `FLT_RADIX` is a power of `2`, then the precision shall be sufficient for an exact +representation of the value; if the precision is missing and `FLT_RADIX` is not a power of `2`, then the precision shall +be sufficient to distinguish values of type double, except that trailing zeros may be omitted; if the precision is zero +and the `#` flag is not specified, no decimal-point character shall appear. The letters `abcdef` shall be used for a +conversion and the letters `ABCDEF` for A conversion. The `A` conversion specifier produces a number with `X` and `P` +instead of `x` and `p`. The exponent shall always contain at least one digit, and only as many more digits as necessary +to represent the decimal exponent of `2`. If the value is zero, the exponent shall be zero. A double argument representing an infinity or NaN shall be converted in the style of an `f` or `F` conversion specifier. - * `c` - -The int argument shall be converted to an `unsigned char`, and the resulting byte shall be written.

-If an `l (ell)` qualifier is present, the `wint_t` argument shall be converted as if by an `ls` conversion specification with no precision and an argument that points to a two-element array of type `wchar_t,` the first element of which contains the `wint_t` argument to the `ls` conversion specification and the second element contains a `null` wide character. - - * `s` - -The argument shall be a pointer to an array of `char`. Bytes from the array shall be written up to (but not including) any terminating `null` byte. If the precision is specified, no more than that many bytes shall be written. If the precision is not specified or is greater than the size of the array, the application shall ensure that the array contains a `null` byte.

-If an `l (ell)` qualifier is present, the argument shall be a pointer to an array of type `wchar_t`. Wide characters from the array shall be converted to characters (each as if by a call to the `wcrtomb()` function, with the conversion state described by an `mbstate_t` object initialized to zero before the first wide character is converted) up to and including a terminating `null` wide character. The resulting characters shall be written up to (but not including) the terminating `null` character (byte). If no precision is specified, the application shall ensure that the array contains a `null` wide character. If a precision is specified, no more than that many characters (bytes) shall be written (including shift sequences, if any), and the array shall contain a `null` wide character if, to equal the character sequence length given by the precision, the function would need to access a wide character one past the end of the array. In no case shall a partial character be written. - - * `p` - -The argument shall be a pointer to `void`. The value of the pointer is converted to a sequence of printable characters, in an implementation-defined manner. - - * `n` - -The argument shall be a pointer to an integer into which is written the number of bytes written to the output so far by this call to one of the `fprintf()` functions. No argument is converted. - - * `C` - -Equivalent to `lc`. +* `c` - +The int argument shall be converted to an `unsigned char`, and the resulting byte shall be written. +If an `l (ell)` qualifier is present, the `wint_t` argument shall be converted as if by an `ls` conversion specification +with no precision and an argument that points to a two-element array of type `wchar_t,` the first element of which +contains the `wint_t` argument to the `ls` conversion specification and the second element contains a `null` wide +character. + +* `s` - +The argument shall be a pointer to an array of `char`. Bytes from the array shall be written up to (but not including) +any terminating `null` byte. If the precision is specified, no more than that many bytes shall be written. If the +precision is not specified or is greater than the size of the array, the application shall ensure that the array +contains a `null` byte. +If an `l (ell)` qualifier is present, the argument shall be a pointer to an array of type `wchar_t`. Wide characters +from the array shall be converted to characters (each as if by a call to the `wcrtomb()` function, with the conversion +state described by an `mbstate_t` object initialized to zero before the first wide character is converted) up to and +including a terminating `null` wide character. The resulting characters shall be written up to (but not including) the +terminating `null` character (byte). If no precision is specified, the application shall ensure that the array contains +a `null` wide character. If a precision is specified, no more than that many characters (bytes) shall be written +(including shift sequences, if any), and the array shall contain a `null` wide character if, to equal the character +sequence length given by the precision, the function would need to access a wide character one past the end of the +array. In no case shall a partial character be written. + +* `p` - +The argument shall be a pointer to `void`. The value of the pointer is converted to a sequence of printable characters, +in an implementation-defined manner. + +* `n` - +The argument shall be a pointer to an integer into which is written the number of bytes written to the output so far by +this call to one of the `fprintf()` functions. No argument is converted. + +* `C` - +Equivalent to `lc`. * `S` - -Equivalent to `ls`. +Equivalent to `ls`. -* `%` - +* `%` - Print a `%` character; no argument is converted. The complete conversion specification shall be `%%`. -If a conversion specification does not match one of the above forms, the behavior is undefined. If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined. +If a conversion specification does not match one of the above forms, the behavior is undefined. If any argument is not +the correct type for the corresponding conversion specification, the behavior is undefined. -In no case shall a nonexistent or small field width cause truncation of a field; if the result of a conversion is wider than the field width, the field shall be expanded to contain the conversion result. Characters generated by `fprintf()` and `printf()` are printed as if `fputc()` had been called. +In no case shall a nonexistent or small field width cause truncation of a field; if the result of a conversion is wider +than the field width, the field shall be expanded to contain the conversion result. Characters generated by `fprintf()` +and `printf()` are printed as if `fputc()` had been called. -For the `a` and `A` conversion specifiers, if `FLT_RADIX` is a power of `2`, the value shall be correctly rounded to a hexadecimal floating number with the given precision. +For the `a` and `A` conversion specifiers, if `FLT_RADIX` is a power of `2`, the value shall be correctly rounded to a +hexadecimal floating number with the given precision. -For `a` and `A` conversions, if `FLT_RADIX` is not a power of `2` and the result is not exactly representable in the given precision, the result should be one of the two adjacent numbers in hexadecimal floating style with the given precision, with the extra stipulation that the error should have a correct sign for the current rounding direction. +For `a` and `A` conversions, if `FLT_RADIX` is not a power of `2` and the result is not exactly representable in the +given precision, the result should be one of the two adjacent numbers in hexadecimal floating style with the given +precision, with the extra stipulation that the error should have a correct sign for the current rounding direction. -For the `e`, `E`, `f`, `F`, `g`, and `G` conversion specifiers, if the number of significant decimal digits is at most `DECIMAL_DIG,` then the result should be correctly rounded. If the number of significant decimal digits is more than `DECIMAL_DIG` but the source value is exactly representable with `DECIMAL_DIG` digits, then the result should be an exact representation with trailing zeros. Otherwise, the source value is bounded by two adjacent decimal strings `L < U`, both having `DECIMAL_DIG` significant digits; the value of the resultant decimal string `D` should satisfy `L <= D <= U`, with the extra stipulation that the error should have a correct sign for the current rounding direction. +For the `e`, `E`, `f`, `F`, `g`, and `G` conversion specifiers, if the number of significant decimal digits is at most +`DECIMAL_DIG,` then the result should be correctly rounded. If the number of significant decimal digits is more than +`DECIMAL_DIG` but the source value is exactly representable with `DECIMAL_DIG` digits, then the result should be an +exact representation with trailing zeros. Otherwise, the source value is bounded by two adjacent decimal strings +`L < U`, both having `DECIMAL_DIG` significant digits; the value of the resultant decimal string `D` should satisfy +`L <= D <= U`, with the extra stipulation that the error should have a correct sign for the current rounding direction. The last data modification and last file status change timestamps of the file shall be marked for update: - * Between the call to a successful execution of `fprintf()` or `printf()` and the next successful completion of a call to `fflush()` or `fclose()` on the same stream or a call to `exit()` or `abort()` - - * Upon successful completion of a call to `dprintf()` - +* Between the call to a successful execution of `fprintf()` or `printf()` and the next successful completion of a call +to `fflush()` or `fclose()` on the same stream or a call to `exit()` or `abort()` +* Upon successful completion of a call to `dprintf()` ## Return value +Upon successful completion, the `dprintf()`, `fprintf()`, and `printf()` functions shall return the number of bytes +transmitted. -Upon successful completion, the `dprintf()`, `fprintf()`, and `printf()` functions shall return the number of bytes transmitted. - -Upon successful completion, the `sprintf()` function shall return the number of bytes written to _s_, excluding the terminating `null` byte. +Upon successful completion, the `sprintf()` function shall return the number of bytes written to _s_, excluding the +terminating `null` byte. -Upon successful completion, the `snprintf()` function shall return the number of bytes that would be written to _s_ had `n` been sufficiently large excluding the terminating `null` byte. +Upon successful completion, the `snprintf()` function shall return the number of bytes that would be written to _s_ +had `n` been sufficiently large excluding the terminating `null` byte. -If an output error was encountered, these functions shall return a negative value and set `errno` to indicate the error. - -If the value of `n` is zero on a call to `snprintf()`, nothing shall be written, the number of bytes that would have been written had `n` been sufficiently large excluding the terminating `null` shall be returned, and _s_ may be a `null` pointer. +If an output error was encountered, these functions shall return a negative value and set `errno` to indicate the +error. +If the value of `n` is zero on a call to `snprintf()`, nothing shall be written, the number of bytes that would have +been written had `n` been sufficiently large excluding the terminating `null` shall be returned, and _s_ may be a +`null` pointer. ## Errors - -For the conditions under which `dprintf()`, `fprintf()`, and `printf()` fail and may fail, refer to `fputc()` or `fputwc()`. +For the conditions under which `dprintf()`, `fprintf()`, and `printf()` fail and may fail, refer to `fputc()` or +`fputwc()`. In addition, all forms of `fprintf()` shall fail if: - * `EILSEQ` - A wide-character code that does not correspond to a valid character has been detected. +* `EILSEQ` - A wide-character code that does not correspond to a valid character has been detected. - * `EOVERFLOW` - The value to be returned is greater than `INT_MA`. +* `EOVERFLOW` - The value to be returned is greater than `INT_MA`. The `dprintf()` function may fail if: - * `EBADF` - The _fildes_ argument is not a valid file descriptor. +* `EBADF` - The _fildes_ argument is not a valid file descriptor. The `dprintf()`, `fprintf()`, and `printf()` functions may fail if: - - `ENOMEM` - Insufficient storage space is available. +* `ENOMEM` - Insufficient storage space is available. The `snprintf()` function shall fail if: - - `EOVERFLOW` - The value of `n` is greater than `INT_MA`.
+* `EOVERFLOW` - The value of `n` is greater than `INT_MA`. ## Tests @@ -226,6 +372,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/p/putc.part-impl.md b/libc/functions/p/putc.part-impl.md index b46b3716..a2e4802f 100644 --- a/libc/functions/p/putc.part-impl.md +++ b/libc/functions/p/putc.part-impl.md @@ -1,33 +1,30 @@ -# Synopsis -`#include `
+# Synopsis -` int putc(int c, FILE *stream);`
+`#include ` + +`int putc(int c, FILE *stream);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description -The `putc()` function shall be equivalent to `fputc()`, except that if it is -implemented as a macro it may evaluate stream more than once, so the argument should never be an expression with -side-effects. +## Description +The `putc()` function shall be equivalent to `fputc()`, except that if it is implemented as a macro it may evaluate +stream more than once, so the argument should never be an expression with side-effects. ## Return value - Refer to fputc. - ## Errors - Refer to fputc. - - - ## Tests Untested @@ -36,6 +33,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/p/putchar.part-impl.md b/libc/functions/p/putchar.part-impl.md index 65d99153..04a519f2 100644 --- a/libc/functions/p/putchar.part-impl.md +++ b/libc/functions/p/putchar.part-impl.md @@ -1,33 +1,31 @@ -# Synopsis -`#include `
+# Synopsis -` int putchar(int c);`
+`#include ` + +`int putchar(int c);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description `putchar()` - put a byte on a stdout stream The function call `putchar(c)` shall be equivalent to `putc(c,stdout)`. - ## Return value - Refer to fputc. - ## Errors - Refer to fputc. - - - ## Tests Untested @@ -36,6 +34,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/p/putchar_unlocked.part-impl.md b/libc/functions/p/putchar_unlocked.part-impl.md index 10ebad55..67966eec 100644 --- a/libc/functions/p/putchar_unlocked.part-impl.md +++ b/libc/functions/p/putchar_unlocked.part-impl.md @@ -1,47 +1,44 @@ -# Synopsis -`#include `
+# Synopsis -` int getc_unlocked(FILE *stream);`
+`#include ` -` int getchar_unlocked(void);`
+`int getc_unlocked(FILE *stream);` -` int putc_unlocked(int c, FILE *stream);`
+`int getchar_unlocked(void);` -` int putchar_unlocked(int c); `
+`int putc_unlocked(int c, FILE *stream);` + +` int putchar_unlocked(int c); ` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -Versions of the functions `getc()`, `getchar()`, `putc()`, and `putchar()` respectively named `getc_unlocked()`, `getchar_unlocked()`, -`putc_unlocked()`, and `putchar_unlocked()` shall be provided which are functionally equivalent to the original versions, -with the exception that they are not required to be implemented in a fully thread-safe manner. They shall be thread-safe when used -within a scope protected by `flockfile()` (or `ftrylockfile()`) and `funlockfile()`. +Versions of the functions `getc()`, `getchar()`, `putc()`, and `putchar()` respectively named `getc_unlocked()`, +`getchar_unlocked()`,`putc_unlocked()`, and `putchar_unlocked()` shall be provided which are functionally equivalent to +the original versions, with the exception that they are not required to be implemented in a fully thread-safe manner. +They shall be thread-safe when used within a scope protected by `flockfile()` (or `ftrylockfile()`) and `funlockfile()`. -These functions can safely be used in a multi-threaded program if and only if they are called while the invoking thread owns the `( FILE *)` object, as is the case after a successful call to the `flockfile()` -or `ftrylockfile()` functions. +These functions can safely be used in a multi-threaded program if and only if they are called while the invoking thread +owns the `( FILE *)` object, as is the case after a successful call to the `flockfile()` or `ftrylockfile()` functions. If `getc_unlocked()` or `putc_unlocked()` are implemented as macros they may evaluate stream more than once, so the stream argument should never be an expression with side-effects. - ## Return value - See `getc()`, `getchar()`, `putc()`, and `putchar()`. - ## Errors - See `getc()`, `getchar()`, `putc()`, and `putchar()`. - - - ## Tests Untested @@ -50,6 +47,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/p/putenv.part-impl.md b/libc/functions/p/putenv.part-impl.md index bcbe2242..6eaa34a6 100644 --- a/libc/functions/p/putenv.part-impl.md +++ b/libc/functions/p/putenv.part-impl.md @@ -1,40 +1,38 @@ -# Synopsis -`#include `
+# Synopsis -`int putenv(char *string);`
+`#include ` + +`int putenv(char *string);` ## Status + Partially implemented -## Conformance -IEEE Std 1003.1-2017 -## Description +## Conformance +IEEE Std 1003.1-2017 +## Description -The `putenv()` function shall use the string argument to set environment variable values. The string argument should point to a string of the form " name= value ". The `putenv()` function shall make the value of the environment variable name equal to value by altering an existing variable or creating a new one. In either case, the string pointed to by string shall become part of the environment, so altering the string shall change the environment. +The `putenv()` function shall use the string argument to set environment variable values. The string argument should +point to a string of the form " name= value ". The `putenv()` function shall make the value of the environment variable +name equal to value by altering an existing variable or creating a new one. In either case, the string pointed to by +string shall become part of the environment, so altering the string shall change the environment. The `putenv()` function need not be thread-safe. - - ## Return value - -Upon successful completion, `putenv()` shall return `0`; otherwise, it shall return a non-zero value and set `errno` to indicate the error. - +Upon successful completion, `putenv()` shall return `0`; otherwise, it shall return a non-zero value and set `errno` to +indicate the error. ## Errors - The function may fail if: - * `EINVAL` - The string argument doesn't contain `'='`. - - * `ENOMEM` - Insufficient memory was available. - - +* `EINVAL` - The string argument doesn't contain `'='`. +* `ENOMEM` - Insufficient memory was available. ## Tests @@ -44,6 +42,7 @@ Tested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/p/puts.part-impl.md b/libc/functions/p/puts.part-impl.md index f9561ffc..ab81c6b7 100644 --- a/libc/functions/p/puts.part-impl.md +++ b/libc/functions/p/puts.part-impl.md @@ -1,36 +1,36 @@ -# Synopsis -`#include `
+# Synopsis -` int puts(const char *s);`
+`#include ` + +`int puts(const char *s);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The `puts()` function shall write the string pointed to by _s_, followed by a ``, to the standard output -stream stdout. The terminating `null` byte shall not be written. +The `puts()` function shall write the string pointed to by _s_, followed by a ``, to the standard output stream +stdout. The terminating `null` byte shall not be written. The -last data modification and last file status change timestamps of the file shall be marked for update between the successful -execution of `puts()` and the next successful completion of a call to `fflush()` -or `fclose()` on the same stream or a call to `exit()` or `abort()`. - +last data modification and last file status change timestamps of the file shall be marked for update between the +successful execution of `puts()` and the next successful completion of a call to `fflush()` or `fclose()` on the same +stream or a call to `exit()` or `abort()`. ## Return value - -Upon successful completion, `puts()` shall return a non-negative number. Otherwise, it shall return `EOF`, shall set an error -indicator for the stream,  and `errno` shall be set to indicate the error. - +Upon successful completion, `puts()` shall return a non-negative number. Otherwise, it shall return `EOF`, shall set an +error indicator for the stream,  and `errno` shall be set to indicate the error. ## Errors Refer to `fputc()`. - ## Tests Untested @@ -39,6 +39,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/q/qsort.part-impl.md b/libc/functions/q/qsort.part-impl.md index eeef7db1..e28e0e55 100644 --- a/libc/functions/q/qsort.part-impl.md +++ b/libc/functions/q/qsort.part-impl.md @@ -1,47 +1,46 @@ -# Synopsis -`#include `
+# Synopsis -` void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *));`
+`#include ` + +`void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *));` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The `qsort()` function shall sort an array of nel objects, the initial element of which is pointed to by -_base_. The size of each object, in bytes, is specified by the _width_ argument. If the nel argument has the value -zero, the comparison function pointed to by compar shall not be called and no rearrangement shall take place. +The `qsort()` function shall sort an array of nel objects, the initial element of which is pointed to by _base_. +The size of each object, in bytes, is specified by the _width_ argument. If the nel argument has the value zero, +the comparison function pointed to by compar shall not be called and no rearrangement shall take place. The application shall ensure that the comparison function pointed to by compar does not alter the contents of the array. -The implementation may reorder elements of the array between calls to the comparison function, but shall not alter the contents of -any individual element. +The implementation may reorder elements of the array between calls to the comparison function, but shall not alter the +contents of any individual element. -When the same objects (consisting of _width_ bytes, irrespective of their current positions in the array) are passed more than -once to the comparison function, the results shall be consistent with one another. That is, they shall define a total ordering on -the array. - -The contents of the array shall be sorted in ascending order according to a comparison function. The compar argument is a -pointer to the comparison function, which is called with two arguments that point to the elements being compared. The application -shall ensure that the function returns an integer less than, equal to, or greater than `0`, if the first argument is considered -respectively less than, equal to, or greater than the second. If two members compare as equal, their order in the sorted array is -unspecified. +When the same objects (consisting of _width_ bytes, irrespective of their current positions in the array) are passed +more than once to the comparison function, the results shall be consistent with one another. That is, they shall +define a total ordering on the array. +The contents of the array shall be sorted in ascending order according to a comparison function. The compar argument is +a pointer to the comparison function, which is called with two arguments that point to the elements being compared. The +application shall ensure that the function returns an integer less than, equal to, or greater than `0`, if the first +argument is considered respectively less than, equal to, or greater than the second. If two members compare as equal, +their order in the sorted array is unspecified. ## Return value - The `qsort()` function shall not return a value. - ## Errors - No errors are defined. - ## Tests Untested @@ -50,6 +49,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/r/rand.part-impl.md b/libc/functions/r/rand.part-impl.md index dafad51b..59d03b3f 100644 --- a/libc/functions/r/rand.part-impl.md +++ b/libc/functions/r/rand.part-impl.md @@ -1,50 +1,46 @@ -# Synopsis -`#include `
+# Synopsis -` int rand(void);`
+`#include ` -`int rand_r(unsigned *seed); `
+`int rand(void);` -` void srand(unsigned seed);`
+`int rand_r(unsigned *seed);` + +`void srand(unsigned seed);` ## Status + Partially implemented + ## Conformance -IEEE Std 1003.1-2017 -## Description +IEEE Std 1003.1-2017 -The `rand()` function shall compute a sequence of pseudo-random integers in the range `[0, RAND_MA]`  with a -period of at least `232`. +## Description - The -`rand()` function need not be thread-safe. - The `rand_r()` function shall compute a sequence of pseudo-random integers in the range `[0, RAND_MA]`. (The value of -the ``RAND_MA`` macro shall be at least `32767`.) -If ``rand_r()`` is called with the same initial value for the object pointed to by _seed_ and that object is not -modified between successive returns and calls to `rand_r()`, the same sequence shall be generated. -The `srand()` function uses the argument as a seed for a new sequence of pseudo-random numbers to be returned by subsequent -calls to `rand()`. If `srand()` is then called with the same seed value, the sequence of pseudo-random numbers shall be -repeated. If `rand()` is called before any calls to `srand()` are made, the same sequence shall be generated as when -`srand()` is first called with a seed value of `1`. -The implementation shall behave as if no function defined in this volume of POSIX.1-2017 calls `rand()` or -`srand()`. +The `rand()` function shall compute a sequence of pseudo-random integers in the range `[0, RAND_MA]`  with a period of +at least `232`. + The `rand()` function need not be thread-safe. The `rand_r()` function shall compute a sequence of pseudo-random + integers in the range `[0, RAND_MA]`. (The value of the ``RAND_MA`` macro shall be at least `32767`.) If ``rand_r()`` + is called with the same initial value for the object pointed to by _seed_ and that object is not modified between + successive returns and calls to `rand_r()`, the same sequence shall be generated. The `srand()` function uses the + argument as a seed for a new sequence of pseudo-random numbers to be returned by subsequent calls to `rand()`. If + `srand()` is then called with the same seed value, the sequence of pseudo-random numbers shall be repeated. If `rand()` + is called before any calls to `srand()` are made, the same sequence shall be generated as when `srand()` is first + called with a seed value of `1`. The implementation shall behave as if no function defined in this volume of + POSIX.1-2017 calls `rand()` or `srand()`. ## Return value - -The `rand()` function shall return the next pseudo-random number in the sequence. -The `rand_r()` function shall return a pseudo-random integer. -The `srand()` function shall not return a value. - +* The `rand()` function shall return the next pseudo-random number in the sequence. +* The `rand_r()` function shall return a pseudo-random integer. +* The `srand()` function shall not return a value. ## Errors - No errors are defined. - ## Tests Untested @@ -53,6 +49,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/r/read.part-impl.md b/libc/functions/r/read.part-impl.md index 37d999d2..a248b55f 100644 --- a/libc/functions/r/read.part-impl.md +++ b/libc/functions/r/read.part-impl.md @@ -1,44 +1,50 @@ -# Synopsis -`#include `
+# Synopsis -`ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset);`
+`#include ` -`ssize_t read(int fildes, void *buf, size_t nbyte);`
+`ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset);` + +`ssize_t read(int fildes, void *buf, size_t nbyte);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `read()` function shall attempt to read _nbyte_ bytes from the file associated with the open file descriptor, _fildes_, into the buffer pointed to by _buf_. The behavior of multiple concurrent reads on the same pipe, `FIFO`, or terminal device is unspecified. Before any action described below is taken, and if _nbyte_ is zero, the `read()` function may detect and return errors -as described below. In the absence of errors, or if error detection is not performed, the `read()` function shall return zero -and have no other results. -On files that support seeking (for example, a regular file), the `read()` shall start at a position in the file given by -the file offset associated with _fildes_. The file offset shall be incremented by the number of bytes actually read. +as described below. In the absence of errors, or if error detection is not performed, the `read()` function shall +return zero and have no other results. -Files that do not support seeking-for example, terminals-always read from the current position. The value of a file offset -associated with such a file is undefined. +On files that support seeking (for example, a regular file), the `read()` shall start at a position in the file given +by the file offset associated with _fildes_. The file offset shall be incremented by the number of bytes actually read. -No data transfer shall occur past the current end-of-file. If the starting position is at or after the end-of-file, `0` shall be -returned. If the file refers to a device special file, the result of subsequent `read()` requests is +Files that do not support seeking-for example, terminals-always read from the current position. The value of a file +offset associated with such a file is undefined. + +No data transfer shall occur past the current end-of-file. If the starting position is at or after the end-of-file, +`0` shall be returned. If the file refers to a device special file, the result of subsequent `read()` requests is implementation-defined. + If the value of _nbyte_ is greater than `SSIZE_MAX`, the result is implementation-defined. When attempting to read from an empty pipe or `FIFO`: - - * If no process has the pipe open for writing, `read()` shall return 0 to indicate end-of-file. -* If some process has the pipe open for writing and `O_NONBLOCK` is set, `read()` shall return -1 and set errno to `EAGAIN`. +* If some process has the pipe open for writing and `O_NONBLOCK` is set, `read()` shall return -1 and set errno to +`EAGAIN`. -* If some process has the pipe open for writing and `O_NONBLOCK` is clear, `read()` shall block the calling thread until some data is written or the pipe is closed by all processes that had the pipe open for writing. +* If some process has the pipe open for writing and `O_NONBLOCK` is clear, `read()` shall block the calling thread +until some data is written or the pipe is closed by all processes that had the pipe open for writing. When attempting to read a file (other than a pipe or `FIFO`) that supports non-blocking reads and has no data currently available: @@ -50,148 +56,142 @@ available: * The use of the `O_NONBLOCK` flag has no effect if there is some data available. The `read()` function reads data previously written to a file. If any portion of a regular file prior to the end-of-file -has not been written, `read()` shall return bytes with value `0`. For example, `lseek()` allows the file offset to be set beyond the end of existing data in the file. If data -is later written at this point, subsequent reads in the gap between the previous end of data and the newly written data shall -return bytes with value `0` until data is written into the gap. +has not been written, `read()` shall return bytes with value `0`. For example, `lseek()` allows the file offset to be +set beyond the end of existing data in the file. If data is later written at this point, subsequent reads in the gap +between the previous end of data and the newly written data shall return bytes with value `0` until data is written +into the gap. Upon successful completion, where _nbyte_ is greater than `0`, `read()` shall mark for update the last data access -timestamp of the file, and shall return the number of bytes read. This number shall never be greater than _nbyte_. The value -returned may be less than _nbyte_ if the number of bytes left in the file is less than _nbyte_, if the `read()` -request was interrupted by a signal, or if the file is a pipe or `FIFO` or special file and has fewer than _nbyte_ bytes -immediately available for reading. For example, a `read()` from a file associated with a terminal may return one typed line of -data. +timestamp of the file, and shall return the number of bytes read. This number shall never be greater than _nbyte_. +The value returned may be less than _nbyte_ if the number of bytes left in the file is less than _nbyte_, if the +`read()` request was interrupted by a signal, or if the file is a pipe or `FIFO` or special file and has fewer than +_nbyte_ bytes immediately available for reading. For example, a `read()` from a file associated with a terminal may +return one typed line of data. If a `read()` is interrupted by a signal before it reads any data, it shall return `-1` with errno set to `EINTR`. If a `read()` is interrupted by a signal after it has successfully read some data, it shall return the number of bytes read. -For regular files, no data transfer shall occur past the offset maximum established in the open file description associated with -_fildes_. +For regular files, no data transfer shall occur past the offset maximum established in the open file description +associated with _fildes_. -If _fildes_ refers to a socket, `read()` shall be equivalent to `recv()` -with no flags set. +If _fildes_ refers to a socket, `read()` shall be equivalent to `recv()` with no flags set. -If the `O_DSYNC` and `O_RSYNC` bits have been set, read I/O operations on the file descriptor shall complete as defined by synchronized -I/O data integrity completion. If the `O_SYNC` and `O_RSYNC` bits have been set, read I/O operations on the file descriptor shall -complete as defined by synchronized I/O file integrity completion. +If the `O_DSYNC` and `O_RSYNC` bits have been set, read I/O operations on the file descriptor shall complete as defined +by synchronized I/O data integrity completion. If the `O_SYNC` and `O_RSYNC` bits have been set, read I/O operations on +the file descriptor shall complete as defined by synchronized I/O file integrity completion. -If _fildes_ refers to a shared memory object, the result of the `read()` function is unspecified. +If _fildes_ refers to a shared memory object, the result of the `read()` function is unspecified. -If _fildes_ refers to a typed memory object, the result of the `read()` function is unspecified. +If _fildes_ refers to a typed memory object, the result of the `read()` function is unspecified. -A `read()` from a STREAMS file can read data in three different modes: byte-stream mode, message-nondiscard -mode, and message-discard mode. The default shall be byte-stream mode. This can be changed using the `I_SRDOPT` `ioctl()` request, and can be tested with `I_GRDOPT` `ioctl()`. In byte-stream mode, `read()` shall retrieve data from the `STREAM` until as many -bytes as were requested are transferred, or until there is no more data to be retrieved. Byte-stream mode ignores message -boundaries. +A `read()` from a STREAMS file can read data in three different modes: byte-stream mode, message-nondiscard mode, and +message-discard mode. The default shall be byte-stream mode. This can be changed using the `I_SRDOPT` `ioctl()` request, +and can be tested with `I_GRDOPT` `ioctl()`. In byte-stream mode, `read()` shall retrieve data from the `STREAM` until +as many bytes as were requested are transferred, or until there is no more data to be retrieved. Byte-stream mode +ignores message boundaries. -In `STREAMS` message-nondiscard mode, `read()` shall retrieve data until as many bytes as were requested are transferred, or -until a message boundary is reached. If `read()` does not retrieve all the data in a message, the remaining data shall be left -on the `STREAM`, and can be retrieved by the next `read()` call. Message-discard mode also retrieves data until as many bytes as -were requested are transferred, or a message boundary is reached. However, unread data remaining in a message after the -`read()` returns shall be discarded, and shall not be available for a subsequent `read()`, `getmsg()`, or `getpmsg()` call. +In `STREAMS` message-nondiscard mode, `read()` shall retrieve data until as many bytes as were requested are +transferred, or until a message boundary is reached. If `read()` does not retrieve all the data in a message, the +remaining data shall be left on the `STREAM`, and can be retrieved by the next `read()` call. Message-discard mode also +retrieves data until as many bytes as were requested are transferred, or a message boundary is reached. However, unread +data remaining in a message after the `read()` returns shall be discarded, and shall not be available for a subsequent +`read()`, `getmsg()`, or `getpmsg()` call. How `read()` handles zero-byte `STREAMS` messages is determined by the current read mode setting. In byte-stream mode, `read()` shall accept data until it has read _nbyte_ bytes, or until there is no more data to read, or until a zero-byte message block is encountered. The `read()` function shall then return the number of bytes read, and place the zero-byte -message back on the `STREAM` to be retrieved by the next `read()`, `getmsg()`, or `getpmsg()`. In message-nondiscard mode or message-discard mode, a zero-byte message -shall return 0 and the message shall be removed from the `STREAM`. When a zero-byte message is read as the first message on a `STREAM`, -the message shall be removed from the `STREAM` and 0 shall be returned, regardless of the read mode. - -A `read()` from a `STREAMS` file shall return the data in the message at the front of the `STREAM` head read queue, regardless -of the priority band of the message. - -By default, `STREAMs` are in control-normal mode, in which a `read()` from a `STREAMS` file can only process messages that -contain a data part but do not contain a control part. The `read()` shall fail if a message containing a control part is -encountered at the `STREAM` head. This default action can be changed by placing the `STREAM` in either control-data mode or -control-discard mode with the `I_SRDOPT` `ioctl()` command. In control-data mode, -`read()` shall convert any control part to data and pass it to the application before passing any data part originally present -in the same message. In control-discard mode, `read()` shall discard message control parts but return to the process any data -part in the message. -In addition, `read()` shall fail if the `STREAM` head had processed an asynchronous error before the call. In this case, the -value of errno shall not reflect the result of `read()`, but reflect the prior error. If a hangup occurs on the `STREAM` -being read, `read()` shall continue to operate normally until the `STREAM` head read queue is empty. Thereafter, it shall return -`0`. +message back on the `STREAM` to be retrieved by the next `read()`, `getmsg()`, or `getpmsg()`. In message-nondiscard +mode or message-discard mode, a zero-byte message shall return 0 and the message shall be removed from the `STREAM`. +When a zero-byte message is read as the first message on a `STREAM`, the message shall be removed from the `STREAM` +and 0 shall be returned, regardless of the read mode. + +A `read()` from a `STREAMS` file shall return the data in the message at the front of the `STREAM` head read queue, +regardless of the priority band of the message. + +By default, `STREAMs` are in control-normal mode, in which a `read()` from a `STREAMS` file can only process messages +that contain a data part but do not contain a control part. The `read()` shall fail if a message containing a control +part is encountered at the `STREAM` head. This default action can be changed by placing the `STREAM` in either +control-data mode or control-discard mode with the `I_SRDOPT` `ioctl()` command. In control-data mode, `read()` +shall convert any control part to data and pass it to the application before passing any data part originally present in +the same message. In control-discard mode, `read()` shall discard message control parts but return to the process any +data part in the message. + +In addition, `read()` shall fail if the `STREAM` head had processed an asynchronous error before the call. In this case, +the value of errno shall not reflect the result of `read()`, but reflect the prior error. If a hangup occurs on the +`STREAM` being read, `read()` shall continue to operate normally until the `STREAM` head read queue is empty. +Thereafter, it shall return `0`. The `pread()` function shall be equivalent to `read()`, except that it shall read from a given position in the file -without changing the file offset. The first three arguments to `pread()` are the same as `read()` with the addition of a -fourth argument offset for the desired position inside the file. An attempt to perform a `pread()` on a file that is -incapable of seeking shall result in an error. - +without changing the file offset. The first three arguments to `pread()` are the same as `read()` with the addition +of a fourth argument offset for the desired position inside the file. An attempt to perform a `pread()` on a file that +is incapable of seeking shall result in an error. ## Return value - -Upon successful completion, these functions shall return a non-negative integer indicating the number of bytes actually read. -Otherwise, the functions shall return `-1` and set errno to indicate the error. +Upon successful completion, these functions shall return a non-negative integer indicating the number of bytes actually +read. Otherwise, the functions shall return `-1` and set errno to indicate the error. ## Errors - These functions shall fail if: +* `EAGAIN` - The file is neither a pipe, nor a `FIFO`, nor a socket, the `O_NONBLOCK` flag is set for the file +descriptor, and the thread would be delayed in the read operation. - * `EAGAIN` - The file is neither a pipe, nor a `FIFO`, nor a socket, the `O_NONBLOCK` flag is set for the file descriptor, and the thread would -be delayed in the read operation. - - * `EBADF` - The fildes argument is not a valid file descriptor open for reading. +* `EBADF` - The fildes argument is not a valid file descriptor open for reading. - * `EBADMSG` - The file is a `STREAM` file that is set to control-normal mode and the message waiting to be read includes a control -part. +* `EBADMSG` - The file is a `STREAM` file that is set to control-normal mode and the message waiting to be read includes +a control +part. - * `EINTR` - The read operation was terminated due to the receipt of a signal, and no data was transferred. +* `EINTR` - The read operation was terminated due to the receipt of a signal, and no data was transferred. - * `EINVAL` - The `STREAM` or multiplexer referenced by _fildes_ is linked (directly or indirectly) downstream from a multiplexer. +* `EINVAL` - The `STREAM` or multiplexer referenced by _fildes_ is linked (directly or indirectly) downstream from a +multiplexer. +* `EIO` - The process is a member of a background process group attempting to read from its controlling terminal, and +either the calling thread is blocking `SIGTTIN` or the process is ignoring `SIGTTIN` or the process group of the process +is orphaned. This error may also be generated for implementation-defined reasons. - * `EIO` - The process is a member of a background process group attempting to read from its controlling terminal, and either the calling -thread is blocking `SIGTTIN` or the process is ignoring `SIGTTIN` or the process group of the process is orphaned. This error may also -be generated for implementation-defined reasons. +* `EISDIR` - The _fildes_ argument refers to a directory and the implementation does not allow the directory to be read +using `read()` or `pread()`. The `readdir()` function should be used instead. - * `EISDIR` - -The _fildes_ argument refers to a directory and the implementation does not allow the directory to be read using `read()` -or `pread()`. The `readdir()` function should be used instead. - - * `EOVERFLOW` - The file is a regular file, _nbyte_ is greater than `0`, the starting position is before the end-of-file, and the starting -position is greater than or equal to the offset maximum established in the open file description associated with -_fildes_. +* `EOVERFLOW` - The file is a regular file, _nbyte_ is greater than `0`, the starting position is before the +end-of-file, and the starting position is greater than or equal to the offset maximum established in the open +file description associated with _fildes_. The `pread()` function shall fail if: +* `EINVAL` - The file is a regular file or block special file, and the offset argument is negative. The file offset +shall remain unchanged. - * `EINVAL` - The file is a regular file or block special file, and the offset argument is negative. The file offset shall remain -unchanged. - - * `ESPIPE` - The file is incapable of seeking. - +* `ESPIPE` - The file is incapable of seeking. The `read()` function shall fail if: +* `EAGAIN` - The file is a pipe or `FIFO`, the `O_NONBLOCK` flag is set for the file descriptor, and the thread would be +delayed in the read operation. - * `EAGAIN` - The file is a pipe or `FIFO`, the `O_NONBLOCK` flag is set for the file descriptor, and the thread would be delayed in the read -operation. +* `EAGAIN` or `EWOULDBLOCK` - The file is a socket, the `O_NONBLOCK` flag is set for the file descriptor, and the thread +would be delayed in the read operation. - - `EAGAIN` or `EWOULDBLOCK` - The file is a socket, the `O_NONBLOCK` flag is set for the file descriptor, and the thread would be delayed in the read -operation. +* `ECONNRESET` - A read was attempted on a socket and the connection was forcibly closed by its peer. - * `ECONNRESET` - A read was attempted on a socket and the connection was forcibly closed by its peer. +* `ENOTCONN` - A read was attempted on a socket that is not connected. - * `ENOTCONN` - A read was attempted on a socket that is not connected. - - * `ETIMEDOUT` - A read was attempted on a socket and a transmission timeout occurred. +* `ETIMEDOUT` - A read was attempted on a socket and a transmission timeout occurred. These functions may fail if: +* `EIO` - A physical I/O error has occurred. - * `EIO` - A physical I/O error has occurred. - - * `ENOBUFS` - Insufficient resources were available in the system to perform the operation. - - * `ENOMEM` - Insufficient memory was available to fulfill the request. - - * `ENXIO` - A request was made of a nonexistent device, or the request was outside the capabilities of the device. +* `ENOBUFS` - Insufficient resources were available in the system to perform the operation. +* `ENOMEM` - Insufficient memory was available to fulfill the request. +* `ENXIO` - A request was made of a nonexistent device, or the request was outside the capabilities of the device. ## Tests @@ -201,6 +201,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/r/readdir.part-impl.md b/libc/functions/r/readdir.part-impl.md index b52af98d..caaf40ec 100644 --- a/libc/functions/r/readdir.part-impl.md +++ b/libc/functions/r/readdir.part-impl.md @@ -1,97 +1,95 @@ -# Synopsis -`#include `
+# Synopsis -` struct dirent *readdir(DIR *dirp);`
+`#include ` -` int readdir_r(DIR *restrict dirp, struct dirent *restrict entry, struct dirent **restrict result);`
+`struct dirent *readdir(DIR *dirp);` + +`int readdir_r(DIR *restrict dirp, struct dirent *restrict entry, struct dirent **restrict result);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description -The type DIR, which is defined in the `` header, represents -a directory stream, which is an ordered sequence of all the directory entries in a particular directory. Directory entries -represent files; files may be removed from a directory or added to a directory asynchronously to the operation of -`readdir()`. +The type DIR, which is defined in the `` header, represents a directory stream, which is an ordered sequence +of all the directory entries in a particular directory. Directory entries represent files; files may be removed from a +directory or added to a directory asynchronously to the operation of `readdir()`. -The `readdir()` function shall return a pointer to a structure representing the directory entry at the current position in -the directory stream specified by the argument _dirp_, and position the directory stream at the next entry. It shall return a -`null` pointer upon reaching the end of the directory stream. The structure _dirent_ defined in the `` header describes a directory entry. The value of the structure's -`d_ino` member shall be set to the file serial number of the file named by the `d_name` member. If the `d_name` -member names a symbolic link, the value of the `d_ino` member shall be set to the file serial number of the symbolic link +The `readdir()` function shall return a pointer to a structure representing the directory entry at the current position +in the directory stream specified by the argument _dirp_, and position the directory stream at the next entry. It shall +return a `null` pointer upon reaching the end of the directory stream. The structure _dirent_ defined in the +`` header describes a directory entry. The value of the structure's `d_ino` member shall be set to the +file serial number of the file named by the `d_name` member. If the `d_name` member names a symbolic link, the value of +the `d_ino` member shall be set to the file serial number of the symbolic link itself. The `readdir()` function shall not return directory entries containing empty names. If entries for dot or dot-dot exist, one entry shall be returned for dot and one entry shall be returned for dot-dot; otherwise, they shall not be returned. The application shall not modify the structure to which the return value of `readdir()` points, nor any storage areas -pointed to by pointers within the structure. The returned pointer, and pointers within the structure, might be invalidated or the -structure or the storage areas might be overwritten by a subsequent call to `readdir()` on the same directory stream. They -shall not be affected by a call to `readdir()` on a different directory stream. The returned pointer, and pointers within the -structure, might also be invalidated if the calling thread is terminated. +pointed to by pointers within the structure. The returned pointer, and pointers within the structure, might be +invalidated or the structure or the storage areas might be overwritten by a subsequent call to `readdir()` on the +same directory stream. They shall not be affected by a call to `readdir()` on a different directory stream. The +returned pointer, and pointers within the structure, might also be invalidated if the calling thread is terminated. -If a file is removed from or added to the directory after the most recent call to `opendir()` or `rewinddir()`, whether a -subsequent call to `readdir()` returns an entry for that file is unspecified. +If a file is removed from or added to the directory after the most recent call to `opendir()` or `rewinddir()`, whether +a subsequent call to `readdir()` returns an entry for that file is unspecified. The `readdir()` function may buffer several directory entries per actual read operation; `readdir()` shall mark for update the last data access timestamp of the directory each time the directory is actually read. -After a call to `fork()`, either the parent or child (but not both) may continue -processing the directory stream using `readdir()`, `rewinddir()`,  or `seekdir()`. If both the -parent and child processes use these functions, the result is undefined. +After a call to `fork()`, either the parent or child (but not both) may continue processing the directory stream using +`readdir()`, `rewinddir()`,  or `seekdir()`. If both the parent and child processes use these functions, the result +is undefined. The `readdir()` function need not be thread-safe. -Applications wishing to check for error situations should set `errno` to 0 before calling `readdir()`. If `errno` -is set to non-zero on return, an error occurred. +Applications wishing to check for error situations should set `errno` to 0 before calling `readdir()`. If `errno` is +set to non-zero on return, an error occurred. -The ``readdir_r()`` function shall initialize the _dirent_ structure referenced by _entry_ to represent the -directory entry at the current position in the directory stream referred to by _dirp_, store a pointer to this structure at -the location referenced by _result_, and position the directory stream at the next entry. +The ``readdir_r()`` function shall initialize the _dirent_ structure referenced by _entry_ to represent the directory +entry at the current position in the directory stream referred to by _dirp_, store a pointer to this structure at the +location referenced by _result_, and position the directory stream at the next entry. -The storage pointed to by _entry_ shall be large enough for a _dirent_ with an array of char `d_name` -members containing at least ``NAME_MAX`+1` elements. +The storage pointed to by _entry_ shall be large enough for a _dirent_ with an array of char `d_name` members containing +at least ``NAME_MAX`+1` elements. Upon successful return, the pointer returned at _*result_ shall have the same value as the argument _entry_. Upon reaching the end of the directory stream, this pointer shall have the value `NULL`. The ``readdir_r()`` function shall not return directory entries containing empty names. -If a file is removed from or added to the directory after the most recent call to `opendir()` or `rewinddir()`, whether a -subsequent call to ``readdir_r()`` returns an entry for that file is unspecified. +If a file is removed from or added to the directory after the most recent call to `opendir()` or `rewinddir()`, whether +a subsequent call to ``readdir_r()`` returns an entry for that file is unspecified. The ``readdir_r()`` function may buffer several directory entries per actual read operation; ``readdir_r()`` shall mark for update the last data access timestamp of the directory each time the directory is actually read. - ## Return value - Upon successful completion, `readdir()` shall return a pointer to an object of type `struct dirent`. When an error is -encountered, a `null` pointer shall be returned and `errno` shall be set to indicate the error. When the end of the directory is -encountered, a `null` pointer shall be returned and `errno` is not changed. +encountered, a `null` pointer shall be returned and `errno` shall be set to indicate the error. When the end of the +directory is encountered, a `null` pointer shall be returned and `errno` is not changed. + If successful, the `readdir_r()` function shall return zero; otherwise, an error number shall be returned to indicate the error. - ## Errors - These functions shall fail if: - - * `EOVERFLOW` - One of the values in the structure to be returned cannot be represented correctly. - +* `EOVERFLOW` - One of the values in the structure to be returned cannot be represented correctly. These functions may fail if: - * `EBADF` - The _dirp_ argument does not refer to an open directory stream. - - * `ENOENT` - The current position of the directory stream is invalid. +* `EBADF` - The _dirp_ argument does not refer to an open directory stream. +* `ENOENT` - The current position of the directory stream is invalid. ## Tests @@ -101,6 +99,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/r/realloc.part-impl.md b/libc/functions/r/realloc.part-impl.md index c6e0a0d6..11912db1 100644 --- a/libc/functions/r/realloc.part-impl.md +++ b/libc/functions/r/realloc.part-impl.md @@ -1,67 +1,60 @@ -# Synopsis -`#include `
+# Synopsis -` void *realloc(void *ptr, size_t size);`
+`#include ` + +`void *realloc(void *ptr, size_t size);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `realloc()` function shall deallocate the old object pointed to by _ptr_ and return a pointer to a new object that has the size specified by _size_. The contents of the new object shall be the same as that of the old object prior to -deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object have -indeterminate values. If the _size_ of the space requested is zero, the behavior shall be implementation-defined: either a `null` -pointer is returned, or the behavior shall be as if the size were some non-zero value, except that the behavior is undefined if the -returned pointer is used to access an object. If the space cannot be allocated, the object shall remain unchanged. +deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object +have indeterminate values. If the _size_ of the space requested is zero, the behavior shall be implementation-defined: +either a `null` pointer is returned, or the behavior shall be as if the size were some non-zero value, except that the +behavior is undefined if the returned pointer is used to access an object. If the space cannot be allocated, the object +shall remain unchanged. -If _ptr_ is a `null` pointer, `realloc()` shall be equivalent to `malloc()` -for the specified _size_. +If _ptr_ is a `null` pointer, `realloc()` shall be equivalent to `malloc()` for the specified _size_. -If _ptr_ does not match a pointer returned earlier by `calloc()`, `malloc()`, or `realloc()` or if the space has previously been deallocated by a call to `free()` or `realloc()`, the behavior is undefined. +If _ptr_ does not match a pointer returned earlier by `calloc()`, `malloc()`, or `realloc()` or if the space has +previously been deallocated by a call to `free()` or `realloc()`, the behavior is undefined. The order and contiguity of storage allocated by successive calls to `realloc()` is unspecified. The pointer returned if -the allocation succeeds shall be suitably aligned so that it may be assigned to a pointer to any type of object and then used to -access such an object in the space allocated (until the space is explicitly freed or reallocated). Each such allocation shall yield -a pointer to an object disjoint from any other object. The pointer returned shall point to the start (lowest byte address) of the -allocated space. If the space cannot be allocated, a `null` pointer shall be returned. - +the allocation succeeds shall be suitably aligned so that it may be assigned to a pointer to any type of object and then +used to access such an object in the space allocated (until the space is explicitly freed or reallocated). Each such +allocation shall yield a pointer to an object disjoint from any other object. The pointer returned shall point to the +start (lowest byte address) of the allocated space. If the space cannot be allocated, a `null` +pointer shall be returned. ## Return value +Upon successful completion, `realloc()` shall return a pointer to the (possibly moved) allocated space. If size is `0`, +either: -Upon successful completion, `realloc()` shall return a pointer to the (possibly moved) allocated space. If size is -`0`, either: - - - -* A `null` pointer shall be returned  and, if _ptr_ is not a `null` pointer, errno shall be set to an implementation-defined value. - - - - - -* A pointer to the allocated space shall be returned, and the memory object pointed to by _ptr_ shall be freed. The application shall ensure that the pointer is not used to access an object. - - +* A `null` pointer shall be returned  and, if _ptr_ is not a `null` pointer, errno shall be set to an +implementation-defined value. +* A pointer to the allocated space shall be returned, and the memory object pointed to by _ptr_ shall be freed. +The application shall ensure that the pointer is not used to access an object. If there is not enough available memory, `realloc()` shall return a `null` pointer  and set errno to `ENOMEM`.  If `realloc()` returns a `null` pointer  and `errno` has been set to `ENOMEM`,  the memory referenced by _ptr_ shall not be changed. - ## Errors - The `realloc()` function shall fail if: - - * `ENOMEM` - Insufficient memory is available. - +* `ENOMEM` - Insufficient memory is available. ## Tests @@ -71,6 +64,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/r/remove.part-impl.md b/libc/functions/r/remove.part-impl.md index 1c72b9a7..16b0a781 100644 --- a/libc/functions/r/remove.part-impl.md +++ b/libc/functions/r/remove.part-impl.md @@ -1,35 +1,32 @@ -# Synopsis -`#include `
+# Synopsis -` int remove(const char *path);`
+`#include ` + +`int remove(const char *path);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `remove()` function shall cause the file named by the pathname pointed to by _path_ to be no longer accessible by -that name. A subsequent attempt to open that file using that name shall fail, unless it is created anew. - -If _path_ does not name a directory, `remove(path)` shall be equivalent to `unlink(path)`. - -If _path_ names a directory, `remove(path)` shall be equivalent to `rmdir(path)`. +that name. A subsequent attempt to open that file using that name shall fail, unless it is created a new. +* If _path_ does not name a directory, `remove(path)` shall be equivalent to `unlink(path)`. +* If _path_ names a directory, `remove(path)` shall be equivalent to `rmdir(path)`. ## Return value - -Refer to `rmdir()` or `unlink()`. - +Refer to `rmdir()` or `unlink()`. ## Errors - - -Refer to `rmdir()` or `unlink()`. - +Refer to `rmdir()` or `unlink()`. ## Tests @@ -39,6 +36,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/r/rename.part-impl.md b/libc/functions/r/rename.part-impl.md index 33a0f882..fd280559 100644 --- a/libc/functions/r/rename.part-impl.md +++ b/libc/functions/r/rename.part-impl.md @@ -1,168 +1,161 @@ -# Synopsis -`#include `
+# Synopsis -` int rename(const char *old, const char *new);`
+`#include ` -`#include `
+`int rename(const char *old, const char *new);` -`int renameat(int oldfd, const char *old, int newfd, const char *new); `
+`#include ` + +`int renameat(int oldfd, const char *old, int newfd, const char *new);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description The `rename()` function shall change the name of a file. The _old_ argument points to the pathname of the file to be -renamed. The _new_ argument points to the new pathname of the file. -If the _new_ argument does not resolve to an -existing directory entry for a file of type directory and the new argument contains at least one non- ```` -character and ends with one or more trailing ```` characters after all symbolic links have been processed, `rename()` -shall fail. - -If either the _old_ or _new_ argument names a symbolic link, `rename()` shall operate on the symbolic link -itself, and shall not resolve the last component of the argument. If the _old_ argument and the _new_ argument resolve to -either the same existing directory entry or different directory entries for the same existing file, `rename()` shall return -successfully and perform no other action. - -If the _old_ argument points to the pathname of a file that is not a directory, the _new_ argument shall not point to -the pathname of a directory. If the link named by the _new_ argument exists, it shall be removed and _old_ renamed to -_new_. In this case, a link named _new_ shall remain visible to other threads throughout the renaming operation and refer -either to the file referred to by _new_ or _old_ before the operation began. Write access permission is required for both -the directory containing _old_ and the directory containing _new_. +renamed. The _new_ argument points to the new pathname of the file. If the _new_ argument does not resolve to an +existing directory entry for a file of type directory and the new argument contains at least one non- `` +character and ends with one or more trailing ```` characters after all symbolic links have been processed, +`rename()`shall fail. + +If either the _old_ or _new_ argument names a symbolic link, `rename()` shall operate on the symbolic link itself, +and shall not resolve the last component of the argument. If the _old_ argument and the _new_ argument resolve to +either the same existing directory entry or different directory entries for the same existing file, `rename()` +shall return successfully and perform no other action. + +If the _old_ argument points to the pathname of a file that is not a directory, the _new_ argument shall not point +to the pathname of a directory. If the link named by the _new_ argument exists, it shall be removed and _old_ renamed +to _new_. In this case, a link named _new_ shall remain visible to other threads throughout the renaming operation and +refer either to the file referred to by _new_ or _old_ before the operation began. Write access permission is required +for both the directory containing _old_ and the directory containing _new_. If the _old_ argument points to the pathname of a directory, the _new_ argument shall not point to the pathname of a file that is not a directory. If the directory named by the _new_ argument exists, it shall be removed and _old_ renamed to _new_. In this case, a link named _new_ shall exist throughout the renaming operation and shall refer either to the -directory referred to by _new_ or _old_ before the operation began. If _new_ names an existing directory, it shall -be required to be an empty directory. +directory referred to by _new_ or _old_ before the operation began. If _new_ names an existing directory, it shall be +required to be an empty directory. -If either pathname argument refers to a path whose final component is either dot or dot-dot, `rename()` shall -fail. +If either pathname argument refers to a path whose final component is either dot or dot-dot, `rename()` shall fail. -If the _old_ argument points to a pathname of a symbolic link, the symbolic link shall be renamed. If the _new_ -argument points to a pathname of a symbolic link, the symbolic link shall be removed. +If the _old_ argument points to a pathname of a symbolic link, the symbolic link shall be renamed. If the _new_ argument +points to a pathname of a symbolic link, the symbolic link shall be removed. The _old_ pathname shall not name an ancestor directory of the _new_ pathname. Write access permission is required for the directory containing _old_ and the directory containing _new_. If the _old_ argument points to the pathname of a -directory, write access permission may be required for the directory named by _old_, and, if it exists, the directory named by -_new_. +directory, write access permission may be required for the directory named by _old_, and, if it exists, the directory +named by _new_. -If the link named by the _new_ argument exists and the file's link count becomes `0` when it is removed and no process has -the file open, the space occupied by the file shall be freed and the file shall no longer be accessible. If one or more processes -have the file open when the last link is removed, the link shall be removed before `rename()` returns, but the removal of the -file contents shall be postponed until all references to the file are closed. +If the link named by the _new_ argument exists and the file's link count becomes `0` when it is removed and no process +has the file open, the space occupied by the file shall be freed and the file shall no longer be accessible. If one or +more processes have the file open when the last link is removed, the link shall be removed before `rename()` returns, +but the removal of the file contents shall be postponed until all references to the file are closed. Upon successful completion, `rename()` shall mark for update the last data modification and last file status change timestamps of the parent directory of each file. If the `rename()` function fails for any reason other than `EIO`, any file named by _new_ shall be unaffected. -The `renameat()` function shall be equivalent to the `rename()` function except in the case where either _old_ or -_new_ specifies a relative path. If _old_ is a relative path, the file to be renamed is located relative to the directory +The `renameat()` function shall be equivalent to the `rename()` function except in the case where either _old_ or _new_ +specifies a relative path. If _old_ is a relative path, the file to be renamed is located relative to the directory associated with the file descriptor _oldfd_ instead of the current working directory. If _new_ is a relative path, the same happens only relative to the directory associated with _newfd_. If the access mode of the open file description -associated with the file descriptor is not `O_SEARCH,` the function shall check whether directory searches are permitted using the -current permissions of the directory underlying the file descriptor. If the access mode is `O_SEARCH,` the function shall not perform -the check. +associated with the file descriptor is not `O_SEARCH,` the function shall check whether directory searches are permitted +using the current permissions of the directory underlying the file descriptor. If the access mode is `O_SEARCH,` the +function shall not perform the check. If `renameat()` is passed the special value `AT_FDCWD` in the _oldfd_ or _newfd_ parameter, the current working -directory shall be used in the determination of the file for the respective path parameter. - +directory shall be used in the determination of the file for the respective path parameter. ## Return value +Upon successful completion, the `rename()` function shall return `0`. Otherwise, it shall return `-1`, errno shall be +set to indicate the error,  and neither the file named by _old_ nor the file named by _new_ shall be changed or +created. -Upon successful completion, the `rename()` function shall return `0`. Otherwise, it shall return `-1`, errno shall -be set to indicate the error,  and neither the file named by -_old_ nor the file named by _new_ shall be changed or created. Upon successful completion, the `renameat()` function shall return `0`. Otherwise, it shall return `-1` and set errno to -indicate the error. - +indicate the error. ## Errors +The `rename()`  and `renameat()` functions shall fail if: -The `rename()`  and `renameat()` - functions shall fail if: +* `EACCES` - A component of either path prefix denies search permission; or one of the directories containing _old_ + or _new_ denies write permissions; or, write permission is required and is denied for a directory pointed to by the + _old_ or _new_ arguments. +* `EBUSY` - The directory named by _old_ or _new_ is currently in use by the system or another process, and the + implementation considers this an error. - * `EACCES` - A component of either path prefix denies search permission; or one of the directories containing _old_ or _new_ denies -write permissions; or, write permission is required and is denied for a directory pointed to by the _old_ or _new_ -arguments. +* `EEXIST` or `ENOTEMPTY` - The link named by _new_ is a directory that is not an empty directory. - * `EBUSY` - The directory named by _old_ or _new_ is currently in use by the system or another process, and the implementation -considers this an error. -`EEXIST` or `ENOTEMPTY` - -The link named by _new_ is a directory that is not an empty directory. +* `EINVAL` - The _old_ pathname names an ancestor directory of the _new_ pathname, or either pathname argument + contains a final component that is dot or dot-dot. - * `EINVAL` - The _old_ pathname names an ancestor directory of the _new_ pathname, or either pathname argument contains a final -component that is dot or dot-dot. +* `EIO` - A physical I/O error has occurred. - * `EIO` - A physical I/O error has occurred. +* `EISDIR` - The _new_ argument points to a directory and the _old_ argument points to a file that is not a directory. - * `EISDIR` - The _new_ argument points to a directory and the _old_ argument points to a file that is not a directory. +* `ELOOP` - A loop exists in symbolic links encountered during resolution of the path argument. - * `ELOOP` - A loop exists in symbolic links encountered during resolution of the path argument. +* `EMLINK` - The file named by _old_ is a directory, and the link count of the parent directory of _new_ would exceed + `LINK_MAX`. - * `EMLINK` - The file named by _old_ is a directory, and the link count of the parent directory of _new_ would exceed `LINK_MAX`. +* `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. - * `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. +* `ENOENT` - The link named by _old_ does not name an existing file, a component of the path prefix of _new_ does not + exist, or either _old_ or _new_ points to an empty string. - * `ENOENT` - The link named by _old_ does not name an existing file, a component of the path prefix of _new_ does not exist, or either -_old_ or _new_ points to an empty string. +* `ENOSPC` - The directory that would contain _new_ cannot be extended. - * `ENOSPC` - The directory that would contain _new_ cannot be extended. +* `ENOTDIR` - A component of either path prefix names an existing file that is neither a directory nor a symbolic + link to a directory; or the _old_ argument names a directory and the _new_ argument names a non-directory file; or the + _old_ argument contains at least one non- `` character and ends with one or more trailing `` characters + and the last pathname component names an existing file that is neither a directory nor a symbolic link to a directory; + or the _old_ argument names an existing non-directory file and the _new_ argument names a nonexistent file, contains at + least one non- `` character, and ends with one or more trailing `` characters; or the _new_ argument + names an existing non-directory file, contains at least one non- `` character, and ends with one or more + trailing `` characters. - * `ENOTDIR` - A component of either path prefix names an existing file that is neither a directory nor a symbolic link to a directory; or the -_old_ argument names a directory and the _new_ argument names a non-directory file; or the _old_ argument contains -at least one non- `` character and ends with one or more trailing `` characters and the last pathname -component names an existing file that is neither a directory nor a symbolic link to a directory; or the _old_ argument names -an existing non-directory file and the _new_ argument names a nonexistent file, contains at least one non- `` -character, and ends with one or more trailing `` characters; or the _new_ argument names an existing non-directory -file, contains at least one non- `` character, and ends with one or more trailing `` characters. -`EPERM` or `EACCES` -The S_ISVTX flag is set on the directory containing the file referred to by _old_ and the process does not satisfy the -criteria specified in XBD Directory Protection with respect to -old; or _new_ refers to an existing file, the S_ISVTX flag is set on the directory containing this file, and the -process does not satisfy the criteria specified in XBD Directory -Protection with respect to this file. +* `EPERM` or `EACCES` - The S_ISVTX flag is set on the directory containing the file referred to by _old_ and the + process does not satisfy the criteria specified in XBD Directory Protection with respect to old; or _new_ refers to + an existing file, the S_ISVTX flag is set on the directory containing this file, and the process does not satisfy the + criteria specified in XBD Directory Protection with respect to this file. - * `EROFS` - The requested operation requires writing in a directory on a read-only file system. +* `EROFS` - The requested operation requires writing in a directory on a read-only file system. - * `EXDEV` - The links named by _new_ and _old_ are on different file systems and the implementation does not support links between -file systems. +* `EXDEV` - The links named by _new_ and _old_ are on different file systems and the implementation does not support + links between file systems. In addition, the `renameat()` function shall fail if: +* `EACCES` - The access mode of the open file description associated with _oldfd_ or _newfd_ is not O_SEARCH and the + permissions of the directory underlying _oldfd_ or _newfd_, respectively, do not permit directory searches. - * `EACCES` - The access mode of the open file description associated with _oldfd_ or _newfd_ is not O_SEARCH and the permissions -of the directory underlying _oldfd_ or _newfd_, respectively, do not permit directory searches. +* `EBADF` - The _old_ argument does not specify an absolute path and the _oldfd_ argument is neither AT_FDCWD nor a + valid file descriptor open for reading or searching, or the _new_ argument does not specify an absolute path and the + _newfd_ argument is neither AT_FDCWD nor a valid file descriptor open for reading or searching. - * `EBADF` - The _old_ argument does not specify an absolute path and the _oldfd_ argument is neither AT_FDCWD nor a valid file -descriptor open for reading or searching, or the _new_ argument does not specify an absolute path and the _newfd_ -argument is neither AT_FDCWD nor a valid file descriptor open for reading or searching. +* `ENOTDIR` - The _old_ or _new_ argument is not an absolute path and _oldfd_ or _newfd_, respectively, is a file + descriptor associated with a non-directory file. - * `ENOTDIR` - The _old_ or _new_ argument is not an absolute path and _oldfd_ or _newfd_, respectively, is a file -descriptor associated with a non-directory file. - - -The `rename()`  and `renameat()` +The `rename()`  and `renameat()`  functions may fail if: +* `EBUSY` - The file named by the _old_ or _new_ arguments is a named STREAM. - * `EBUSY` - The file named by the _old_ or _new_ arguments is a named STREAM. - - * `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the path argument. - - * `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an intermediate result with a -length that exceeds `PATH_MAX`. - - * `ETXTBSY` - The file named by _new_ exists and is the last directory entry to a pure procedure (shared text) file that is being executed. - +* `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the path argument. +* `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an + intermediate result with a length that exceeds `PATH_MAX`. +* `ETXTBSY` - The file named by _new_ exists and is the last directory entry to a pure procedure (shared text) file + that is being executed. The following sections are informative. @@ -174,6 +167,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/r/rewind.part-impl.md b/libc/functions/r/rewind.part-impl.md index d7f47917..092f2abd 100644 --- a/libc/functions/r/rewind.part-impl.md +++ b/libc/functions/r/rewind.part-impl.md @@ -1,17 +1,22 @@ -# Synopsis -`#include `
+# Synopsis -` void rewind(FILE *stream);`
+`#include ` + +`void rewind(FILE *stream);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 + ## Description `rewind()` - reset the file position indicator in a stream -The call: +The call: `rewind(stream)` @@ -22,18 +27,15 @@ shall be equivalent to: except that `rewind()` shall also clear the error indicator. Since `rewind()` does not return a value, an application wishing to detect errors should clear `errno`, then call -`rewind()`, and if `errno` is non-zero, assume an error has occurred. - +`rewind()`, and if `errno` is non-zero, assume an error has occurred. ## Return value - The `rewind()` function shall not return a value. - ## Errors -Refer to `fseek()` with the exception of `EINVAL` which does not apply. +Refer to `fseek()` with the exception of `EINVAL` which does not apply. ## Tests @@ -43,6 +45,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/functions/r/rmdir.part-impl.md b/libc/functions/r/rmdir.part-impl.md index 2cb3271b..38091452 100644 --- a/libc/functions/r/rmdir.part-impl.md +++ b/libc/functions/r/rmdir.part-impl.md @@ -1,79 +1,83 @@ -# Synopsis -`#include `
+# Synopsis -`int rmdir(const char *path);`
+`#include ` + +`int rmdir(const char *path);` ## Status + Partially implemented + ## Conformance + IEEE Std 1003.1-2017 -## Description +## Description The `rmdir()` function shall remove a directory whose name is given by _path_. The directory shall be removed only if it is an empty directory. -If the directory is the root directory or the current working directory of any process, it is unspecified whether the function -succeeds, or whether it shall fail and set errno to `EBUSY`. +If the directory is the root directory or the current working directory of any process, it is unspecified whether the +function succeeds, or whether it shall fail and set errno to `EBUSY`. If _path_ names a symbolic link, then `rmdir()` shall fail and set errno to `ENOTDIR`. If the _path_ argument refers to a path whose final component is either `dot` or `dot-dot`, `rmdir()` shall fail. -If the directory's link count becomes `0` and no process has the directory open, the space occupied by the directory shall be -freed and the directory shall no longer be accessible. If one or more processes have the directory open when the last link is -removed, the dot and dot-dot entries, if present, shall be removed before `rmdir()` returns and no new entries may be created -in the directory, but the directory shall not be removed until all references to the directory are closed. +If the directory's link count becomes `0` and no process has the directory open, the space occupied by the directory +shall be freed and the directory shall no longer be accessible. If one or more processes have the directory open when +the last link is removed, the dot and dot-dot entries, if present, shall be removed before `rmdir()` returns and no new +entries may be created in the directory, but the directory shall not be removed until all references to the directory +are closed. If the directory is not an empty directory, `rmdir()` shall fail and set errno to `EEXIST` or `ENOTEMPTY`. Upon successful completion, `rmdir()` shall mark for update the last data modification and last file status change timestamps of the parent directory. - ## Return value - -Upon successful completion, the function `rmdir()` shall return `0`. Otherwise, `-1` shall be returned, and `errno` set to -indicate the error. If `-1` is returned, the named directory shall not be changed. - +Upon successful completion, the function `rmdir()` shall return `0`. Otherwise, `-1` shall be returned, and `errno` set +to indicate the error. If `-1` is returned, the named directory shall not be changed. ## Errors - The `rmdir()` function shall fail if: +* `EACCES` - Search permission is denied on a component of the _path_ prefix, or write permission is denied on the + parent directory of the directory to be removed. - * `EACCES` - Search permission is denied on a component of the _path_ prefix, or write permission is denied on the parent directory of the directory to be removed. - - * `EBUSY` - The directory to be removed is currently in use by the system or some process and the implementation considers this to be an error. - - * `EEXIST` or `ENOTEMPTY` - The _path_ argument names a directory that is not an empty directory, or there are hard links to the directory other than dot or a single entry in dot-dot. +* `EBUSY` - The directory to be removed is currently in use by the system or some process and the implementation + considers this to be an error. - * `EINVAL` - The _path_ argument contains a last component that is dot. +* `EEXIST` or `ENOTEMPTY` - The _path_ argument names a directory that is not an empty directory, or there are hard +links to the directory other than dot or a single entry in dot-dot. - * `EIO` - A physical I/O error has occurred. +* `EINVAL` - The _path_ argument contains a last component that is dot. - * `ELOOP` - A loop exists in symbolic links encountered during resolution of the _path_ argument. +* `EIO` - A physical I/O error has occurred. - * `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. +* `ELOOP` - A loop exists in symbolic links encountered during resolution of the _path_ argument. - * `ENOENT` - A component of _path_ does not name an existing file, or the path argument names a nonexistent directory or pointsto an empty string. +* `ENAMETOOLONG` - The length of a component of a pathname is longer than `NAME_MAX`. - * `ENOTDIR` - A component of _path_ names an existing file that is neither a directory nor a symbolic link to a directory. +* `ENOENT` - A component of _path_ does not name an existing file, or the path argument names a nonexistent directory or +pointsto an empty string. - * `EPERM` or `EACCES` - The `S_ISVTX` flag is set on the directory containing the file referred to by the _path_ argument and the process does not satisfy the criteria specified in XBD Directory Protection. +* `ENOTDIR` - A component of _path_ names an existing file that is neither a directory nor a symbolic link to a +directory. - * `EROFS` - The directory entry to be removed resides on a read-only file system. +* `EPERM` or `EACCES` - The `S_ISVTX` flag is set on the directory containing the file referred to by the _path_ +argument and the process does not satisfy the criteria specified in XBD Directory Protection. +* `EROFS` - The directory entry to be removed resides on a read-only file system. The `rmdir()` function may fail if: +* `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the _path_ argument. - * `ELOOP` - More than `SYMLOOP_MAX` symbolic links were encountered during resolution of the _path_ argument. - - * `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an intermediate result with a length that exceeds `PATH_MAX`. - +* `ENAMETOOLONG` - The length of a pathname exceeds `PATH_MAX`, or pathname resolution of a symbolic link produced an +intermediate result with a length that exceeds `PATH_MAX`. ## Tests @@ -83,6 +87,7 @@ Untested None -## See Also +## See Also + 1. [Standard library functions](../README.md) 2. [Table of Contents](../../../README.md) diff --git a/libc/posix.md b/libc/posix.md index b938d52e..56e7568d 100644 --- a/libc/posix.md +++ b/libc/posix.md @@ -1,16 +1,19 @@ # POSIX emulation -The `libphoenix` repository provides POSIX API enabling users to build and run portable POSIX applications. The emulation layer is built upon Phoenix-RTOS native messaging API and a dedicated server (`posixsrv`). +The `libphoenix` repository provides POSIX API enabling users to build and run portable POSIX applications. The +emulation layer is built upon Phoenix-RTOS native messaging API and a dedicated server (`posixsrv`). The purpose of `posixsrv` is to store data that can be shared between processes, i.e.: - - keep track of file descriptors and their mapping to open files, - - manage standard IPC mechanisms: pipes, UNIX sockets, - - provide UNIX 98 pseudoterminals, - - dispatch events for efficient `poll()`-like functions + +- keep track of file descriptors and their mapping to open files, +- manage standard IPC mechanisms: pipes, UNIX sockets, +- provide UNIX 98 pseudoterminals, +- dispatch events for efficient `poll()`-like functions It also registers and handles special files, such as `/dev/null` or `/dev/random`. -In the current implementation some parts of `posixsrv` functionality is kept inside the kernel and accessed using a set of system calls. Future implementations will instead delegate requests directly to `posixsrv`. +In the current implementation some parts of `posixsrv` functionality is kept inside the kernel and accessed using a set +of system calls. Future implementations will instead delegate requests directly to `posixsrv`. ## Source code @@ -23,4 +26,4 @@ git clone https://github.com/phoenix-rtos/phoenix-rtos-posixsrv ## See also 1. [Standard library functions](functions/README.md) -2. [Table of Contents](../README.md) \ No newline at end of file +2. [Table of Contents](../README.md)