Linux: using "clone3" and "waitid"

Joined
Oct 17, 2023
Messages
2
Reaction score
0
Hello, I'm trying to learn about "forking" processes with "clone3". I have read the manual pages to understand it. Other than the manual pages, I was able to find only ONE example of how to use it online (on the internet) and it doesn't seem to work. In addition, the example uses "waitpid" instead of the "waitid" that I want to use. In conclusion, I have modified the example to "transform" it to the following code:

C:
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <bits/types/struct_rusage.h>
#include <errno.h>
#include <linux/sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <unistd.h>

#ifndef CLONE_PIDFD
#define CLONE_PIDFD 0x00001000
#endif

#ifndef __NR_clone3
#define __NR_clone3 -1
struct clone_args {
  __aligned_u64 flags;
  __aligned_u64 pidfd;
  __aligned_u64 child_tid;
  __aligned_u64 parent_tid;
  __aligned_u64 exit_signal;
  __aligned_u64 stack;
  __aligned_u64 stack_size;
  __aligned_u64 tls;
};
#endif

static pid_t sys_clone3(struct clone_args *args) { return syscall(__NR_clone3, args, sizeof(struct clone_args)); }
static int sys_waitid(
  idtype_t type, id_t id, siginfo_t* info,
  struct rusage* usage, int options)
{
  return syscall(247, type, id, info, usage, options);
}

int value = 10;

int main(int argc, char *argv[]) {
  struct clone_args args = {
    .flags = CLONE_VM,
    .exit_signal = SIGCHLD,
  };

  int pid = sys_clone3(&args);
  if (pid < 0) {
    fprintf(stderr, "%s - Failed to create new process\n", strerror(errno));
    exit(EXIT_FAILURE);
  }

  if (pid == 0) {
    printf("Child process with pid %d\n", getpid());
    value = 20;
    printf("Value changed!");
    exit(EXIT_SUCCESS);
  }

  printf("Parent process received child's pid %d\n", pid);

  siginfo_t info;
  struct rusage usage;
  int wait_status = sys_waitid(P_ALL, 0, &info, &usage, __WALL);
  if (wait_status == -1) {
    fprintf(stderr, "Failed to wait on child process (%d)\n", errno);
    exit(EXIT_FAILURE);
  }

  printf("Tha value is: %d\n", value);

  return 0;
}

I had success using "fork" and "waitid" so I think that I'm doing something wrong with "clone3". I do suppose I'm missing a very small but important detail like it has happened in the past, so I thought asking if someone has figured it out. From what I understand, the block of the cloned process does not seem to be executed for some reason.... Also, if I run the program multiple times in a row, at some point, it will fail to wait for the process with exit code 22. I don't know if that's

I do need these two specifically. I am writing a system's library and I want to learn how to use them. Also, I am creating my own waitid version because the version of libc does not make use of the rusage struct, so I want to be 100% sure that there isn't something else going on that I cannot see. Thank you!
 
Last edited:

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,828
Messages
2,569,736
Members
45,518
Latest member
vlonesshirt

Latest Threads

Top