From: Andrea Cervesato <andrea.cervesato@suse.de>
To: Linux Test Project <ltp@lists.linux.it>
Subject: [LTP] [PATCH v3 3/3] doc: Add SAFE_* macros reference page
Date: Tue, 02 Jun 2026 17:49:28 +0200 [thread overview]
Message-ID: <20260602-doc_add_missing_headers-v3-3-474deff77d2a@suse.com> (raw)
In-Reply-To: <20260602-doc_add_missing_headers-v3-0-474deff77d2a@suse.com>
From: Andrea Cervesato <andrea.cervesato@suse.com>
Add doc/developers/api_safe_macros.rst listing all 245 SAFE_* wrapper
macros grouped by header and category (file ops, memory, process,
signals, networking, pthreads, IPC, cgroups, clocks, etc.).
This gives test writers a single reference page to discover available
safe macros without grepping headers.
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
doc/developers/api_safe_macros.rst | 382 +++++++++++++++++++++++++++++++++++++
doc/index.rst | 4 +
2 files changed, 386 insertions(+)
diff --git a/doc/developers/api_safe_macros.rst b/doc/developers/api_safe_macros.rst
new file mode 100644
index 0000000000000000000000000000000000000000..379394b2c2c5c9b7965cd95e6d602f774aa854d9
--- /dev/null
+++ b/doc/developers/api_safe_macros.rst
@@ -0,0 +1,382 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+.. Copyright (c) Linux Test Project, 2026
+
+Safe macros reference
+=====================
+
+LTP provides ``SAFE_*`` wrappers for common system calls and library
+functions. Each wrapper calls the underlying function and, on failure,
+invokes ``tst_brk(TBROK | TERRNO, ...)`` to abort the test. This
+eliminates repetitive error-checking boilerplate.
+
+**When NOT to use SAFE_\* macros:** when the syscall is the *subject*
+of the test (e.g. testing ``close()`` error paths). Use ``TEST()`` or
+``TST_EXP_*`` macros instead.
+
+Core macros (tst_safe_macros.h)
+-------------------------------
+
+File and directory operations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- ``SAFE_ACCESS(path, mode)``
+- ``SAFE_CHMOD(path, mode)``
+- ``SAFE_CHOWN(path, owner, group)``
+- ``SAFE_CHDIR(path)``
+- ``SAFE_CHROOT(path)``
+- ``SAFE_CREAT(path, mode)``
+- ``SAFE_FCHMOD(fd, mode)``
+- ``SAFE_FCHOWN(fd, owner, group)``
+- ``SAFE_GETCWD(buf, size)``
+- ``SAFE_LCHOWN(path, owner, group)``
+- ``SAFE_LINK(oldpath, newpath)``
+- ``SAFE_LINKAT(olddirfd, oldpath, newdirfd, newpath, flags)``
+- ``SAFE_MKDIR(path, mode)``
+- ``SAFE_MKFIFO(path, mode)``
+- ``SAFE_MKNOD(path, mode, dev)``
+- ``SAFE_READLINK(path, buf, bufsiz)``
+- ``SAFE_RENAME(oldpath, newpath)``
+- ``SAFE_RMDIR(path)``
+- ``SAFE_SYMLINK(target, linkpath)``
+- ``SAFE_SYMLINKAT(target, newdirfd, linkpath)``
+- ``SAFE_UNLINK(path)``
+
+File descriptor operations
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- ``SAFE_CLOSE(fd)`` — also sets ``fd = -1``
+- ``SAFE_DUP(oldfd)``
+- ``SAFE_DUP2(oldfd, newfd)``
+- ``SAFE_FCNTL(fd, cmd, ...)``
+- ``SAFE_FSYNC(fd)``
+- ``SAFE_OPEN(path, oflag, ...)``
+- ``SAFE_OPENDIR(name)``
+- ``SAFE_CLOSEDIR(dirp)``
+- ``SAFE_READDIR(dirp)``
+- ``SAFE_PIPE(pipefd)``
+- ``SAFE_PIPE2(pipefd, flags)``
+- ``SAFE_PTSNAME(fd)``
+
+Reading and writing
+~~~~~~~~~~~~~~~~~~~
+
+- ``SAFE_READ(len_strict, fd, buf, count)``
+- ``SAFE_READV(fd, iov, iovcnt)``
+- ``SAFE_WRITE(len_strict, fd, buf, count)``
+- ``SAFE_WRITEV(fd, iov, iovcnt)``
+
+Memory management
+~~~~~~~~~~~~~~~~~
+
+- ``SAFE_CALLOC(nmemb, size)``
+- ``SAFE_MALLOC(size)``
+- ``SAFE_MEMALIGN(alignment, size)``
+- ``SAFE_REALLOC(ptr, size)``
+- ``SAFE_MUNMAP(addr, length)``
+- ``SAFE_MLOCK(addr, len)``
+- ``SAFE_MUNLOCK(addr, len)``
+- ``SAFE_MPROTECT(addr, len, prot)``
+- ``SAFE_MSYNC(addr, length, flags)``
+- ``SAFE_MINCORE(addr, length, vec)``
+
+Process management
+~~~~~~~~~~~~~~~~~~
+
+- ``SAFE_EXECL(path, arg, ...)``
+- ``SAFE_EXECLP(file, arg, ...)``
+- ``SAFE_EXECVP(file, argv)``
+- ``SAFE_KILL(pid, sig)``
+- ``SAFE_WAIT(status)``
+- ``SAFE_WAITPID(pid, status, opts)``
+- ``SAFE_GETPGID(pid)``
+- ``SAFE_SETPGID(pid, pgid)``
+- ``SAFE_SETSID()``
+- ``SAFE_PRCTL(option, ...)``
+- ``SAFE_PTRACE(request, pid, addr, data)``
+- ``SAFE_PIDFD_OPEN(pid, flags)``
+
+User and group
+~~~~~~~~~~~~~~
+
+- ``SAFE_GETPWNAM(name)``
+- ``SAFE_GETGRNAM(name)``
+- ``SAFE_GETGRNAM_FALLBACK(name)``
+- ``SAFE_GETGRGID(gid)``
+- ``SAFE_GETGROUPS(size, list)``
+- ``SAFE_SETGROUPS(size, list)``
+- ``SAFE_SETUID(uid)``
+- ``SAFE_SETEUID(euid)``
+- ``SAFE_SETREUID(ruid, euid)``
+- ``SAFE_SETRESUID(ruid, euid, suid)``
+- ``SAFE_GETRESUID(ruid, euid, suid)``
+- ``SAFE_SETGID(gid)``
+- ``SAFE_SETEGID(egid)``
+- ``SAFE_SETREGID(rgid, egid)``
+- ``SAFE_SETRESGID(rgid, egid, sgid)``
+- ``SAFE_GETRESGID(rgid, egid, sgid)``
+
+Signals
+~~~~~~~
+
+- ``SAFE_SIGACTION(signum, act, oldact)``
+- ``SAFE_SIGADDSET(set, signum)``
+- ``SAFE_SIGDELSET(set, signum)``
+- ``SAFE_SIGEMPTYSET(set)``
+- ``SAFE_SIGFILLSET(set)``
+- ``SAFE_SIGNAL(signum, handler)``
+- ``SAFE_SIGPROCMASK(how, set, oldset)``
+- ``SAFE_SIGWAIT(set, sig)``
+
+Extended attributes
+~~~~~~~~~~~~~~~~~~~
+
+- ``SAFE_GETXATTR(path, name, value, size)``
+- ``SAFE_SETXATTR(path, name, value, size, flags)``
+- ``SAFE_REMOVEXATTR(path, name)``
+- ``SAFE_LSETXATTR(path, name, value, size, flags)``
+- ``SAFE_LREMOVEXATTR(path, name)``
+- ``SAFE_FSETXATTR(fd, name, value, size, flags)``
+- ``SAFE_FREMOVEXATTR(fd, name)``
+
+Mounting
+~~~~~~~~
+
+- ``SAFE_MOUNT(source, target, filesystemtype, mountflags, data)``
+- ``SAFE_MOUNT2(source, target, filesystemtype, mountflags, data)``
+- ``SAFE_UMOUNT(target)``
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+- ``SAFE_BASENAME(path)``
+- ``SAFE_CMD(argv, stdout_path, stderr_path)``
+- ``SAFE_DIRNAME(path)``
+- ``SAFE_GETPRIORITY(which, who)``
+- ``SAFE_GETRUSAGE(who, usage)``
+- ``SAFE_IOCTL(fd, request, ...)``
+- ``SAFE_PERSONALITY(persona)``
+- ``SAFE_SETENV(name, value, overwrite)``
+- ``SAFE_SETNS(fd, nstype)``
+- ``SAFE_SSCANF(str, format, ...)``
+- ``SAFE_STATVFS(path, buf)``
+- ``SAFE_SYSCONF(name)``
+- ``SAFE_SYSINFO(info)``
+- ``SAFE_UNSHARE(flags)``
+
+String conversion
+~~~~~~~~~~~~~~~~~
+
+- ``SAFE_STRTOL(str, min, max)``
+- ``SAFE_STRTOUL(str, min, max)``
+- ``SAFE_STRTOF(str, min, max)``
+
+Inline macros (tst_safe_macros_inline.h)
+----------------------------------------
+
+- ``SAFE_FSTAT(fd, statbuf)``
+- ``SAFE_FTRUNCATE(fd, length)``
+- ``SAFE_GETRLIMIT(resource, rlim)``
+- ``SAFE_LSEEK(fd, offset, whence)``
+- ``SAFE_LSTAT(path, statbuf)``
+- ``SAFE_MMAP(addr, length, prot, flags, fd, offset)``
+- ``SAFE_POSIX_FADVISE(fd, offset, len, advice)``
+- ``SAFE_SETRLIMIT(resource, rlim)``
+- ``SAFE_STAT(path, statbuf)``
+- ``SAFE_STATFS(path, buf)``
+- ``SAFE_TRUNCATE(path, length)``
+
+File content operations (tst_safe_file_ops.h)
+----------------------------------------------
+
+- ``SAFE_FILE_SCANF(path, fmt, ...)``
+- ``SAFE_FILE_LINES_SCANF(path, fmt, ...)``
+- ``SAFE_FILE_PRINTF(path, fmt, ...)``
+- ``SAFE_TRY_FILE_PRINTF(path, fmt, ...)``
+- ``SAFE_FILE_READ_STR(path, buf)``
+- ``SAFE_READ_MEMINFO(item)``
+- ``SAFE_READ_PROC_STATUS(pid, item)``
+- ``SAFE_CP(src, dst)``
+- ``SAFE_TOUCH(path, mode, times)``
+- ``SAFE_MOUNT_OVERLAY()``
+
+File-at operations (tst_safe_file_at.h)
+----------------------------------------
+
+- ``SAFE_OPENAT(dirfd, path, oflag, ...)``
+- ``SAFE_FILE_READAT(dirfd, path, buf, bufsiz)``
+- ``SAFE_FILE_PRINTFAT(dirfd, path, fmt, ...)``
+- ``SAFE_UNLINKAT(dirfd, path, flags)``
+- ``SAFE_FCHOWNAT(dirfd, path, owner, group, flags)``
+- ``SAFE_FSTATAT(dirfd, path, statbuf, flags)``
+
+Positioned I/O (tst_safe_prw.h)
+---------------------------------
+
+- ``SAFE_PREAD(len_strict, fd, buf, count, offset)``
+- ``SAFE_PREADV(fd, iov, iovcnt, offset)``
+- ``SAFE_PWRITE(len_strict, fd, buf, count, offset)``
+- ``SAFE_PWRITEV(fd, iov, iovcnt, offset)``
+
+Networking (tst_safe_net.h)
+----------------------------
+
+- ``SAFE_SOCKET(domain, type, protocol)``
+- ``SAFE_SOCKETPAIR(domain, type, protocol, sv)``
+- ``SAFE_BIND(sockfd, addr, addrlen)``
+- ``SAFE_CONNECT(sockfd, addr, addrlen)``
+- ``SAFE_LISTEN(sockfd, backlog)``
+- ``SAFE_ACCEPT(sockfd, addr, addrlen)``
+- ``SAFE_SEND(sockfd, buf, len, flags)``
+- ``SAFE_SENDTO(sockfd, buf, len, flags, dest_addr, addrlen)``
+- ``SAFE_SENDMSG(sockfd, msg, flags)``
+- ``SAFE_RECV(sockfd, buf, len, flags)``
+- ``SAFE_RECVMSG(sockfd, msg, flags)``
+- ``SAFE_GETSOCKNAME(sockfd, addr, addrlen)``
+- ``SAFE_GETSOCKOPT(sockfd, level, optname, optval, optlen)``
+- ``SAFE_SETSOCKOPT(sockfd, level, optname, optval, optlen)``
+- ``SAFE_SETSOCKOPT_INT(sockfd, level, optname, value)``
+- ``SAFE_GETHOSTNAME(name, len)``
+- ``SAFE_SETHOSTNAME(name, len)``
+- ``SAFE_GETADDRINFO(node, service, hints, res)``
+
+Pthreads (tst_safe_pthread.h)
+------------------------------
+
+- ``SAFE_PTHREAD_CREATE(thread, attr, start_routine, arg)``
+- ``SAFE_PTHREAD_JOIN(thread, retval)``
+- ``SAFE_PTHREAD_CANCEL(thread)``
+- ``SAFE_PTHREAD_KILL(thread, sig)``
+- ``SAFE_PTHREAD_BARRIER_INIT(barrier, attr, count)``
+- ``SAFE_PTHREAD_BARRIER_WAIT(barrier)``
+- ``SAFE_PTHREAD_BARRIER_DESTROY(barrier)``
+- ``SAFE_PTHREAD_MUTEX_INIT(mutex, attr)``
+- ``SAFE_PTHREAD_MUTEX_LOCK(mutex)``
+- ``SAFE_PTHREAD_MUTEX_TRYLOCK(mutex)``
+- ``SAFE_PTHREAD_MUTEX_TIMEDLOCK(mutex, abstime)``
+- ``SAFE_PTHREAD_MUTEX_UNLOCK(mutex)``
+- ``SAFE_PTHREAD_MUTEX_DESTROY(mutex)``
+- ``SAFE_PTHREAD_MUTEXATTR_INIT(attr)``
+- ``SAFE_PTHREAD_MUTEXATTR_SETTYPE(attr, type)``
+- ``SAFE_PTHREAD_MUTEXATTR_DESTROY(attr)``
+
+Standard I/O (tst_safe_stdio.h)
+--------------------------------
+
+- ``SAFE_FOPEN(path, mode)``
+- ``SAFE_FREOPEN(path, mode, stream)``
+- ``SAFE_FCLOSE(stream)``
+- ``SAFE_FREAD(ptr, size, nmemb, stream)``
+- ``SAFE_FWRITE(ptr, size, nmemb, stream)``
+- ``SAFE_FFLUSH(stream)``
+- ``SAFE_FSEEK(stream, offset, whence)``
+- ``SAFE_FTELL(stream)``
+- ``SAFE_FILENO(stream)``
+- ``SAFE_POPEN(command, type)``
+- ``SAFE_ASPRINTF(strp, fmt, ...)``
+
+SysV IPC (tst_safe_sysv_ipc.h)
+--------------------------------
+
+- ``SAFE_MSGGET(key, msgflg)``
+- ``SAFE_MSGSND(msqid, msgp, msgsz, msgflg)``
+- ``SAFE_MSGRCV(msqid, msgp, msgsz, msgtyp, msgflg)``
+- ``SAFE_MSGCTL(msqid, cmd, buf)``
+- ``SAFE_SEMGET(key, nsems, semflg)``
+- ``SAFE_SEMOP(semid, sops, nsops)``
+- ``SAFE_SEMCTL(semid, semnum, cmd, ...)``
+- ``SAFE_SHMGET(key, size, shmflg)``
+- ``SAFE_SHMAT(shmid, shmaddr, shmflg)``
+- ``SAFE_SHMDT(shmaddr)``
+- ``SAFE_SHMCTL(shmid, cmd, buf)``
+
+POSIX IPC (tst_safe_posix_ipc.h)
+----------------------------------
+
+- ``SAFE_MQ_OPEN(name, oflag, ...)``
+- ``SAFE_MQ_CLOSE(mqdes)``
+- ``SAFE_MQ_SEND(mqdes, msg_ptr, msg_len, msg_prio)``
+- ``SAFE_MQ_NOTIFY(mqdes, sevp)``
+- ``SAFE_MQ_UNLINK(name)``
+
+Clocks and timers (tst_safe_clocks.h)
+--------------------------------------
+
+- ``SAFE_CLOCK_GETRES(clk_id, res)``
+- ``SAFE_CLOCK_GETTIME(clk_id, tp)``
+- ``SAFE_CLOCK_SETTIME(clk_id, tp)``
+- ``SAFE_CLOCK_NANOSLEEP(clk_id, flags, request, remain)``
+- ``SAFE_TIMER_CREATE(clockid, sevp, timerid)``
+- ``SAFE_TIMER_SETTIME(timerid, flags, new_value, old_value)``
+- ``SAFE_TIMER_GETTIME(timerid, curr_value)``
+- ``SAFE_TIMER_DELETE(timerid)``
+
+Timer file descriptors (tst_safe_timerfd.h)
+--------------------------------------------
+
+- ``SAFE_TIMERFD_CREATE(clockid, flags)``
+- ``SAFE_TIMERFD_SETTIME(fd, flags, new_value, old_value)``
+- ``SAFE_TIMERFD_GETTIME(fd, curr_value)``
+
+io_uring (tst_safe_io_uring.h)
+-------------------------------
+
+- ``SAFE_IO_URING_INIT(entries, params, ring)``
+- ``SAFE_IO_URING_ENTER(fd, to_submit, min_complete, flags, sig)``
+- ``SAFE_IO_URING_CLOSE(ring)``
+
+Filesystem creation (tst_mkfs.h)
+--------------------------------
+
+- ``SAFE_MKFS(device, fs_type, fs_opts, extra_opts)``
+
+Process creation (tst_clone.h, tst_test.h)
+------------------------------------------
+
+- ``SAFE_CLONE(args)``
+- ``SAFE_FORK()``
+
+Control groups (tst_cgroup.h)
+-----------------------------
+
+- ``SAFE_CG_HAS(cg, file_name)``
+- ``SAFE_CG_OPEN(cg, file_name, flags, fds)``
+- ``SAFE_CG_READ(cg, file_name, out, len)``
+- ``SAFE_CG_PRINT(cg, file_name, str)``
+- ``SAFE_CG_PRINTF(cg, file_name, fmt, ...)``
+- ``SAFE_CG_SCANF(cg, file_name, fmt, ...)``
+- ``SAFE_CG_LINES_SCANF(cg, file_name, fmt, ...)``
+- ``SAFE_CG_OCCURSIN(cg, file_name, needle)``
+- ``SAFE_CG_FCHOWN(cg, file_name, owner, group)``
+
+Epoll (tst_epoll.h)
+-------------------
+
+- ``SAFE_EPOLL_CREATE1(flags)``
+- ``SAFE_EPOLL_CTL(epfd, op, fd, ev)``
+- ``SAFE_EPOLL_WAIT(epfd, events, maxevents, timeout)``
+
+Swap files (tse_swap.h)
+-----------------------
+
+- ``SAFE_MAKE_SMALL_SWAPFILE(swapfile)``
+- ``SAFE_MAKE_SWAPFILE_SIZE(swapfile, size)``
+- ``SAFE_MAKE_SWAPFILE_BLKS(swapfile, blocks)``
+
+Realtime signals (lapi/safe_rt_signal.h)
+----------------------------------------
+
+- ``SAFE_RT_SIGACTION(signum, act, oldact, sigsetsize)``
+- ``SAFE_RT_SIGPROCMASK(how, set, oldset, sigsetsize)``
+
+Fallback syscall wrappers (include/lapi/)
+-----------------------------------------
+
+- ``SAFE_STATX(dirfd, pathname, flags, mask, buf)``
+- ``SAFE_FCHMODAT2(dfd, filename, mode, flags)``
+- ``SAFE_SPLICE(fd_in, off_in, fd_out, off_out, len, flags)``
+- ``SAFE_KEYCTL(cmd, arg2, arg3, arg4, arg5)``
+- ``SAFE_USERFAULTFD(flags, retry)``
+- ``SAFE_MODIFY_LDT(func, ptr, bytecount)``
+- ``SAFE_LANDLOCK_CREATE_RULESET(attr, size, flags)``
+- ``SAFE_LANDLOCK_ADD_RULE(ruleset_fd, rule_type, rule_attr, flags)``
+- ``SAFE_LANDLOCK_RESTRICT_SELF(ruleset_fd, flags)``
diff --git a/doc/index.rst b/doc/index.rst
index 58944a72da4c0a6d9362b0f85551683da03f5b72..c1252d34773e8411674fb143f5d871025b2fd96d 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -25,6 +25,7 @@
developers/writing_tests
developers/test_case_tutorial
developers/api_c_tests
+ developers/api_safe_macros
developers/api_shell_tests
developers/api_network_tests
developers/api_kvm_tests
@@ -82,6 +83,9 @@ For developers
:doc:`developers/api_c_tests`
Walk through the C API features
+:doc:`developers/api_safe_macros`
+ Reference of all ``SAFE_*`` wrapper macros
+
:doc:`developers/api_shell_tests`
Walk through the Shell API features
--
2.51.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
next prev parent reply other threads:[~2026-06-02 15:50 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-02 15:49 [LTP] [PATCH v3 0/3] Complete the documentation adding missing headers Andrea Cervesato
2026-06-02 15:49 ` [LTP] [PATCH v3 1/3] doc: Add missing API references to api_c_tests.rst Andrea Cervesato
2026-06-02 17:34 ` [LTP] " linuxtestproject.agent
2026-06-02 15:49 ` [LTP] [PATCH v3 2/3] doc: Complete struct tst_test table and shell API docs Andrea Cervesato
2026-06-02 15:49 ` Andrea Cervesato [this message]
2026-06-02 16:15 ` [LTP] [PATCH v3 0/3] Complete the documentation adding missing headers Andrea Cervesato via ltp
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260602-doc_add_missing_headers-v3-3-474deff77d2a@suse.com \
--to=andrea.cervesato@suse.de \
--cc=ltp@lists.linux.it \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.