(root)/
strace-6.5/
tests-mx32/
vfork-f.c
       1  /*
       2   * Copyright (c) 2015-2021 Dmitry V. Levin <ldv@strace.io>
       3   * All rights reserved.
       4   *
       5   * SPDX-License-Identifier: GPL-2.0-or-later
       6   */
       7  
       8  #include "tests.h"
       9  #include <assert.h>
      10  #include <fcntl.h>
      11  #include <stdio.h>
      12  #include <string.h>
      13  #include <unistd.h>
      14  #include <sys/wait.h>
      15  
      16  static int
      17  logit_(const char *const str)
      18  {
      19  	return !chdir(str);
      20  }
      21  
      22  #define prefix "vfork-f."
      23  #define logit(arg) logit_(prefix arg)
      24  
      25  int main(int ac, char **av)
      26  {
      27  	if (ac < 1)
      28  		return 1;
      29  	if (ac > 1) {
      30  		if (read(0, &ac, sizeof(int)))
      31  			return 2;
      32  		return logit("exec");
      33  	}
      34  
      35  	logit("start");
      36  
      37  	int child_wait_fds[2];
      38  	(void) close(0);
      39  	if (pipe(child_wait_fds))
      40  		perror_msg_and_fail("pipe");
      41  	if (fcntl(child_wait_fds[1], F_SETFD, FD_CLOEXEC))
      42  		perror_msg_and_fail("fcntl");
      43  
      44  	int parent_wait_fds[2];
      45  	if (pipe(parent_wait_fds))
      46  		perror_msg_and_fail("pipe");
      47  	if (fcntl(parent_wait_fds[0], F_SETFD, FD_CLOEXEC))
      48  		perror_msg_and_fail("fcntl");
      49  	if (fcntl(parent_wait_fds[1], F_SETFD, FD_CLOEXEC))
      50  		perror_msg_and_fail("fcntl");
      51  
      52  	char *const args[] = { av[0], (char *) "", NULL };
      53  	pid_t pid = vfork();
      54  
      55  	if (pid < 0)
      56  		perror_msg_and_fail("vfork");
      57  
      58  	if (!pid) {
      59  		if (logit("child") || execve(args[0], args, args + 1))
      60  			_exit(2);
      61  	}
      62  
      63  	close(0);
      64  	close(parent_wait_fds[1]);
      65  
      66  	if (read(parent_wait_fds[0], &parent_wait_fds[1], sizeof(int)))
      67  		perror_msg_and_fail("read");
      68  	logit("parent");
      69  	close(child_wait_fds[1]);
      70  
      71  	int status;
      72  	assert(wait(&status) == pid);
      73  	assert(status == 0);
      74  
      75  	pid_t ppid = getpid();
      76  	logit("finish");
      77  
      78  	printf("%-5d chdir(\"%sstart\") = -1 ENOENT (%m)\n"
      79  	       "%-5d chdir(\"%schild\") = -1 ENOENT (%m)\n"
      80  	       "%-5d chdir(\"%sparent\") = -1 ENOENT (%m)\n"
      81  	       "%-5d chdir(\"%sexec\") = -1 ENOENT (%m)\n"
      82  	       "%-5d chdir(\"%sfinish\") = -1 ENOENT (%m)\n",
      83  	       ppid, prefix,
      84  	       pid, prefix,
      85  	       ppid, prefix,
      86  	       pid, prefix,
      87  	       ppid, prefix);
      88  	return 0;
      89  }