A controlled privilege boundary
Operating systems must let programs execute efficiently while retaining control over protected resources. Applications ordinarily run in restricted user mode; the kernel handles privileged operations in kernel mode. Exposing services such as file access does not give the caller unrestricted permission to execute privileged instructions.
Entry must follow paths established by the kernel rather than arbitrary addresses selected by an application. The kernel must still check arguments, addresses and access conditions. A hardware-supported mode transition alone does not make an interface secure if the subsequent handling trusts invalid user input. System calls therefore combine a service interface with part of the system's protection boundary.
References: [1]
From wrapper to kernel
Applications commonly invoke a C-library wrapper. It prepares a system-call number and arguments according to the platform's conventions, placing them in designated registers or other agreed locations, then executes the instruction that enters the kernel. Hardware and kernel code preserve the necessary execution state, dispatch the request and perform the work. A returning call eventually passes its result back to user code.
Instructions, numbering and register conventions differ across architectures. Linux wrappers also translate low-level error representations into the application's return value and errno conventions. A particular register layout or negative-error encoding should therefore not be mistaken for a universal rule covering every operating system.
Results are part of the contract
Linux read provides a concrete example. Its arguments identify a file descriptor, a destination buffer and a maximum byte count. Success returns the number actually read, which may be smaller than requested without indicating an error. For a nonzero-length read on an ordinary file, zero signals end of file.
On failure the wrapper returns −1 and sets errno. Examples include EBADF for an invalid descriptor and EFAULT for an inaccessible buffer address. Nonblocking operations may report EAGAIN when they cannot proceed immediately. Signal interruption has additional rules.
Suppose a program requests 100 bytes but receives 40 near the end of a file. Those 40 bytes are still a successful result, not automatically a failed operation. The caller must interpret the count and decide what its own higher-level task requires next. Correct handling distinguishes partial progress from failure rather than assuming every request is completed in full.
References: [3]
Library calls are a different layer
A wrapper's name often matches the Linux system call it invokes, but not always; it may also select among kernel interfaces or perform additional processing. Higher-level standard I/O instead exposes buffered FILE streams and conceals lower-level I/O details.
A library operation can consume data already buffered in user space or retain output until it is flushed. Consequently, a high-level input or output call is not necessarily one kernel entry. Understanding the distinction helps explain delayed visible output and prevents library stream state from being confused with system-call results or the underlying resource. A system call names the boundary for requesting kernel service, not every function a program executes.