tools/include/nolibc/sys.h

Source file repositories/reference/linux-study-clean/tools/include/nolibc/sys.h

File Facts

System
Linux kernel
Corpus path
tools/include/nolibc/sys.h
Extension
.h
Size
17869 bytes
Lines
946
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

#include "nolibc.h"

#ifndef _NOLIBC_SYS_H
#define _NOLIBC_SYS_H

#include "std.h"

/* system includes */
#include <linux/unistd.h>
#include <linux/signal.h>  /* for SIGCHLD */
#include <linux/termios.h>
#include <linux/mman.h>
#include <linux/fs.h>
#include <linux/loop.h>
#include <linux/time.h>
#include <linux/auxvec.h>
#include <linux/fcntl.h> /* for O_* and AT_* */
#include <linux/sched.h> /* for CLONE_* */
#include <linux/stat.h>  /* for statx() */

#include "errno.h"
#include "stdarg.h"
#include "types.h"


/* Syscall return helper: takes the syscall value in argument and checks for an
 * error in it. This may only be used with signed returns (int or long), but
 * not with pointers. An error is any value < 0. When an error is encountered,
 * -ret is set into errno and -1 is returned. Otherwise the returned value is
 * passed as-is with its type preserved.
 */

#define __sysret(arg)							\
({									\
	__typeof__(arg) __sysret_arg = (arg);				\
	(__sysret_arg < 0)                              /* error ? */	\
		? (({ SET_ERRNO(-__sysret_arg); }), -1) /* ret -1 with errno = -arg */ \
		: __sysret_arg;                         /* return original value */ \
})

/* Syscall ENOSYS helper: Avoids unused-parameter warnings, provides compile
 * time validation and a debugging hook.
 */

#if defined(NOLIBC_COMPILE_TIME_ENOSYS)
static __inline__ int __nolibc_enosys(const char *syscall, ...)
{
	(void)syscall;
	return -ENOSYS;
}

#elif __nolibc_has_attribute(error)
__attribute__((error("system call not implemented")))
extern int __nolibc_enosys(const char *syscall, ...);

#else
static __inline__ int __nolibc_enosys(const char *syscall, ...)
{
	extern int __nolibc_enosys_error;
	(void)syscall;

	return __nolibc_enosys_error;
}
#endif


/*
 * Helper for 32-bit machines where a 64-bit syscall arg needs to be split into
 * two 32-bit parts while making sure the order of the low/high parts are correct
 * for the endianness:
 * __NOLIBC_LLARGPART(x, 0), __NOLIBC_LLARGPART(x, 1)
 */
#define __NOLIBC_LLARGPART(_arg, _part) \
	(((union { long long ll; long l[2]; }) { .ll = _arg }).l[_part])


/* Functions in this file only describe syscalls. They're declared static so
 * that the compiler usually decides to inline them while still being allowed
 * to pass a pointer to one of their instances. Each syscall exists in two
 * versions:
 *   - the "internal" ones, which matches the raw syscall interface at the
 *     kernel level, which may sometimes slightly differ from the documented
 *     libc-level ones. For example most of them return either a valid value
 *     or -errno. All of these are prefixed with "_sys_". They may be called
 *     by non-portable applications if desired.
 *
 *   - the "exported" ones, whose interface must closely match the one
 *     documented in man(2), that applications are supposed to expect. These
 *     ones rely on the internal ones, and set errno.
 *

Annotation

Implementation Notes