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