Пример #1
0
struct ProcChild *
proc_fork(void (*child_func)(void), const char *desc)
{
	pid_t pid;
	int fdr[2], fdw[2];

	pipe(fdr);
	pipe(fdw);
	pid = fork();
	if (pid == -1) return NULL;

	if (pid == 0) {
		// new child process starts
		close(fdw[1]);
		close(fdr[0]);
		memset(&my_proc, 0, sizeof(struct Proc));
		my_proc.parent.from = fdw[0];
		my_proc.parent.to = fdr[1];
		my_proc.parent.pid = getppid();
		my_proc.desc = desc;
		handle_signals();
		log_debug(LOG_PROC, "%s process %d started\n", desc, getpid());
		child_func();
		proc_finish();
		while (1) {} // to keep gcc happy
	} else {
		// parent process continues
		close(fdw[0]);
		close(fdr[1]);
		return add_child(pid, fdw[1], fdr[0], desc);
	}
}
Пример #2
0
static int test_child(int (*child_func) (void))
{
    struct stat st1, st2;
    int r;

    /* make sure we don't propagate mounts back to the parent */
    r = mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL);
    assert(r >= 0);

    r = stat(b1_mountpath, &st1);
    assert(r >= 0);

    /* mount fresh domain */
    r = mount(b1_filesystem,
              b1_mountpath,
              b1_filesystem,
              MS_NOSUID | MS_NOEXEC | MS_NODEV,
              NULL);
    assert(r >= 0);

    r = stat(b1_mountpath, &st2);
    assert(r >= 0);

    /* new domain must not equal parent domain */
    assert(st1.st_dev != st2.st_dev);

    return child_func();
}
Пример #3
0
/* To open and start new
 * python shell process
 */
gboolean
ptyFork (ChildProcessData *python_shell_data, GError **error)
{
    int mfd, slaveFd, savedErrno;

    mfd = posix_openpt (O_RDWR | O_NOCTTY | O_NONBLOCK);     
    grantpt (mfd);
    unlockpt (mfd);

    python_shell_data->master_fd = mfd;
    python_shell_data->slave_name = g_strdup (ptsname (mfd));
    python_shell_data->sh_argv = g_malloc0 (sizeof (gchar *));
    python_shell_data->sh_argv[0] = g_strdup ("/bin/sh");

    /*if (!g_spawn_async (python_shell_data->current_dir, python_shell_data->argv, NULL, 0, 
                       child_func, (gpointer)python_shell_data, 
                       &(python_shell_data->pid), error))

        return FALSE;*/

    pid_t childPid = fork ();
    if (childPid == 0)
    {
        child_func ((gpointer)python_shell_data);
        execv (python_shell_data->sh_argv [0], python_shell_data->sh_argv);
    }
    python_shell_data->pid = childPid;
    return TRUE;
}
Пример #4
0
void test_setup(int i, char *argv0)
{
	char nobody_uid[] = "nobody";
	struct passwd *ltpuser;

	switch (i) {
	case 0:
		break;

	case 1:
		header.version = _LINUX_CAPABILITY_VERSION;
		header.pid = 0;
		break;

	case 2:
		header.version = INVALID_VERSION;
		header.pid = 0;
		break;

	case 3:
		header.version = _LINUX_CAPABILITY_VERSION;
		/*
		 * when a non-zero pid is specified, process should have
		 * CAP_SETPCAP capability to change capabilities.
		 * by default, CAP_SETPCAP is not enabled. So giving
		 * a non-zero pid results in capset() failing with
		 * errno EPERM
		 *
		 * Note: this seems to have changed with recent kernels
		 * => create a child and try to set its capabilities
		 */
		child_pid = FORK_OR_VFORK();
		if (child_pid == -1)
			tst_brkm(TBROK | TERRNO, cleanup, "fork failed");
		else if (child_pid == 0) {
#ifdef UCLINUX
			if (self_exec(argv0, "") < 0) {
				perror("self_exec failed");
				exit(1);
			}
#else
			child_func();
#endif
		} else {
			header.pid = child_pid;
			ltpuser = getpwnam(nobody_uid);
			if (ltpuser == NULL)
				tst_brkm(TBROK | TERRNO, cleanup,
					 "getpwnam failed");
			if (seteuid(ltpuser->pw_uid) == -1)
				tst_brkm(TBROK | TERRNO, cleanup,
					 "seteuid failed");

		}
		break;

	}
}
Пример #5
0
/** The main function reads command line arguments, opens
 * the log and forks the child process.
 */
