#include <inttypes.h>
#include <linux/audit.h>
#include <linux/capability.h>
-//#include <linux/falloc.h>
#include <linux/if_link.h>
#include <linux/input.h>
#include <linux/loop.h>
#define BPF_FS_MAGIC 0xcafe4a11
#endif
-#ifndef OCFS2_SUPER_MAGIC
-#define OCFS2_SUPER_MAGIC 0x7461636f
-#endif
-
#ifndef MS_MOVE
#define MS_MOVE 8192
#endif
#define NS_GET_NSTYPE _IO(0xb7, 0x3)
#endif
-#ifndef FALLOC_FL_KEEP_SIZE
-#define FALLOC_FL_KEEP_SIZE 0x01
-#endif
-
-#ifndef FALLOC_FL_PUNCH_HOLE
-#define FALLOC_FL_PUNCH_HOLE 0x02
+#ifndef PF_KTHREAD
+#define PF_KTHREAD 0x00200000
#endif
#include "missing_syscall.h"
#endif // 0
int is_kernel_thread(pid_t pid) {
+ _cleanup_free_ char *line = NULL;
+ unsigned long long flags;
+ size_t l, i;
const char *p;
- size_t count;
- char c;
- bool eof;
- FILE *f;
+ char *q;
+ int r;
if (IN_SET(pid, 0, 1) || pid == getpid_cached()) /* pid 1, and we ourselves certainly aren't a kernel thread */
return 0;
+ if (!pid_is_valid(pid))
+ return -EINVAL;
- assert(pid > 1);
+ p = procfs_file_alloca(pid, "stat");
+ r = read_one_line_file(p, &line);
+ if (r == -ENOENT)
+ return -ESRCH;
+ if (r < 0)
+ return r;
- p = procfs_file_alloca(pid, "cmdline");
- f = fopen(p, "re");
- if (!f) {
- if (errno == ENOENT)
- return -ESRCH;
- return -errno;
+ /* Skip past the comm field */
+ q = strrchr(line, ')');
+ if (!q)
+ return -EINVAL;
+ q++;
+
+ /* Skip 6 fields to reach the flags field */
+ for (i = 0; i < 6; i++) {
+ l = strspn(q, WHITESPACE);
+ if (l < 1)
+ return -EINVAL;
+ q += l;
+
+ l = strcspn(q, WHITESPACE);
+ if (l < 1)
+ return -EINVAL;
+ q += l;
}
- (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
-
- count = fread(&c, 1, 1, f);
- eof = feof(f);
- fclose(f);
+ /* Skip preceeding whitespace */
+ l = strspn(q, WHITESPACE);
+ if (l < 1)
+ return -EINVAL;
+ q += l;
- /* Kernel threads have an empty cmdline */
+ /* Truncate the rest */
+ l = strcspn(q, WHITESPACE);
+ if (l < 1)
+ return -EINVAL;
+ q[l] = 0;
- if (count <= 0)
- return eof ? 1 : -errno;
+ r = safe_atollu(q, &flags);
+ if (r < 0)
+ return r;
- return 0;
+ return !!(flags & PF_KTHREAD);
}
#if 0 /// UNNEEDED by elogind