tools/testing/selftests/proc/fd-003-kthread.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/proc/fd-003-kthread.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/proc/fd-003-kthread.c- Extension
.c- Size
- 3993 bytes
- Lines
- 179
- 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.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
sys/syscall.hassert.hdirent.hlimits.hstdio.hstring.hsys/types.hsys/stat.hfcntl.hunistd.hproc.h
Detected Declarations
function openatfunction test_readdirfunction sys_statxfunction test_lookup_failfunction test_lookupfunction main
Annotated Snippet
// Test that /proc/$KERNEL_THREAD/fd/ is empty.
#undef NDEBUG
#include <sys/syscall.h>
#include <assert.h>
#include <dirent.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "proc.h"
#define PF_KHTREAD 0x00200000
/*
* Test for kernel threadness atomically with openat().
*
* Return /proc/$PID/fd descriptor if process is kernel thread.
* Return -1 if a process is userspace process.
*/
static int kernel_thread_fd(unsigned int pid)
{
unsigned int flags = 0;
char buf[4096];
int dir_fd, fd;
ssize_t rv;
snprintf(buf, sizeof(buf), "/proc/%u", pid);
dir_fd = open(buf, O_RDONLY|O_DIRECTORY);
if (dir_fd == -1)
return -1;
/*
* Believe it or not, struct task_struct::flags is directly exposed
* to userspace!
*/
fd = openat(dir_fd, "stat", O_RDONLY);
if (fd == -1) {
close(dir_fd);
return -1;
}
rv = read(fd, buf, sizeof(buf));
close(fd);
if (0 < rv && rv <= sizeof(buf)) {
unsigned long long flags_ull;
char *p, *end;
int i;
assert(buf[rv - 1] == '\n');
buf[rv - 1] = '\0';
/* Search backwards: ->comm can contain whitespace and ')'. */
for (i = 0; i < 43; i++) {
p = strrchr(buf, ' ');
assert(p);
*p = '\0';
}
p = strrchr(buf, ' ');
assert(p);
flags_ull = xstrtoull(p + 1, &end);
assert(*end == '\0');
assert(flags_ull == (unsigned int)flags_ull);
flags = flags_ull;
}
fd = -1;
if (flags & PF_KHTREAD) {
fd = openat(dir_fd, "fd", O_RDONLY|O_DIRECTORY);
}
close(dir_fd);
return fd;
}
static void test_readdir(int fd)
{
DIR *d;
struct dirent *de;
d = fdopendir(fd);
assert(d);
de = xreaddir(d);
assert(streq(de->d_name, "."));
Annotation
- Immediate include surface: `sys/syscall.h`, `assert.h`, `dirent.h`, `limits.h`, `stdio.h`, `string.h`, `sys/types.h`, `sys/stat.h`.
- Detected declarations: `function openat`, `function test_readdir`, `function sys_statx`, `function test_lookup_fail`, `function test_lookup`, `function main`.
- Atlas domain: Support Tooling And Documentation / tools.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.