int
main(int argc, char** argv)
{
	int 			pid;
	char 			*infilename, *outfilename;
	FILE 			*infile, *outfile;
	sigset_t 		ss;

	infile = NULL;
	outfile = NULL;
	
	if (argc < 3 || argc > 4) {
		print_usage();
		exit(-1);
	}

	infilename = argv[1];
	outfilename = argv[2];
	if (argc > 3) { 
		if ((logfile = fopen(argv[3], "w")) == NULL) {
			perror("unable to open logfile");
			print_usage();
			exit(-1);
		}
	} else logfile = stdout;
	fprintf(logfile, "%ld: log opened\n", (long int)time(NULL));

	/** Create a blocking sigprocmask for the morse code signals so 
	 * that the blocked signals can be caught with sigtimedwait 
	 * instead of the signal handler
	 * */
	sigemptyset(&ss);
	sigaddset(&ss, MORSE_SHORT);
	sigaddset(&ss, MORSE_LONG);
	sigaddset(&ss, MORSE_PAUSE);
	
	sigprocmask(SIG_BLOCK, &ss, NULL);
	
	/* Fork the child process */
	if ((pid = fork()) < 0){
		perror("fork error");
		exit(-1);
	}
	if (pid == 0) {
		/* In child */
		child_func(infilename,infile);
		fflush(logfile);
		fclose(logfile);
	}
	else {
		/* In parent */
		parent_func(outfilename, outfile, pid);
		fflush(logfile);
		fclose(logfile);
	}
	return 0;
}
Пример #6
0
struct ProcChild *
proc_fork(void (*child_func)(void), const char *desc)
{
	pid_t pid;
	int fdr[2], fdw[2];
	int i;

	pipe(fdr);
	pipe(fdw);
	pid = fork();
	if (pid == -1) return NULL;

	if (pid == 0) {
		// new child process starts
		// we have to close unneeded pipes inherited from the parent
		if (my_proc.parent.to != -1) close(my_proc.parent.to);
		if (my_proc.parent.from != -1) close(my_proc.parent.from);
		for (i = 0; i < my_proc.nr_children; i++) {
			close(my_proc.children[i].to);
			close(my_proc.children[i].from);
		}
		close(fdw[1]);
		close(fdr[0]);
		// stop parent's pipes from propagating through an exec()
		fcntl(fdw[0], F_SETFD, FD_CLOEXEC);
		fcntl(fdr[1], F_SETFD, FD_CLOEXEC);
		// now setup our own data
		memset(&my_proc, 0, sizeof(struct Proc));
		my_proc.parent.from = fdw[0];
		my_proc.parent.to = fdr[1];
		my_proc.parent.pid = getppid();
		my_proc.desc = desc;
		handle_signals();
		set_my_name(desc);
		log_debug(LOG_PROC, "%s process %d started\n", desc, getpid());
		// finally jump to the real function
		child_func();
		proc_finish();
		while (1) {} // to keep gcc happy
	} else {
		// parent process continues
		close(fdw[0]);
		close(fdr[1]);
		return add_child(pid, fdw[1], fdr[0], desc);
	}
}
Пример #7
0
static void test(void)
{
	pid_t pid;
	int status;

	/* unshares the network namespace */
	if (unshare(CLONE_NEWNET) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "unshare failed");

	pid = tst_fork();
	if (pid < 0) {
		tst_brkm(TBROK | TERRNO, cleanup, "fork failed");
	}
	if (pid == 0) {
		_exit(child_func());
	}

	/* creates TAP network interface dummy0 */
	if (WEXITSTATUS(system("ip tuntap add dev dummy0 mode tap")) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "system failed");

	/* removes previously created dummy0 device */
	if (WEXITSTATUS(system("ip tuntap del mode tap dummy0")) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "system failed");

	/* allow child to continue */
	TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);


	SAFE_WAITPID(cleanup, pid, &status, 0);
	if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
		tst_resm(TFAIL, "netlink interface fail");
		return;
	}
	if (WIFSIGNALED(status)) {
		tst_resm(TFAIL, "child was killed with signal %s",
			 tst_strsig(WTERMSIG(status)));
		return;
	}

	tst_resm(TPASS, "netlink interface pass");
}
Пример #8
0
int main(int argc, char *argv[])
{
    int nchildren = 1;
    int pid;
    int x;

    if (argc > 1) {
        nchildren = atoi(argv[1]);
    }
    
    for (x = 0; x < nchildren; x++) {
        if ((pid = fork()) == 0) {
            child_func(x + 1);
            exit(0);
        }
    }

    wait(NULL);

    return 0;
}
Пример #9
0
static int fork_and_wait_child (void (*child_func) (void))
{
    pid_t pid;

    int status;

    pid = fork ();
    ATF_REQUIRE (pid != -1);
    if (pid == 0)
    {
        status = 0;                /* Silence compiler warnings */
        child_func ();
        UNREACHABLE;
    }
    else
    {
        ATF_REQUIRE (waitpid (pid, &status, 0) != 0);
    }

    return status;
}
Пример #10
0
static int create_child_and_init_lib(int n, Prolib_t *lib, void(*child_func)(int numth, Prolib_t *lib))
{
    int i;
    pid_t pid;
    for (i = 0; i < n; i++)
    {
        pid = fork();
        if (-1 == pid )
        {
            perror("fork");
            return -1;
        }
        if (0 == pid)
        {
            lib[i].pid = getpid();
            child_func(i, lib);
            exit(0);
        }
    }

    return 0;
}
Пример #11
0
void parent_func()
{
    int parent_var;

    child_func(&parent_var);
}
Пример #12
0
int child_func(void)
{
	int i, fd;
	struct timespec ts = {.tv_sec = 0, .tv_nsec = 0};
	int msec = 0;

	sleep(1);
	srand(time(NULL));
	for (i=0; i<NLOOP; i++) {
		sprintf(name, SHM_NAME, i);
		fd = shm_open(name, O_RDONLY|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
		if (fd != -1)
		{
			sem_wait(sem);
			//fprintf(stderr, "%d: %d\n", getpid(), *create_cnt);
			(*create_cnt)++;
			sem_post(sem);
		}
		/* get a random number [0, 20] */
		msec = (int) (20.0 * rand() / RAND_MAX) ;
		ts.tv_nsec = msec * 1000000;
		nanosleep(&ts, NULL);
	}
	return 0;
}

int main() {
	int i, pid, result_fd;
	char semname[20];

	snprintf(semname, 20, "/sem23-1_%d", getpid());
	sem = sem_open(semname, O_CREAT, 0777, 1);
	if (sem == SEM_FAILED || sem == NULL) {
		perror("error at sem_open");
		return PTS_UNRESOLVED;
	}
	sem_unlink(semname);

	result_fd = shm_open(SHM_RESULT_NAME,
			     O_RDWR|O_CREAT,
			     S_IRUSR|S_IWUSR);
	if (result_fd == -1) {
		perror("An error occurs when calling shm_open()");
		return PTS_UNRESOLVED;
	}
	shm_unlink(SHM_RESULT_NAME);
	if (ftruncate(result_fd, sizeof(*create_cnt)) != 0) {
		perror("An error occurs when calling ftruncate()");
		shm_unlink(SHM_RESULT_NAME);
		return PTS_UNRESOLVED;
	}

	create_cnt = mmap(NULL, sizeof(*create_cnt), PROT_WRITE,
		MAP_SHARED, result_fd, 0);
	if (create_cnt == MAP_FAILED) {
		perror("An error occurs when calling mmap()");
		shm_unlink(SHM_RESULT_NAME);
		return PTS_UNRESOLVED;
	}

	*create_cnt = 0;

	for (i=0; i<NPROCESS; i++) {
	        pid = fork();
		if (pid == -1) {
			perror("An error occurs when calling fork()");
			return PTS_UNRESOLVED;
		} else if (pid == 0) {
			child_func();
			exit(0);
		}
	}

	while (wait(NULL) > 0);

	for (i=0; i<NLOOP; i++) {
		sprintf(name, SHM_NAME, i);
		shm_unlink(name);
	}

	fprintf(stderr, "create_cnt: %d\n", *create_cnt);
	if (*create_cnt != NLOOP) {
		printf("Test FAILED\n");
		return PTS_FAIL;
	}

	return PTS_PASS;
}
Пример #13
0
static int
test_sig(void (*child_func)(void), int expected_sig, int expected_code)
{
   int code, term_sig;
   int child_pid;
   int wstatus;
   int rc;

   child_pid = fork();

   if (child_pid < 0) {
      printf("fork() failed\n");
      return 1;
   }

   if (!child_pid) {
      child_func();
      exit(0);
   }

   rc = waitpid(-1, &wstatus, 0);

   if (rc != child_pid) {
      printf("waitpid returned %d instead of child's pid: %d\n", rc, child_pid);
      return 1;
   }

   code = WEXITSTATUS(wstatus);
   term_sig = WTERMSIG(wstatus);

   if (expected_sig > 0) {

      if (code != 0) {
         printf("ERROR: expected child to exit with 0, got: %d\n", code);
         return 1;
      }

      if (term_sig != expected_sig) {
         printf("ERROR: expected child exit due to signal "
                "%d, instead got terminated by: %d\n", expected_sig, term_sig);
         return 1;
      }

      printf("The child exited with signal %d, as expected.\n", expected_sig);

   } else {

      if (term_sig != 0) {
         printf("ERROR: expected child to exit with code %d, "
                "it got terminated with signal: %d\n", expected_code, term_sig);
         return 1;
      }

      if (code != expected_code) {
         printf("ERROR: expected child exit with "
                "code %d, got: %d\n", expected_code, code);
         return 1;
      }

      printf("The child exited with code %d, as expected.\n", expected_code);
   }
   return 0;
}
Пример #14
0
int main(int argc, char *argv[])
{
  sem_t *sem_mutex;  //Binary semaphore to use a mutex
  int *stateptr;     //Shared memory global int to store active button state
  int hit_count = 0, rows, cols;
  WINDOW *mainwin = NULL;
  int nextch;
  MEVENT event;
  struct sigaction act;

  //Create a binary semaphore to use as a mutex:
  //(will be inerited by children)
  if ((sem_mutex = sem_open("/mutex", O_CREAT|O_EXCL, 0600, 1)) == SEM_FAILED) {
    perror("Semaphore creation failed");
    return EXIT_FAILURE; }

  //Now unlink semaphore so it will be deleted in case of ^-C or crash:
  sem_unlink("/mutex");

  //Setup anonymous, shared memory for global int:
  if ((stateptr = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) {
    perror("Shared memory creation failed");
    return EXIT_FAILURE; }

  //Initialize button state (no active buttons):
  *stateptr = 0;

  //Initialize and setup the curses window:
  if ((mainwin = initscr()) == NULL) {
    fprintf(stderr,"Failed to initialize curses window\n");
    return EXIT_FAILURE; }
  getmaxyx(mainwin,rows,cols);
  mvprintw(rows/2,cols/2-18,"Click on the Corner Buttons to Score!",rows,cols);
  mvprintw(rows/2+2,cols/2-10,"(rows: %d  cols: %d)",rows,cols);
  refresh();

  //Setup signal handler for SIGCHLD signals:
  memset(&act,0,sizeof(act));
  act.sa_handler = sigchld_handler;
  sigemptyset(&act.sa_mask);
  sigaction(SIGCHLD,&act,NULL);

  //Create children:
  //****************
 
  for (int i=0; i < running; i++){//memory problem???
	  switch(fork()){
		  case -1:
			perror("fork failed");
			sigchld_handler(EXIT_FAILURE);
			endwin();//put this in here since failures don't close the window apparently.
			exit(EXIT_FAILURE);
		  case 0:
			
			child_func(1+i, rows, cols,sem_mutex,stateptr);//1+processcount allows for proper numbering.
			sigchld_handler(EXIT_SUCCESS);
			exit(EXIT_SUCCESS);
		  default: 
		    break;//no break leads to error apparently.
			//I got it now the switch statement will determine the parent function follows the default.
		}
  }

  //Setup curses to get mouse events:
  keypad(mainwin, TRUE);
  mousemask(ALL_MOUSE_EVENTS, NULL);

  //Loop catching mouse clicks while children are running:
    while (running > 0) {
    //nextch = wgetch(mainwin);
    if ((nextch = getch()) == KEY_MOUSE && getmouse(&event) == OK && (event.bstate & BUTTON1_PRESSED)) {
      //Check if user clicked on a label:
      if (check_click(*stateptr, event.x, event.y, rows, cols)) {
        //Clicked on current label:
        hit_count++;
        mvprintw(rows/2+5,cols/2-11,"Got #%d at (%3d,%3d)",*stateptr,event.x,event.y);
        wrefresh(curscr);  //Need this to ensure entire screen is redrawn despite child changes.
      } }
  }

  //Close curses window so terminal settings are restored to normal:
  endwin();

  //Print out results:
  printf("\nYour hit count was: %d\n\n",hit_count);

  //Collect all the children:
  //*************************
  //return exit success if child successfully exited.
  int status;
  int tempcount = 0;//made a temp count since I think running will be 0 by now.
  while(tempcount<4){
  wait(&status);// wait for children shouldn't all return status
 
  if(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS){
	tempcount++;//increment temp count.
  }else
	exit(EXIT_FAILURE);//return exit failure according to lecture.
  }
  exit(EXIT_SUCCESS);//completes while loop so returns exit success.
}