1.. _posix_details:
2
3Implementation Details
4######################
5
6In many ways, Zephyr provides support like any POSIX OS; API bindings are provided in the C
7programming language, POSIX headers are available in the standard include path, when configured.
8
9Unlike other multi-purpose POSIX operating systems
10
11- Zephyr is not "a POSIX OS". The Zephyr kernel was not designed around the POSIX standard, and
12  POSIX support is an opt-in feature
13- Zephyr apps are not linked separately, nor do they execute as subprocesses
14- Zephyr, libraries, and application code are compiled and linked together, running similarly to
15  a single-process application, in a single (possibly virtual) address space
16- Zephyr does not provide a POSIX shell, compiler, utilities, and is not self-hosting.
17
18.. note::
19   Unlike the Linux kernel or FreeBSD, Zephyr does not maintain a static table of system call
20   numbers for each supported architecture, but instead generates system calls dynamically at
21   build time. See `System Calls <syscalls>` for more information.
22
23Design
24======
25
26As a library, Zephyr's POSIX API implementation makes an effort to be a thin abstraction layer
27between the application, middleware, and the Zephyr kernel.
28
29Some general design considerations:
30
31- The POSIX interface and implementations should be part of Zephyr's POSIX library, and not
32  elsewhere, unless required both by the POSIX API implementation and some other feature. An
33  example where the implementation should remain part of the POSIX implementation is
34  ``getopt()``. Examples where the implementation should be part of separate libraries are
35  multithreading and networking.
36
37- When the POSIX API and another Zephyr subsystem both rely on a feature, the implementation of
38  that feature should be as a separate Zephyr library that can be used by both the POSIX API and
39  the other library or subsystem. This reduces the likelihood of dependency cycles in code. When
40  practical, that rule should expand to include macros. In the example below, ``libposix``
41  depends on ``libzfoo`` for the implementation of some functionality "foo" in Zephyr. If
42  ``libzfoo`` also depends on ``libposix``, then there is a dependency cycle. The cycle can be
43  removed via mutual dependency, ``libcommon``.
44
45.. graphviz::
46   :caption: Dependency cycle between POSIX and another Zephyr library
47
48   digraph {
49       node [shape=rect, style=rounded];
50       rankdir=LR;
51
52       libposix [fillcolor="#d5e8d4"];
53       libzfoo [fillcolor="#dae8fc"];
54
55       libposix -> libzfoo;
56       libzfoo -> libposix;
57   }
58
59.. graphviz::
60   :caption: Mutual dependencies between POSIX and other Zephyr libraries
61
62   digraph {
63       node [shape=rect, style=rounded];
64       rankdir=LR;
65
66       libposix [fillcolor="#d5e8d4"];
67       libzfoo [fillcolor="#dae8fc"];
68       libcommon [fillcolor="#f8cecc"];
69
70       libposix -> libzfoo;
71       libposix -> libcommon;
72       libzfoo -> libcommon;
73   }
74
75- POSIX API calls should be provided as regular callable C functions; if a Zephyr
76  `System Call <syscalls>` is needed as part of the implementation, the declaration and the
77  implementation of that system call should be hidden behind the POSIX API.
78