/* the routine we call when we are going to spawn/fork/whatnot a child
   process from the parent netserver daemon. raj 2011-07-08 */
void
spawn_child() {

#if defined(WIN32)
  BOOL b;
  char *cmdline;
  int cmdline_length;
  int cmd_index;
  PROCESS_INFORMATION pi;
  STARTUPINFO si;
  int i;
#endif

  if (debug) {
    fprintf(where,
	    "%s: enter\n",
	    __FUNCTION__);
    fflush(where);
  }

#if defined(HAVE_FORK)

  /* flush the usual suspects */
  fflush(stdin);
  fflush(stdout);
  fflush(stderr);
  fflush(where);

  signal(SIGCLD,SIG_IGN);

  switch (fork()) {
  case -1:
    fprintf(where,
	    "%s: fork() error %s (errno %d)\n",
	    __FUNCTION__,
	    strerror(errno),
	    errno);
    fflush(where);
    exit(1);

  case 0:
    /* we are the child, but not of inetd.  we don't know if we are
       the child of a daemonized parent or not, so we still need to
       worry about the standard file descriptors. raj 2011-07-11 */

    close_listens(listen_list);
    open_debug_file();

    child = 1;
    netperf_daemon = 0;
    process_requests();
    exit(0);
    break;

  default:
    /* we are the parent, not a great deal to do here, but we may
       want to reap some children */
#if !defined(HAVE_SETSID)
    /* Only call "waitpid()" if "setsid()" is not used. */
    while(waitpid(-1, NULL, WNOHANG) > 0) {
      if (debug) {
	fprintf(where,
		"%s: reaped a child process\n",
		__FUNCTION__);
      }
    }
#endif
    break;
  }

#elif defined(WIN32)
  /* create the cmdline array based on strlen(program) + 80 chars */
  cmdline_length = strlen(program) + 80;
  cmdline = malloc(cmdline_length + 1);  // +1 for trailing null
	    
  memset(&si, 0 , sizeof(STARTUPINFO));
  si.cb = sizeof(STARTUPINFO);
	    
  /* Pass the server_sock as stdin for the new process.  Hopefully
     this will continue to be created with the OBJ_INHERIT
     attribute. */
  si.hStdInput = (HANDLE)server_sock;
  si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
  si.dwFlags = STARTF_USESTDHANDLES;
	    
  /* Build cmdline for child process */
  strcpy(cmdline, program);
  cmd_index = strlen(cmdline);
  if (verbosity > 1) {
    cmd_index += snprintf(&cmdline[cmd_index],
			  cmdline_length - cmd_index,
			  " -v %d",
			  verbosity);
  }
  for (i=0; i < debug; i++) {
    cmd_index += snprintf(&cmdline[cmd_index],
			  cmdline_length - cmd_index,
			  " -d");
  }
  cmd_index += snprintf(&cmdline[cmd_index],
			cmdline_length - cmd_index,
			" -I %x",
			(int)(UINT_PTR)server_sock);

  /* are these -i settings even necessary? the command line scanning
     does not seem to do anything with them */
  cmd_index += snprintf(&cmdline[cmd_index],
			cmdline_length - cmd_index,
			" -i %x",
			(int)(UINT_PTR)server_control);
  cmd_index += snprintf(&cmdline[cmd_index],
			cmdline_length - cmd_index,
			" -i %x",
			(int)(UINT_PTR)where);
	    
  b = CreateProcess(NULL,    /* Application Name */
		    cmdline,
		    NULL,    /* Process security attributes */
		    NULL,    /* Thread security attributes */
		    TRUE,    /* Inherit handles */
		    0,       /* Creation flags
				PROCESS_QUERY_INFORMATION,  */
		    NULL,    /* Enviornment */
		    NULL,    /* Current directory */
		    &si,     /* StartupInfo */
		    &pi);
  if (!b)
    {
      perror("CreateProcessfailure: ");
      free(cmdline); /* even though we exit :) */
      exit(1);
    }
	    
  /* We don't need the thread or process handles any more;
     let them go away on their own timeframe. */
	    
  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
	    
  /* the caller/parent will close server_sock */

  free(cmdline);

#else

  fprintf(where,
	  "%s called on platform which cannot spawn children\n",
	  __FUNCTION__);
  fflush(where);
  exit(1);

#endif /* HAVE_FORK */
}
Esempio n. 2
0
int main(int argc, char *argv[]) {

	initializeSigHandler();

	setpgid(0, 0);
	int i = 0;
	int ret = 0;
	pid_t pid;
	cmpQty = argc - 2;
	cmp = malloc(sizeof(company*) * cmpQty);
	map = malloc(sizeof(graph));
	sem_id = createSem(SEM_CREAT_KEY, cmpQty + SEM_QTY);
	setAllSem(sem_id, cmpQty + SEM_QTY, 0);

	if (initPIDS() == MALLOC_ERROR
	)
		return MALLOC_ERROR;

	/***PARSER***/
	if (cmp == NULL || map == NULL
	)
		return parserError(NULL, NULL, MALLOC_ERROR, NULL);
	if ((ret = parseFiles(argc, argv, map, cmp)) != EXIT_SUCCESS
	)
		return ret;

	/***INITIALIZES ARRAYS FOR THE EXECL***/

	initializeArray(&semMsg, sem_id);
	initializeArray(&procQty, ID_QTY + cmpQty);

	/***MAP AND COMPANIES CREATION***/
	if (createIPC(MAIN_ID, cmpQty + ID_QTY) == ERROR
	)
		return ERROR;

	int map_pid = 0;
	int io_pid = 0;
	int mult_pid = 0;
	if ((pid = fork()) == 0) {
		execl("io", semMsg, procQty, NULL);
		exit(1);
	} else {
		io_pid = pid;
		addPid(io_pid);
		if ((pid = fork()) == 0) {
			execl("map", semMsg, procQty, NULL);
			exit(1);
		} else {
			map_pid = pid;
			addPid(map_pid);
			if ((pid = fork()) == 0) {
				execl("multitasker", semMsg, procQty, NULL);
				exit(1);
			} else {
				mult_pid = pid;
				addPid(mult_pid);
				for (i = 0; i < cmpQty; i++) {
					if ((pid = fork()) == 0) {
						char *buf = NULL;
						int id = CMP_ID + i;
						initializeArray(&buf, id);
						execl("company", buf, procQty, semMsg, NULL);
					} else {
						addPid(pid);
					}
				}
			}
		}
	}
	upSem(sem_id, MAIN_ID);
	downSem(sem_id, IO_ID);
	downSem(sem_id, MULTITASKER_ID);
	for (i = 0; i < cmpQty; i++) {
		downSem(sem_id, CMP_ID + i);
		if (initializeCmp(cmp[i], MAIN_ID, CMP_ID + i) == ERROR
		)
			return ERROR;
	}
	downSem(sem_id, MAP_ID);
	if (initializeMap(map, MAIN_ID, MAP_ID) == ERROR) {
		return ERROR;
	}
	downSem(sem_id, MAP_ID);

	for (i = 0; i < cmpQty; i++) {
		wait(0); //Waits for all the companies to finish
	}
	kill(mult_pid, SIGTERM);
	waitpid(mult_pid, 0, 0);

	kill(map_pid, SIGTERM);
	waitpid(map_pid, 0, 0);

	kill(io_pid, SIGTERM);
	waitpid(io_pid, 0, 0);

	if (disconnectFromIPC(MAIN_ID) == ERROR) {
		destroyIPC(MAIN_ID);
	}
	destroySem(sem_id);

	/***FREES***/
	freeAll();

	return EXIT_SUCCESS;

}
Esempio n. 3
0
/**
 * Signal handler for the server.
 */
void handle_sigs(void)
{
	pid_t  chld;
	int    chld_status;
	int    i;
	int    do_exit;

	switch(sig_flag){
		case 0: break; /* do nothing*/
		case SIGPIPE:
				/* SIGPIPE might be rarely received on use of
				   exec module; simply ignore it
				 */
				LM_WARN("SIGPIPE received and ignored\n");
				break;
		case SIGINT:
		case SIGTERM:
			/* we end the program in all these cases */
			if (sig_flag==SIGINT)
				LM_DBG("INT received, program terminates\n");
			else
				LM_DBG("SIGTERM received, program terminates\n");
				
			/* first of all, kill the children also */
			kill_all_children(SIGTERM);
			if (signal(SIGALRM, sig_alarm_kill) == SIG_ERR ) {
				LM_ERR("could not install SIGALARM handler\n");
				/* continue, the process will die anyway if no
				 * alarm is installed which is exactly what we want */
			}
			alarm(OPENSER_SHUTDOWN_TIME); /* 1 minute close timeout */

			while(wait(0) > 0); /* Wait for all the children to terminate */
			signal(SIGALRM, sig_alarm_abort);

			cleanup(1); /* cleanup & show status*/
			alarm(0);
			signal(SIGALRM, SIG_IGN);
			dprint("Thank you for flying " NAME "\n");
			exit(0);
			break;
			
		case SIGUSR1:
#ifdef PKG_MALLOC
			LOG(memlog, "Memory status (pkg):\n");
			pkg_status();
#endif
#ifdef SHM_MEM
			LOG(memlog, "Memory status (shm):\n");
			shm_status();
#endif
			break;
			
		case SIGCHLD:
			do_exit = 0;
			while ((chld=waitpid( -1, &chld_status, WNOHANG ))>0) {
				/* is it a process we know about? */
				for( i=0 ; i<counted_processes ; i++ )
					if (pt[i].pid==chld) break;
				if (i==counted_processes) {
					LM_DBG("unkown child process %d ended. Ignoring\n",chld);
					continue;
				}
				do_exit = 1;
				/* process the signal */
				if (WIFEXITED(chld_status)) 
					LM_INFO("child process %d exited normally,"
							" status=%d\n", chld, 
							WEXITSTATUS(chld_status));
				else if (WIFSIGNALED(chld_status)) {
					LM_INFO("child process %d exited by a signal"
							" %d\n", chld, WTERMSIG(chld_status));
#ifdef WCOREDUMP
					LM_INFO("core was %sgenerated\n",
							 WCOREDUMP(chld_status) ?  "" : "not " );
#endif
				}else if (WIFSTOPPED(chld_status)) 
					LM_INFO("child process %d stopped by a"
								" signal %d\n", chld,
								 WSTOPSIG(chld_status));
			}
			if (!do_exit)
				break;
			LM_INFO("terminating due to SIGCHLD\n");
			/* exit */
			kill_all_children(SIGTERM);
			if (signal(SIGALRM, sig_alarm_kill) == SIG_ERR ) {
				LM_ERR("could not install SIGALARM handler\n");
				/* continue, the process will die anyway if no
				 * alarm is installed which is exactly what we want */
			}
			alarm(OPENSER_SHUTDOWN_TIME); /* 1 minute close timeout */
			while(wait(0) > 0); /* wait for all the children to terminate*/
			signal(SIGALRM, sig_alarm_abort);
			cleanup(1); /* cleanup & show status*/
			alarm(0);
			signal(SIGALRM, SIG_IGN);
			LM_DBG("terminating due to SIGCHLD\n");
			exit(0);
			break;
		
		case SIGHUP: /* ignoring it*/
			LM_DBG("SIGHUP received, ignoring it\n");
			break;
		default:
			LM_CRIT("unhandled signal %d\n", sig_flag);
	}
	sig_flag=0;
}
Esempio n. 4
0
/* Run an external command returning exit status, and optionally filling
 * provided buffer with STDOUT output up to the size provided.
 *
 * Note: XXX: We are not using the timeout parameter at present. We still need
 *       to implement a reliable timeout mechanism.
*/
static int
_run_extcmd(uid_t uid, gid_t gid, const char *cmd, char *so_buf,
        const size_t so_buf_sz, const int cflag, const int timeout,
        const char *substr_search, int *pid_status,
        const fko_srv_options_t * const opts)
{
    char    so_read_buf[IO_READ_BUF_LEN] = {0};
    pid_t   pid=0;
    FILE   *output;
    int     retval = EXTCMD_SUCCESS_ALL_OUTPUT;
    int     line_ctr = 0, found_str = 0, do_break = 0;

    char   *argv_new[MAX_CMDLINE_ARGS]; /* for validation and/or execvpe() */
    int     argc_new=0;

#if HAVE_EXECVPE
    int     pipe_fd[2];
#endif

#if AFL_FUZZING
    /* Don't allow command execution in AFL fuzzing mode
    */
    return 0;
#endif

    *pid_status = 0;

    /* Even without execvpe() we examine the command for basic validity
     * in term of number of args
    */
    memset(argv_new, 0x0, sizeof(argv_new));

    if(strtoargv(cmd, argv_new, &argc_new) != 1)
    {
        log_msg(LOG_ERR,
                "run_extcmd(): Error converting cmd str to argv via strtoargv()");
        return EXTCMD_ARGV_ERROR;
    }

#if !HAVE_EXECVPE
    /* if we are not using execvpe() then free up argv_new unconditionally
     * since was used only for validation
    */
    free_argv(argv_new, &argc_new);
#endif

#if HAVE_EXECVPE
    if(opts->verbose > 1)
        log_msg(LOG_INFO, "run_extcmd() (with execvpe()): running CMD: %s", cmd);

    if(so_buf != NULL || substr_search != NULL)
    {
        if(pipe(pipe_fd) < 0)
        {
            log_msg(LOG_ERR, "run_extcmd(): pipe() failed: %s", strerror(errno));
            free_argv(argv_new, &argc_new);
            return EXTCMD_PIPE_ERROR;
        }
    }

	//在子进程中创建CMD。
    pid = fork();
    if (pid == 0)
    {
        if(chdir("/") != 0)
            exit(EXTCMD_CHDIR_ERROR);

        if(so_buf != NULL || substr_search != NULL)
        {
            close(pipe_fd[0]);
            dup2(pipe_fd[1], STDOUT_FILENO);
            if(cflag & WANT_STDERR)
                dup2(pipe_fd[1], STDERR_FILENO);
            else
                close(STDERR_FILENO);
        }

        /* Take care of gid/uid settings before running the command.
        */
        if(gid > 0)
            if(setgid(gid) < 0)
                exit(EXTCMD_SETGID_ERROR);

        if(uid > 0)
            if(setuid(uid) < 0)
                exit(EXTCMD_SETUID_ERROR);

        /* don't use env
        */
        execvpe(argv_new[0], argv_new, (char * const *)NULL);
    }
    else if(pid == -1)
    {
        log_msg(LOG_ERR, "run_extcmd(): fork() failed: %s", strerror(errno));
        free_argv(argv_new, &argc_new);
        return EXTCMD_FORK_ERROR;
    }

    /* Only the parent process makes it here
    */
    if(so_buf != NULL || substr_search != NULL)
    {
        close(pipe_fd[1]);
        if ((output = fdopen(pipe_fd[0], "r")) != NULL)
        {
            if(so_buf != NULL)
                memset(so_buf, 0x0, so_buf_sz);

            while((fgets(so_read_buf, IO_READ_BUF_LEN, output)) != NULL)
            {
                line_ctr++;

                copy_or_search(so_read_buf, so_buf, so_buf_sz,
                        substr_search, cflag, &found_str, &do_break);

                if(do_break)
                    break;
            }
            fclose(output);

            /* Make sure we only have complete lines
            */
            if(!(cflag & ALLOW_PARTIAL_LINES))
                truncate_partial_line(so_buf);
        }
        else
        {
            log_msg(LOG_ERR,
                    "run_extcmd(): could not fdopen() pipe output file descriptor.");
            free_argv(argv_new, &argc_new);
            return EXTCMD_OPEN_ERROR;
        }
    }

    free_argv(argv_new, &argc_new);

    waitpid(pid, pid_status, 0);

#else

    if(opts->verbose > 1)
        log_msg(LOG_INFO, "run_extcmd() (without execvpe()): running CMD: %s", cmd);

    if(so_buf == NULL && substr_search == NULL)
    {
        /* Since we do not have to capture output, we will fork here (which we
         * * would have to do anyway if we are running as another user as well).
         * */
        pid = fork();
        if(pid == -1)
        {
            log_msg(LOG_ERR, "run_extcmd: fork failed: %s", strerror(errno));
            return(EXTCMD_FORK_ERROR);
        }
        else if (pid == 0)
        {
            /* We are the child */

            if(chdir("/") != 0)
                exit(EXTCMD_CHDIR_ERROR);

            /* Take care of gid/uid settings before running the command.
            */
            if(gid > 0)
                if(setgid(gid) < 0)
                    exit(EXTCMD_SETGID_ERROR);

            if(uid > 0)
                if(setuid(uid) < 0)
                    exit(EXTCMD_SETUID_ERROR);

            *pid_status = system(cmd);
            exit(*pid_status);
        }
        /* Retval is forced to 0 as we don't care about the exit status of
         * the child (for now)
        */
        retval = EXTCMD_SUCCESS_ALL_OUTPUT;
    }
    else
    {
        /* Looking for output use popen and fill the buffer to its limit.
         */
        output = popen(cmd, "r");
        if(output == NULL)
        {
            log_msg(LOG_ERR, "Got popen error %i: %s", errno, strerror(errno));
            retval = EXTCMD_OPEN_ERROR;
        }
        else
        {
            if(so_buf != NULL)
                memset(so_buf, 0x0, so_buf_sz);

            while((fgets(so_read_buf, IO_READ_BUF_LEN, output)) != NULL)
            {
                line_ctr++;

                copy_or_search(so_read_buf, so_buf, so_buf_sz,
                        substr_search, cflag, &found_str, &do_break);

                if(do_break)
                    break;
            }
            pclose(output);

            /* Make sure we only have complete lines
            */
            if(!(cflag & ALLOW_PARTIAL_LINES))
                truncate_partial_line(so_buf);
        }
    }

#endif

    if(substr_search != NULL)
    {
        /* The semantics of the return value changes in search mode to the line
         * number where the substring match was found, or zero if it wasn't found
        */
        if(found_str)
            retval = line_ctr;
        else
            retval = 0;
    }
    else
    {
        if(WIFEXITED(*pid_status))
        {
            /* Even if the child exited with an error condition, if we make it here
             * then the child exited normally as far as the OS is concerned (i.e. didn't
             * crash or get hit with a signal)
            */
            retval = EXTCMD_SUCCESS_ALL_OUTPUT;
        }
        else
            retval = EXTCMD_EXECUTION_ERROR;
    }

    if(opts->verbose > 1)
        log_msg(LOG_INFO,
            "run_extcmd(): returning %d, pid_status: %d",
            retval, WIFEXITED(*pid_status) ? WEXITSTATUS(*pid_status) : *pid_status);

    return(retval);
}
Esempio n. 5
0
int main(int argc, char *argv[])
{
	int opt, status;
	int ret;
	char *namespaces = NULL;
	char **args;
	int flags = 0;
	uid_t uid = -1; /* valid only if (flags & CLONE_NEWUSER) */
	pid_t pid;

	struct start_arg start_arg = {
		.args = &args,
		.uid = &uid,
		.flags = &flags,
	};

	while ((opt = getopt(argc, argv, "s:u:h")) != -1) {
		switch (opt) {
		case 's':
			namespaces = optarg;
			break;
		case 'h':
			usage(argv[0]);
		case 'u':
			uid = lookup_user(optarg);
			if (uid == -1)
				return 1;
		}
	}

	if (argv[optind] == NULL) {
		ERROR("a command to execute in the new namespace is required");
		return 1;
	}

	args = &argv[optind];

	ret = lxc_caps_init();
	if (ret)
		return ret;

	ret = lxc_fill_namespace_flags(namespaces, &flags);
	if (ret)
		usage(argv[0]);

	if (!(flags & CLONE_NEWUSER) && uid != -1) {
		ERROR("-u <uid> needs -s USER option");
		return 1;
	}

	pid = lxc_clone(do_start, &start_arg, flags);
	if (pid < 0) {
		ERROR("failed to clone");
		return -1;
	}

	if (waitpid(pid, &status, 0) < 0) {
		ERROR("failed to wait for '%d'", pid);
		return -1;
	}

	return  lxc_error_set_and_log(pid, status);
}
Esempio n. 6
0
extern int run_parts(char **args, const unsigned char test_mode)
{
	struct dirent **namelist = 0;
	struct stat st;
	char *filename;
	char *arg0 = args[0];
	int entries;
	int i;
	int exitstatus = 0;

#if __GNUC__
	/* Avoid longjmp clobbering */
	(void) &i;
	(void) &exitstatus;
#endif
	/* scandir() isn't POSIX, but it makes things easy. */
	entries = scandir(arg0, &namelist, valid_name, alphasort);

	if (entries == -1) {
		if (test_mode & 2) {
			return(2);
		}
		bb_perror_msg_and_die("failed to open directory %s", arg0);
	}

	for (i = 0; i < entries; i++) {

		filename = concat_path_file(arg0, namelist[i]->d_name);

		if (stat(filename, &st) < 0) {
			bb_perror_msg_and_die("failed to stat component %s", filename);
		}
		if (S_ISREG(st.st_mode) && !access(filename, X_OK)) {
			if (test_mode & 1) {
				puts(filename);
			} else {
				/* exec_errno is common vfork variable */
				volatile int exec_errno = 0;
				int result;
				int pid;

				if ((pid = vfork()) < 0) {
					bb_perror_msg_and_die("failed to fork");
				} else if (!pid) {
					args[0] = filename;
					execv(filename, args);
					exec_errno = errno;
					_exit(1);
				}

				waitpid(pid, &result, 0);
				if(exec_errno) {
					errno = exec_errno;
					bb_perror_msg_and_die("failed to exec %s", filename);
				}
				if (WIFEXITED(result) && WEXITSTATUS(result)) {
					bb_perror_msg("%s exited with return code %d", filename, WEXITSTATUS(result));
					exitstatus = 1;
				} else if (WIFSIGNALED(result)) {
					bb_perror_msg("%s exited because of uncaught signal %d", filename, WTERMSIG(result));
					exitstatus = 1;
				}
			}
		} 
		else if (!S_ISDIR(st.st_mode)) {
			bb_error_msg("component %s is not an executable plain file", filename);
			exitstatus = 1;
		}

		free(namelist[i]);
		free(filename);
	}
	free(namelist);
	
	return(exitstatus);
}
Esempio n. 7
0
int main(int argc, char** argv) {
  int prg_argc;
  char ** prg_argv;  

  progname = argv[0];

  if (argc < 3)
    usage();

  int c, opt_index;
  while ((c = getopt_long(argc, argv, "f:r:", long_options, &opt_index)) != -1) {
    switch (c) {
      case 'f': {
        /* Special case hack for only creating files and not actually executing
        * the program.
         */
        if (argc != 3)
          usage();
    
        char* input_fname = optarg;
    
        input = kTest_fromFile(input_fname);
        if (!input) {
          fprintf(stderr, "%s: error: input file %s not valid.\n", progname,
                  input_fname);
          exit(1);
        }

        prg_argc = input->numArgs;
        prg_argv = input->args;
        prg_argv[0] = argv[1];
        klee_init_env(&prg_argc, &prg_argv);

        replay_create_files(&__exe_fs);
        return 0;
      }
      case 'r':
        rootdir = optarg;
        break;
    }
  }

  /* Normal execution path ... */

  char* executable = argv[optind];

  /* make sure this process has the CAP_SYS_CHROOT capability. */
  if (rootdir)
    ensure_capsyschroot(progname);
  
  /* rootdir should be a prefix of executable's path. */
  if (rootdir && strstr(executable, rootdir) != executable) {
    fprintf(stderr, "Error: chroot: root dir should be a parent dir of executable.\n");
    exit(1);
  }

  /* Verify the executable exists. */
  FILE *f = fopen(executable, "r");
  if (!f) {
    fprintf(stderr, "Error: executable %s not found.\n", executable);
    exit(1);
  }
  fclose(f);

  int idx = 0;
  for (idx = optind + 1; idx != argc; ++idx) {
    char* input_fname = argv[idx];
    unsigned i;
    
    input = kTest_fromFile(input_fname);
    if (!input) {
      fprintf(stderr, "%s: error: input file %s not valid.\n", progname, 
              input_fname);
      exit(1);
    }
    
    obj_index = 0;
    prg_argc = input->numArgs;
    prg_argv = input->args;
    prg_argv[0] = argv[optind];
    klee_init_env(&prg_argc, &prg_argv);

    if (idx > 2)
      fprintf(stderr, "\n");
    fprintf(stderr, "%s: TEST CASE: %s\n", progname, input_fname);
    fprintf(stderr, "%s: ARGS: ", progname);
    for (i=0; i != (unsigned) prg_argc; ++i) {
      char *s = prg_argv[i];
      if (s[0]=='A' && s[1] && !s[2]) s[1] = '\0';
      fprintf(stderr, "\"%s\" ", prg_argv[i]); 
    }
    fprintf(stderr, "\n");

    /* Run the test case machinery in a subprocess, eventually this parent
       process should be a script or something which shells out to the actual
       execution tool. */
    int pid = fork();
    if (pid < 0) {
      perror("fork");
      _exit(66);
    } else if (pid == 0) {
      /* Create the input files, pipes, etc., and run the process. */
      replay_create_files(&__exe_fs);
      run_monitored(executable, prg_argc, prg_argv);
      _exit(0);
    } else {
      /* Wait for the test case. */
      int res, status;

      do {
        res = waitpid(pid, &status, 0);
      } while (res < 0 && errno == EINTR);
      
      if (res < 0) {
        perror("waitpid");
        _exit(66);
      }
    }
  }

  return 0;
}
Esempio n. 8
0
void trace(pid_t child, std::vector<std::string>& files, std::mutex & mutex)
{
  waitpid(-1, NULL, __WALL);

  ptrace(PTRACE_ATTACH, child, 0, 0);
  ptrace(PTRACE_SETOPTIONS, child, NULL, PTRACE_O_TRACEFORK 
                                       | PTRACE_O_TRACEVFORK 
                                       | PTRACE_O_TRACECLONE 
                                       | PTRACE_O_TRACEEXIT 
                                       | PTRACE_O_EXITKILL);

  pid_t pid = child;
  while (true) {
    int status;

    ptrace(PTRACE_SYSCALL, pid, 0, 0);
    pid = waitpid(-1, &status, __WALL);

    if(WIFEXITED(status))
    { 
      break;
    }
    else if (WIFSTOPPED(status))
    {   
        struct user_regs_struct regs;
        ptrace(PTRACE_GETREGS, pid, 0, &regs);
        struct regs {
#ifdef __x86_64__
          unsigned long 
#endif
          long
            err, 
            syscall, 
            arg0;
        } regs_ = { 
#ifdef __x86_64__
          regs.rax, regs.orig_rax, regs.rdi
#else
          regs.eax, regs.orig_eax, regs.ebx
#endif
        };
        if (regs_.err == (unsigned long)-ENOSYS) { //syscall_enter stop
          if (regs_.syscall == __NR_open) {
            std::string file_name;
            long word = ptrace(PTRACE_PEEKDATA, pid, regs_.arg0, NULL);
            char * tmp = (char *)&word;
            while (*tmp != '\0') {
              file_name.push_back(*tmp);
              ++tmp;
              if (tmp == (char *)(&word + 1)) {
                regs_.arg0 += sizeof(word);
                word = ptrace(PTRACE_PEEKDATA, pid, regs_.arg0, NULL);
                tmp = (char *)&word;
              }
            }
            {
              std::lock_guard<std::mutex> l(mutex);
              files.push_back(file_name);
            }
          }
        }
        else { //syscall_exit stop
        }
    }
  }
}
Esempio n. 9
0
static int
do_test (void)
{
  int result = 0;

  char tmpfname[] = "/tmp/tst-mqueue5-barrier.XXXXXX";
  int fd = mkstemp (tmpfname);
  if (fd == -1)
    {
      printf ("cannot open temporary file: %m\n");
      return 1;
    }

  /* Make sure it is always removed.  */
  unlink (tmpfname);

  /* Create one page of data.  */
  size_t ps = sysconf (_SC_PAGESIZE);
  char data[ps];
  memset (data, '\0', ps);

  /* Write the data to the file.  */
  if (write (fd, data, ps) != (ssize_t) ps)
    {
      puts ("short write");
      return 1;
    }

  void *mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  if (mem == MAP_FAILED)
    {
      printf ("mmap failed: %m\n");
      return 1;
    }

  pthread_barrier_t *b2;
  b2 = (pthread_barrier_t *) (((uintptr_t) mem + __alignof (pthread_barrier_t))
			      & ~(__alignof (pthread_barrier_t) - 1));

  pthread_barrier_t *b3;
  b3 = b2 + 1;

  pthread_barrierattr_t a;
  if (pthread_barrierattr_init (&a) != 0)
    {
      puts ("barrierattr_init failed");
      return 1;
    }

  if (pthread_barrierattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0)
    {
      puts ("barrierattr_setpshared failed, could not test");
      return 0;
    }

  if (pthread_barrier_init (b2, &a, 2) != 0)
    {
      puts ("barrier_init failed");
      return 1;
    }

  if (pthread_barrier_init (b3, &a, 3) != 0)
    {
      puts ("barrier_init failed");
      return 1;
    }

  if (pthread_barrierattr_destroy (&a) != 0)
    {
      puts ("barrierattr_destroy failed");
      return 1;
    }

  char name[sizeof "/tst-mqueue5-" + sizeof (pid_t) * 3];
  snprintf (name, sizeof (name), "/tst-mqueue5-%u", getpid ());

  struct mq_attr attr = { .mq_maxmsg = 1, .mq_msgsize = 1 };
  mqd_t q = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);

  if (q == (mqd_t) -1)
    {
      printf ("mq_open failed with: %m\n");
      return result;
    }
  else
    add_temp_mq (name);

  struct sigevent ev;
  memset (&ev, 0xaa, sizeof (ev));
  ev.sigev_notify = SIGEV_NONE;
  if (mq_notify (q, &ev) != 0)
    {
      printf ("mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
      result = 1;
    }

  if (mq_notify (q, &ev) == 0)
    {
      puts ("second mq_notify (q, { SIGEV_NONE }) unexpectedly succeeded");
      result = 1;
    }
  else if (errno != EBUSY)
    {
      printf ("second mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
      result = 1;
    }

  result |= mqsend (q);

  if (mq_notify (q, &ev) != 0)
    {
      printf ("third mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
      result = 1;
    }

  result |= mqrecv (q);

  if (mq_notify (q, NULL) != 0)
    {
      printf ("mq_notify (q, NULL) failed with: %m\n");
      result = 1;
    }

  if (mq_notify (q, NULL) != 0)
    {
      /* Implementation-defined behaviour, so don't fail,
	 just inform.  */
      printf ("second mq_notify (q, NULL) failed with: %m\n");
    }

  struct sigaction sa = { .sa_sigaction = rtmin_handler,
			  .sa_flags = SA_SIGINFO };
  sigemptyset (&sa.sa_mask);
  sigaction (SIGRTMIN, &sa, NULL);

  memset (&ev, 0x55, sizeof (ev));
  ev.sigev_notify = SIGEV_SIGNAL;
  ev.sigev_signo = SIGRTMIN;
  ev.sigev_value.sival_int = 26;
  if (mq_notify (q, &ev) != 0)
    {
      printf ("mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n");
      result = 1;
    }

  ev.sigev_value.sival_ptr = &ev;
  if (mq_notify (q, &ev) == 0)
    {
      puts ("second mq_notify (q, { SIGEV_SIGNAL }) unexpectedly succeeded");
      result = 1;
    }
  else if (errno != EBUSY)
    {
      printf ("second mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n");
      result = 1;
    }

  if (rtmin_cnt != 0)
    {
      puts ("SIGRTMIN signal caught too early");
      result = 1;
    }

  result |= mqsend (q);

  if (rtmin_cnt != 1)
    {
      puts ("SIGRTMIN signal did not arrive");
      result = 1;
    }
  else if (rtmin_pid != getpid ()
	   || rtmin_uid != getuid ()
	   || rtmin_code != SI_MESGQ
	   || rtmin_sigval.sival_int != 26)
    {
      printf ("unexpected siginfo_t fields: pid %u (%u), uid %u (%u), code %d (%d), si_int %d (26)\n",
	      rtmin_pid, getpid (), rtmin_uid, getuid (),
	      rtmin_code, SI_MESGQ, rtmin_sigval.sival_int);
      result = 1;
    }

  ev.sigev_value.sival_int = 75;
  if (mq_notify (q, &ev) != 0)
    {
      printf ("third mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n");
      result = 1;
    }

  result |= mqrecv (q);

  if (mq_notify (q, NULL) != 0)
    {
      printf ("mq_notify (q, NULL) failed with: %m\n");
      result = 1;
    }

  memset (&ev, 0x33, sizeof (ev));
  ev.sigev_notify = SIGEV_NONE;
  if (mq_notify (q, &ev) != 0)
    {
      printf ("fourth mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
      result = 1;
    }

  pid_t pid = fork ();
  if (pid == -1)
    {
      printf ("fork () failed: %m\n");
      mq_unlink (name);
      return 1;
    }

  if (pid == 0)
    do_child (name, b2, b3, q);

  /* Child unsuccessfully attempts to mq_notify.  */

  (void) pthread_barrier_wait (b2);

  result |= mqsend (q);

  (void) pthread_barrier_wait (b2);

  /* Child successfully calls mq_notify SIGEV_SIGNAL now.  */

  result |= mqrecv (q);

  (void) pthread_barrier_wait (b2);

  memset (&ev, 0xbb, sizeof (ev));
  ev.sigev_notify = SIGEV_SIGNAL;
  ev.sigev_signo = SIGRTMIN;
  ev.sigev_value.sival_int = 15;
  if (mq_notify (q, &ev) == 0)
    {
      puts ("fourth mq_notify (q, { SIGEV_SIGNAL }) unexpectedly succeeded");
      result = 1;
    }
  else if (errno != EBUSY)
    {
      printf ("fourth mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n");
      result = 1;
    }

  result |= mqsend (q);

  if (mq_notify (q, &ev) != 0)
    {
      printf ("fifth mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n");
      result = 1;
    }

  if (rtmin_cnt != 1)
    {
      puts ("SIGRTMIN signal caught too early");
      result = 1;
    }

  result |= mqrecv (q);

  (void) pthread_barrier_wait (b2);

  /* Child verifies caught SIGRTMIN signal.  */
  /* Child calls mq_send (q) which triggers SIGRTMIN signal here.  */

  (void) pthread_barrier_wait (b2);

  /* Child mq_open's another mqd_t for the same queue (q2).  */

  if (rtmin_cnt != 2)
    {
      puts ("SIGRTMIN signal did not arrive");
      result = 1;
    }
  else if (rtmin_pid != pid
	   || rtmin_uid != getuid ()
	   || rtmin_code != SI_MESGQ
	   || rtmin_sigval.sival_int != 15)
    {
      printf ("unexpected siginfo_t fields: pid %u (%u), uid %u (%u), code %d (%d), si_int %d (15)\n",
	      rtmin_pid, pid, rtmin_uid, getuid (),
	      rtmin_code, SI_MESGQ, rtmin_sigval.sival_int);
      result = 1;
    }

  result |= mqrecv (q);

  (void) pthread_barrier_wait (b2);

  /* Child successfully calls mq_notify { SIGEV_SIGNAL } on q2.  */

  (void) pthread_barrier_wait (b2);

  memset (&ev, 0xbb, sizeof (ev));
  ev.sigev_notify = SIGEV_NONE;
  if (mq_notify (q, &ev) == 0)
    {
      puts ("fifth mq_notify (q, { SIGEV_NONE }) unexpectedly succeeded");
      result = 1;
    }
  else if (errno != EBUSY)
    {
      printf ("fifth mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
      result = 1;
    }

  (void) pthread_barrier_wait (b2);

  /* Child calls mq_close on q2, which makes the queue available again for
     notification.  */

  mqd_t q3 = mq_open (name, O_RDWR);
  if (q3 == (mqd_t) -1)
    {
      printf ("mq_open q3 in parent failed with: %m\n");
      result = 1;
    }

  (void) pthread_barrier_wait (b2);

  memset (&ev, 0x12, sizeof (ev));
  ev.sigev_notify = SIGEV_NONE;
  if (mq_notify (q3, &ev) != 0)
    {
      printf ("mq_notify (q3, { SIGEV_NONE }) failed with: %m\n");
      result = 1;
    }

  (void) pthread_barrier_wait (b2);

  /* Child unsuccessfully attempts to mq_notify { SIGEV_SIGNAL } on q.  */

  (void) pthread_barrier_wait (b2);

  if (mq_close (q3) != 0)
    {
      printf ("mq_close failed: %m\n");
      result = 1;
    }

  (void) pthread_barrier_wait (b2);

  /* Child successfully calls mq_notify { SIGEV_NONE } on q.  */
  /* Child successfully calls mq_notify NULL on q.  */

  (void) pthread_barrier_wait (b2);

  /* Child creates new thread.  */
  /* Thread blocks on mqrecv (q).  */
  /* Child sleeps for 1sec so that thread has time to reach that point.  */
  /* Child successfully calls mq_notify { SIGEV_SIGNAL } on q.  */

  (void) pthread_barrier_wait (b2);

  result |= mqsend (q);

  (void) pthread_barrier_wait (b3);

  /* Child verifies SIGRTMIN has not been sent.  */

  (void) pthread_barrier_wait (b3);

  result |= mqsend (q);

  (void) pthread_barrier_wait (b3);

  /* Thread verifies SIGRTMIN has been caught.  */
  /* Thread calls mq_notify (q, { SIGEV_NONE }) to verify notification is now
     available for registration.  */
  /* Thread calls mq_notify (q, NULL).  */

  (void) pthread_barrier_wait (b3);

  /* Child calls mq_notify (q, { SIGEV_SIGNAL }).  */

  (void) pthread_barrier_wait (b3);

  /* Thread calls mq_notify (q, NULL). */

  (void) pthread_barrier_wait (b3);

  result |= mqsend (q);
  result |= mqrecv (q);

  (void) pthread_barrier_wait (b3);

  /* Child verifies SIGRTMIN has not been sent.  */
  /* Child calls mq_notify (q, { SIGEV_SIGNAL }).  */

  (void) pthread_barrier_wait (b3);

  /* Thread opens a new O_RDONLY mqd_t (q4).  */
  /* Thread calls mq_notify (q4, NULL). */
  /* Thread calls mq_close (q4).  */

  (void) pthread_barrier_wait (b3);

  result |= mqsend (q);
  result |= mqrecv (q);

  (void) pthread_barrier_wait (b3);

  /* Child verifies SIGRTMIN has not been sent.  */
  /* Child calls mq_notify (q, { SIGEV_SIGNAL }).  */

  (void) pthread_barrier_wait (b3);

  /* Thread opens a new O_WRONLY mqd_t (q5).  */
  /* Thread calls mq_notify (q5, NULL). */
  /* Thread calls mq_close (q5).  */

  (void) pthread_barrier_wait (b3);

  result |= mqsend (q);
  result |= mqrecv (q);

  (void) pthread_barrier_wait (b3);

  /* Child verifies SIGRTMIN has not been sent.  */

  int status;
  if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
    {
      puts ("waitpid failed");
      kill (pid, SIGKILL);
      result = 1;
    }
  else if (!WIFEXITED (status) || WEXITSTATUS (status))
    {
      printf ("child failed with status %d\n", status);
      result = 1;
    }

  if (mq_unlink (name) != 0)
    {
      printf ("mq_unlink failed: %m\n");
      result = 1;
    }

  if (mq_close (q) != 0)
    {
      printf ("mq_close failed: %m\n");
      result = 1;
    }

  if (mq_notify (q, NULL) == 0)
    {
      puts ("mq_notify on closed mqd_t unexpectedly succeeded");
      result = 1;
    }
  else if (errno != EBADF)
    {
      printf ("mq_notify on closed mqd_t did not fail with EBADF: %m\n");
      result = 1;
    }

  memset (&ev, 0x55, sizeof (ev));
  ev.sigev_notify = SIGEV_NONE;
  if (mq_notify (q, &ev) == 0)
    {
      puts ("mq_notify on closed mqd_t unexpectedly succeeded");
      result = 1;
    }
  else if (errno != EBADF)
    {
      printf ("mq_notify on closed mqd_t did not fail with EBADF: %m\n");
      result = 1;
    }

  return result;
}
Esempio n. 10
0
static void __init check_sysemu(void)
{
	unsigned long regs[MAX_REG_NR];
	int pid, n, status, count=0;

	non_fatal("Checking syscall emulation patch for ptrace...");
	sysemu_supported = 0;
	pid = start_ptraced_child();

	if (ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0)
		goto fail;

	CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
	if (n < 0)
		fatal_perror("check_sysemu : wait failed");
	if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
		fatal("check_sysemu : expected SIGTRAP, got status = %d\n",
		      status);

	if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
		fatal_perror("check_sysemu : PTRACE_GETREGS failed");
	if (PT_SYSCALL_NR(regs) != __NR_getpid) {
		non_fatal("check_sysemu got system call number %d, "
			  "expected %d...", PT_SYSCALL_NR(regs), __NR_getpid);
		goto fail;
	}

	n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, os_getpid());
	if (n < 0) {
		non_fatal("check_sysemu : failed to modify system call "
			  "return");
		goto fail;
	}

	if (stop_ptraced_child(pid, 0, 0) < 0)
		goto fail_stopped;

	sysemu_supported = 1;
	non_fatal("OK\n");
	set_using_sysemu(!force_sysemu_disabled);

	non_fatal("Checking advanced syscall emulation patch for ptrace...");
	pid = start_ptraced_child();

	if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
		   (void *) PTRACE_O_TRACESYSGOOD) < 0))
		fatal_perror("check_sysemu: PTRACE_OLDSETOPTIONS failed");

	while (1) {
		count++;
		if (ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
			goto fail;
		CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
		if (n < 0)
			fatal_perror("check_sysemu: wait failed");

		if (WIFSTOPPED(status) &&
		    (WSTOPSIG(status) == (SIGTRAP|0x80))) {
			if (!count) {
				non_fatal("check_sysemu: SYSEMU_SINGLESTEP "
					  "doesn't singlestep");
				goto fail;
			}
			n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET,
				   os_getpid());
			if (n < 0)
				fatal_perror("check_sysemu : failed to modify "
					     "system call return");
			break;
		}
		else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
			count++;
		else {
			non_fatal("check_sysemu: expected SIGTRAP or "
				  "(SIGTRAP | 0x80), got status = %d\n",
				  status);
			goto fail;
		}
	}
	if (stop_ptraced_child(pid, 0, 0) < 0)
		goto fail_stopped;

	sysemu_supported = 2;
	non_fatal("OK\n");

	if (!force_sysemu_disabled)
		set_using_sysemu(sysemu_supported);
	return;

fail:
	stop_ptraced_child(pid, 1, 0);
fail_stopped:
	non_fatal("missing\n");
}
Esempio n. 11
0
static int basic_test(void)
{
	pid_t pid;
	int fd, sem_id, status, ret = 0;
	unsigned long i, j, chunk_no = 0, num_chunks = 0;
	struct write_unit wu;

	sem_id = semaphore_init(1);
	if (sem_id < 0)
		return sem_id;

	num_chunks = file_size / CHUNK_SIZE;

	open_rw_flags |= O_DIRECT;
	open_ro_flags |= O_DIRECT;

	if (test_flags & BASC_TEST) {
		fprintf(stdout, "# Prepare file in %lu length.\n", file_size);
		ret = prep_orig_file_in_chunks(workfile, file_size);
		if (ret)
			return ret;
	}

	fflush(stderr);
	fflush(stdout);

	signal(SIGCHLD, sigchld_handler);

	fd = open_file(workfile, open_rw_flags);
	if (fd < 0)
		return fd;

	if (test_flags & FIHL_TEST) {
		fprintf(stdout, "# Reserve a hole by truncating file to %lu.\n",
			file_size);
		ret = ftruncate(fd, file_size);
		if (ret) {
			ret = errno;
			fprintf(stderr, "ftruncate faile:%d,%s\n",
				ret, strerror(ret));
			return ret;
		}
	}

	fprintf(stdout, "# Fork %lu processes performing writes.\n",
		num_children);
	for (i = 0; i < num_children; i++) {

		pid = fork();

		if (pid < 0) {
			fprintf(stderr, "Fork process error!\n");
			return pid;
		}

		if (pid == 0) {

			srand(getpid());

			for (j = 0; j < num_chunks; j++) {
				if (verbose) 
					fprintf(stdout, "  #%d process writes "
						"#%lu chunk\n", getpid(),
						chunk_no);

				if (semaphore_p(sem_id) < 0) {
					ret = -1;
					goto child_bail;
				}

				if (test_flags & APPD_TEST)
					chunk_no = j;
				else
					chunk_no = get_rand_ul(0, num_chunks - 1);

				prep_rand_dest_write_unit(&wu, chunk_no);

				ret = do_write_chunk(fd, wu);
				if (ret < 0)
					goto child_bail;

				ret = log_write(&wu, log);
				if (ret < 0)
					goto child_bail;

				if (semaphore_v(sem_id) < 0) {
					ret = -1;
					goto child_bail;
				}

				usleep(10000);

				if (!(test_flags & DSCV_TEST))
					continue;

				/*
				 * Are you ready to crash the machine?
				 */

				if ((j > 1) && (j < num_chunks - 1)) {
					if (get_rand_ul(1, num_chunks) == num_chunks / 2) {

						if (semaphore_p(sem_id) < 0) {
							ret = -1;
							goto child_bail;
						}

						fprintf(stdout, "#%d process "
							"tries to crash the "
							"box.\n", getpid());
						if (system("echo b>/proc/sysrq-trigger") < 0) {
							fprintf(stderr, "#%d process "
								"tries to enable sysrq-trigger "
								"but failed.\n", getpid());
							goto child_bail;
						}
					}
				} else if (j == num_chunks - 1) {

						if (semaphore_p(sem_id) < 0) {
							ret = -1;
							goto child_bail;
						}

						fprintf(stdout, "#%d process "
							"tries to crash the "
							"box.\n", getpid());
						if (system("echo b>/proc/sysrq-trigger") < 0) {
							fprintf(stderr, "#%d process "
								"tries to enable sysrq-trigger "
								"but failed.\n", getpid());
							goto child_bail;
						}
				}
			}
child_bail:
			if (fd)
				close(fd);

			if (ret > 0)
				ret = 0;

			exit(ret);
		}

		if (pid > 0)
			child_pid_list[i] = pid;
	}

	signal(SIGINT, sigint_handler);
	signal(SIGTERM, sigterm_handler);

	for (i = 0; i < num_children; i++) {
		waitpid(child_pid_list[i], &status, 0);
		ret = WEXITSTATUS(status);
		if (ret) {
			fprintf(stderr, "Child %d exits abnormally with "
				"RC=%d\n", child_pid_list[i], ret);
		}
	}

	if (fd)
		close(fd);

	if (sem_id)
		semaphore_close(sem_id);

	return ret;
}
Esempio n. 12
0
RTR3DECL(int)   RTProcWaitNoResume(RTPROCESS Process, unsigned fFlags, PRTPROCSTATUS pProcStatus)
{
    /*
     * Validate input.
     */
    if (Process <= 0)
    {
        AssertMsgFailed(("Invalid Process=%d\n", Process));
        return VERR_INVALID_PARAMETER;
    }
    if (fFlags & ~(RTPROCWAIT_FLAGS_NOBLOCK | RTPROCWAIT_FLAGS_BLOCK))
    {
        AssertMsgFailed(("Invalid flags %#x\n", fFlags));
        return VERR_INVALID_PARAMETER;
    }

    /*
     * Perform the wait.
     */
    int iStatus = 0;
    int rc = waitpid(Process, &iStatus, fFlags & RTPROCWAIT_FLAGS_NOBLOCK ? WNOHANG : 0);
    if (rc > 0)
    {
        /*
         * Fill in the status structure.
         */
        if (pProcStatus)
        {
            if (WIFEXITED(iStatus))
            {
                pProcStatus->enmReason = RTPROCEXITREASON_NORMAL;
                pProcStatus->iStatus = WEXITSTATUS(iStatus);
            }
            else if (WIFSIGNALED(iStatus))
            {
                pProcStatus->enmReason = RTPROCEXITREASON_SIGNAL;
                pProcStatus->iStatus = WTERMSIG(iStatus);
            }
            else
            {
                Assert(!WIFSTOPPED(iStatus));
                pProcStatus->enmReason = RTPROCEXITREASON_ABEND;
                pProcStatus->iStatus = iStatus;
            }
        }
        return VINF_SUCCESS;
    }

    /*
     * Child running?
     */
    if (!rc)
    {
        Assert(fFlags & RTPROCWAIT_FLAGS_NOBLOCK);
        return VERR_PROCESS_RUNNING;
    }

    /*
     * Figure out which error to return.
     */
    int iErr = errno;
    if (iErr == ECHILD)
        return VERR_PROCESS_NOT_FOUND;
    return RTErrConvertFromErrno(iErr);
}
Esempio n. 13
0
static int execute_normally(command_t c){
  switch (c->type)
  {
    case AND_COMMAND:
    {
       if(execute_normally(c->u.command[0])) {
          return execute_normally(c->u.command[1]);
       }
       else //left side failed
          return 0;
    }
    case SEQUENCE_COMMAND:
    {
       int temp_ = 0;
       if(!execute_normally(c->u.command[0])) { temp_++; }
       if(!execute_normally(c->u.command[1])) { temp_++; }
       return !temp_;
    }
    case OR_COMMAND:
    {
       if(execute_normally(c->u.command[0])) {
          return 1;
       }
       else //left side failed
          return execute_normally(c->u.command[1]);
    }
    case PIPE_COMMAND:
    {
        pid_t p1 =fork();
        if(p1==0) {//child  
          int fd[2];

          if(pipe(fd)<0)
            error(FAIL, 0, "Failed to create pipe.");
          //printf("%s | %s\n", left, right);
          pid_t p = fork();
          if(p==0) { //child
              close(fd[0]); //close fd thats not being used 
              dup2(fd[1], 1); //duplicate fd1 to stdout
              close(fd[1]);
              if(!execute_normally(c->u.command[0])) {
                exit(FAIL);
              }
              exit(1);
          }
          else { //parent process
              close(fd[1]);
              dup2(fd[0], 0); //duplicate fd0 to stdin
              close(fd[0]);

              //check for error
              
              int status;
              if(waitpid(p, &status, 0)<0) { 
                  exit(FAIL);
              }
            
              if(WEXITSTATUS(status) == FAIL ) {
                  kill(p, SIGKILL);
                  exit(FAIL);
              }
              kill(p, SIGKILL);
              //printf("%s\n", right);
              //execute command
              char* term = strtok(*(c->u.command[1]->u.word), " ");
              char* file = term;
              char* arr[100]; 
              int i = 0;
              while(term!=NULL) {
                  arr[i] = term;
                  term = strtok(NULL, " ");
                  i++;
              }
              arr[i]=NULL;

              //sleep(1);
              execvp(file, arr);
              error(FAIL, 0, "Failed on pipe command: |%s", *(c->u.command[1]->u.word) );
              exit(FAIL);
          }
          exit(1);
        }
        else { //grandparent
              //check for error
              int status;
              if(waitpid(p1, &status, 0)<0) {
                  return 0;
              }
            
              if(WEXITSTATUS(status) == FAIL ) {
                  kill(p1, SIGKILL);
                  return 0;    
              }
              kill(p1, SIGKILL);
              return 1;
        }

    }
    case SIMPLE_COMMAND:
    {
       //execute c->u.word which is a char **

    return execute(*c->u.word, c->input, c->output);
    }

    case SUBSHELL_COMMAND: 
    {      
      pid_t sp = fork();
      if(sp == 0){
        int fp = -1;
        if(c->input != NULL) {
          int fd = open(c->input, O_RDONLY);
          if(fd < 0) {
              error(0, 0, "Failed to open file: %s\n", c->input);
              _exit(FAIL);
          }
          dup2(fd, 0);
        }
        if(c->output != NULL) { 
          fp = open(c->output, O_WRONLY | O_CREAT | O_TRUNC, 0666);
          if(fp < 0) {
              error(0, 0, "Failed to open file: %s\n", c->output);
              _exit(FAIL);
          }
          dup2(fp, 1);
        }

      if(0 == execute_normally(c->u.subshell_command)){
        _exit(FAIL);
      }
      else {
        _exit(987);
         }
      }
       else{
    int status;
    if(waitpid(sp, &status, 0)<0)
      return 0;
    if(WEXITSTATUS(status) == FAIL){
      kill(sp, SIGKILL);
      return 0;
    }
    kill(sp, SIGKILL);
    return 1;

          }
     
  }
    default:
        abort ();
    }

//  if (c->input)
//    printf ("<%s", c->input);
//  if (c->output)
//    printf (">%s", c->output);

   return 1;
}
Esempio n. 14
0
int execute(char* command, char* input, char* output) {
    if(command == NULL) { return 0; }
    char* term = strtok(command, " ");
    
    int orig = dup(1);
    int fp = -1, fd = -1;
    if(input != NULL) {
      fd = open(input, O_RDONLY);
      if(fd < 0) {
          close(fd);
          error(0, 0, "Failed to open file: %s\n", input);
          return 0;
      }
      dup2(fd, 0);
    }
    if(output != NULL) { 
      fp = open(output, O_WRONLY | O_CREAT | O_TRUNC, 0666);
      if(fp < 0) {
          close(fp);
          error(0, 0, "Failed to open file: %s\n", output);
          return 0;
      }
      dup2(fp, 1);
    }
    pid_t p = 0;
    char temp[5];
    strncpy(temp, command,4);
    temp[4] = '\0';
    //check if it is an exec command
    if(0 != strcmp("exec",temp)){ 
       p = fork();
    }

    if(p==0){ //child
      char* arr[100]; 
      int i = 0;
      while(term!=NULL) {
        if(i == 0 && 0 == strcmp(term, "exec")){ 
        }
        else{
          arr[i] = term;
          i++;
        }
        term = strtok(NULL, " ");
      }
      arr[i]=NULL;
      if(strncmp(arr[0], "false", 5)==0)
        exit(FAIL);

      execvp(arr[0], arr);
      error(FAIL, 0, "Command failed: %s", command);
      exit(FAIL);
    }
    else{
      if(input != NULL && fd>0) {
        dup2(orig, 1);
        close(fd);
      }
      if(output != NULL && fp>0) { 
        dup2(orig, 1);
        close(fp);
      }
      int status;
      if(waitpid(p, &status, 0)<0) {
          return 0;
      }
      if(WEXITSTATUS(status) == FAIL ) {
          kill(p, SIGKILL);
          return 0;    
       }
      kill(p,SIGKILL);  

      return 1;
    }

  return 0;
}
Esempio n. 15
0
int
runRedirector(pid_t *pid_return, int *read_fd_return, int *write_fd_return)
{
    int rc, rc2, status;
    pid_t pid;
    int filedes1[2], filedes2[2];
    sigset_t ss, old_mask;

    assert(redirector);

    if(redirector_buffer == NULL) {
        redirector_buffer = malloc(REDIRECTOR_BUFFER_SIZE);
        if(redirector_buffer == NULL)
            return -errno;
    }

    rc = pipe(filedes1);
    if(rc < 0) {
        rc = -errno;
        goto fail1;
    }


    rc = pipe(filedes2);
    if(rc < 0) {
        rc = -errno;
        goto fail2;
    }

    fflush(stdout);
    fflush(stderr);
    flushLog();

    interestingSignals(&ss);
    do {
        rc = sigprocmask(SIG_BLOCK, &ss, &old_mask);
    } while (rc < 0 && errno == EINTR);
    if(rc < 0) {
        rc = -errno;
        goto fail3;
    }

    pid = fork();
    if(pid < 0) {
        rc = -errno;
        goto fail4;
    }

    if(pid > 0) {
        do {
            rc = sigprocmask(SIG_SETMASK, &old_mask, NULL);
        } while(rc < 0 && errno == EINTR);

        if(rc < 0) {
            rc = -errno;
            goto fail4;
        }

        rc = setNonblocking(filedes1[1], 1);
        if(rc >= 0)
            rc = setNonblocking(filedes2[0], 1);
        if(rc < 0) {
            rc = -errno;
            goto fail4;
        }

        /* This is completely unnecesary -- if the redirector cannot be
           started, redirectorStreamHandler1 will get EPIPE straight away --,
           but it improves error messages somewhat. */
        rc = waitpid(pid, &status, WNOHANG);
        if(rc > 0) {
            logExitStatus(status);
            rc = -EREDIRECTOR;
            goto fail4;
        } else if(rc < 0) {
            rc = -errno;
            goto fail4;
        }

        *read_fd_return = filedes2[0];
        *write_fd_return = filedes1[1];

        *pid_return = pid;
        /* This comes at the end so that the fail* labels can work */
        close(filedes1[0]);
        close(filedes2[1]);
    } else {
        close(filedes1[1]);
        close(filedes2[0]);
        uninitEvents();
        do {
            rc = sigprocmask(SIG_SETMASK, &old_mask, NULL);
        } while (rc < 0 && errno == EINTR);
        if(rc < 0)
            exit(142);

        if(filedes1[0] != 0)
            dup2(filedes1[0], 0);
        if(filedes2[1] != 1)
            dup2(filedes2[1], 1);

        execlp(redirector->string, redirector->string, NULL);
        exit(142);
        /* NOTREACHED */
    }
    return 1;

 fail4:
    do {
        rc2 = sigprocmask(SIG_SETMASK, &old_mask, NULL);
    } while(rc2 < 0 && errno == EINTR);
 fail3:
    close(filedes2[0]);
    close(filedes2[1]);
 fail2:
    close(filedes1[0]);
    close(filedes1[1]);
 fail1:
    free(redirector_buffer);
    redirector_buffer = NULL;
    return rc;
}
Esempio n. 16
0
int
mu_progmailer_send (struct _mu_progmailer *pm, mu_message_t msg)
{
  int status;
  mu_stream_t stream = NULL;
  char buffer[512];
  size_t len = 0;
  int rc;
  mu_header_t hdr;
  mu_body_t body;
  int found_nl = 0;
  int exit_status;
	
  if (!pm || !msg)
    return EINVAL;
  mu_message_get_header (msg, &hdr);
  status = mu_header_get_streamref (hdr, &stream);
  if (status)
    {
      mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
		("cannot get header stream: %s", mu_strerror (status)));
      return status;
    }
  mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE, ("Sending headers..."));
  mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
  while ((status = mu_stream_readline (stream, buffer, sizeof (buffer),
				       &len)) == 0
	 && len != 0)
    {
      if (mu_c_strncasecmp (buffer, MU_HEADER_FCC, sizeof (MU_HEADER_FCC) - 1))
	{
	  mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_PROT, ("Header: %s", buffer));
	  if (write (pm->fd, buffer, len) == -1)
	    {
	      status = errno;
	      
	      mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
			("write failed: %s", strerror (status)));
	      break;
	    }
	}
      found_nl = (len == 1 && buffer[0] == '\n');
    }

  if (!found_nl)
    {
      if (write (pm->fd, "\n", 1) == -1)
	{
	  status = errno;
		
	  mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
		    ("write failed: %s", strerror (status)));
	}
    }
  mu_stream_destroy (&stream);
  
  mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE, ("Sending body..."));
  mu_message_get_body (msg, &body);
  status = mu_body_get_streamref (body, &stream);
  if (status)
    {
      mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
		("cannot get body stream: %s\n", mu_strerror (status)));
      return status;
    }

  mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
  while ((status = mu_stream_read (stream, buffer, sizeof (buffer),
				   &len)) == 0
	 && len != 0)
    {
      if (write (pm->fd, buffer, len) == -1)
	{
	  status = errno;
	  
	  mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
		    ("write failed: %s\n", strerror (status)));
	  break;
	}
    }
  mu_body_get_streamref (body, &stream);

  close (pm->fd);

  rc = waitpid (pm->pid, &exit_status, 0);
  if (status == 0)
    {
      if (rc < 0)
	{
	  if (errno == ECHILD)
	    status = 0;
	  else
	    { 
	      status = errno;
	      mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
			("waitpid(%lu) failed: %s\n",
			 (unsigned long) pm->pid, strerror (status)));
	    }
	}
      else if (WIFEXITED (exit_status))
	{
	  exit_status = WEXITSTATUS (exit_status);
	  mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE,
		    ("%s exited with: %d\n",
		     pm->command, exit_status));
	  status = (exit_status == 0) ? 0 : MU_ERR_PROCESS_EXITED;
	}
      else if (WIFSIGNALED (exit_status))
	status = MU_ERR_PROCESS_SIGNALED;
      else
	status = MU_ERR_PROCESS_UNKNOWN_FAILURE;
    }
  pm->pid = -1;
  return status;
}
Esempio n. 17
0
/*
** Implement an HTTP server daemon.
*/
HttpRequest*
http_server(struct in_addr address, int iPort)
{
  int                listener;      /* The server socket */
  int                connection;    /* A socket for each connection */
  fd_set             readfds;       /* Set of file descriptors for select() */
  socklen_t          lenaddr;       /* Length of the inaddr structure */
  int                child;         /* PID of the child process */
  int                nchildren = 0; /* Number of child processes */
  struct timeval     delay;         /* How long to wait inside select() */
  struct sockaddr_in inaddr;        /* The socket address */
  int                reuse = 1;
  int                n = 0;
  char               url_prefix[256];
  int                val; //not used

  /* catch SIGINT */
  (void) signal(SIGINT, sigint);

  /* catch SIGTERM */
  (void) signal(SIGTERM, sigterm);

  memset(&inaddr, 0, sizeof(inaddr));
  inaddr.sin_family = AF_INET;
  inaddr.sin_addr.s_addr = address.s_addr;
  inaddr.sin_port = htons(iPort);
  listener = socket(AF_INET, SOCK_STREAM, 0);

  fprintf(stderr,"DidiWiki firing up ...\n");

  if( listener < 0 )
  {
    fprintf(stderr,"Can't create a socket\n");
    exit(1);
  }

#ifdef SO_REUSEADDR
  setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); 
#endif

  while (n < 10)
  {
    fprintf(stderr,"Attempting to bind to %s:%i .. ", inet_ntoa(address), iPort);

    inaddr.sin_port = htons(iPort + n);

    if( bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr)) < 0 )
    {
      fprintf(stderr,"Failed! \n");
      n++;
      continue;
    }

    fprintf(stderr,"Success! \n");
    break;
  }

  if (n == 10)
  {
    fprintf(stderr,"Can't bind to any ports, giving up.\n");
    exit(1);
  }

  fprintf(stderr,"DidiWiki Started. Please point your browser at %s:%i\n", inet_ntoa(address), iPort);

  /* log starting information */
  openlog("didiwiki", 0, 0);
  syslog(LOG_LOCAL0|LOG_INFO, "started with PID %d", getpid());

  /* Set DIDIWIKI_URL_PREFIX if not already set - rss uses it */
  snprintf(url_prefix, 256, "%s:%i/", inet_ntoa(address), iPort+n);
  setenv("DIDIWIKI_URL_PREFIX", url_prefix , 0);

  listen(listener,10);
  
  /* Listen undefinitely */
  while( 1 )
  {
    if( nchildren>MAX_PARALLEL )
    {
      /* Slow down if connections are arriving too fast */
      sleep( nchildren-MAX_PARALLEL );
    }

    delay.tv_sec = 60;
    delay.tv_usec = 0;
    FD_ZERO(&readfds);
    FD_SET( listener, &readfds);

    if( select( listener+1, &readfds, 0, 0, &delay) )
    {
      lenaddr = sizeof(inaddr);
      connection = accept(listener, (struct sockaddr*)&inaddr, &lenaddr);
      if( connection>=0 )
      {
        child = fork();
        if( child!=0 )
        {
          if( child>0 ) nchildren++;
          close(connection);
        }
        else
        {
          /* *child*, connect stdin/out to socket */
          /* then return req object for caller to handle */
          close(0);
          val = dup(connection);
          close(1);
          val = dup(connection);
          close(2);
          val = dup(connection);
          close(connection);
          return http_request_new();
        }
	    }
    }
    /* Bury dead children */
    while( waitpid(0, 0, WNOHANG)>0 ) nchildren--;
  }
  /* NOT REACHED */  
  exit(1);
}
Esempio n. 18
0
void do_command(int sum,char arglist[100][256])    //执行命令
{
    int flag =0;      //若flag>1,说明命令中含多个>,<,|或格式不正确
    int how=0;    //记录命令中是否含有>,<,|
    int background=0;  //记录命令中是否有&
    pid_t pid;
    int fd;
    int i;
    char* file;      //记录文件名
    char** arg;      //记录命令
    char** argnext;   // 记录管道命令
    arg=(char**)malloc(sizeof(char*)*(sum+1));
    argnext=(char**)malloc(sizeof(char*)*(sum+1));
    for(i=0;i<sum;i++)  //将命令取出
    arg[i]=arglist[i];
    arg[i]=NULL;


    if(strcmp(arg[0],"cd")==0)   //判断是否cd命令
    {
        cd_command(arg);
        return;
    }

    if(strcmp(arg[0],"ls")==0)  //给ls命令默认设置为--color=auto
    {
        i=0;
        while(arg[i]!=NULL)
        i++;
        if(strcmp(arg[i-1],"&")==0)
        {
            arg[i-1]="--color=auto";
            arg[i]="&";
            arg[i+1]=NULL;
        }
        else
        {
        arg[i]="--color=auto";
        arg[++i]=NULL;

        }
    }

    for(i=0;arg[i]!=NULL;i++)  //判断是否含有&
    {
    
        if(strcmp(arg[i],"&")==0)
        {
            if(arg[i+1]!=NULL&&strcmp(arg[0],"ls")!=0)
            {
                printf("wrong command\n");
                return;
            }

        
            else
           {
                 background=1;
                arg[i]=NULL;
                  break;
           }
        }
    }
     
    for(i=0;arg[i]!=NULL;i++)  //判断是否有>,<,|
    {
        
        if(strcmp(arg[i],">")==0)
        {
        
            flag++;
            how=out_redirect;
            if(i==0)
            flag++;
            if(i==sum-1)
            flag++;
        }
    
        if(strcmp(arg[i],"<")==0)
        {
            flag++;
            how=in_redirect;
            if(i==0)
            flag++;
            if(i==sum-1)
            flag++;
        } 
        if(strcmp(arg[i],"|")==0)
        {
            flag++;
            how=have_pipe;
            if(i==0)
            flag++;
            if(arg[i+1]==NULL)
            flag++;
        }

    }

       
    if(flag>1)
    {
        printf("wrong command\n");
        return;
    }

    if(how==out_redirect)
    {
        for(i=0;arg[i]!=NULL;i++)
        if(strcmp(arg[i],">")==0)
        break;
        file=arg[i+1];
        arg[i]=NULL;

    }

    if(how==in_redirect)
    {
        for(i=0;arg[i]!=NULL;i++)
        if(strcmp(arg[i],"<")==0)
        break;
        file=arg[i+1];
        arg[i]=NULL;
    }

    if(how==have_pipe)
    {
        for(i=0;arg[i]!=NULL;i++)
        if(strcmp(arg[i],"|")==0)
        break;
        arg[i]=NULL;
        int j=i+1;
        for(j;arg[j]!=NULL;j++)
        argnext[j-i-1]=arg[j];
        argnext[j-i-1]=arg[j];
    }
    
    
    if((pid=fork())<0)
    {
        printf("creat process error \n");
        return;

    }

        switch(how)
        {
            case normal:
            if(pid==0)
            {
                if(!find_command(arg[0]))
                {
                    printf("未找到'%s'命令\n",arg[0]);
                    exit(1);
                }
                execvp(arg[0],arg);
                exit(0);
            } 
            break;
            case out_redirect:
            if(pid==0)
            {
                if(!find_command(arg[0]))
                {
                    printf("未找到'%s'命令\n",arg[0]);
                    exit(1);
                }
                if((fd=open(file,O_RDWR|O_CREAT|O_TRUNC,0644))==-1)
                {
                    printf("creat file error\n");
                    exit(1);
                }
                if (dup2(fd,1) < 0) {
                    perror("dup2");
                }
                if(execvp(arg[0],arg)==-1)
                {
                    printf("do command error\n");
                    exit(1);

                }
                exit(0);
            }
            break;
            case in_redirect:
            if(pid==0)
            {
                if(!find_command(arg[0]))
                {
                    printf("未找到'%s'命令\n",arg[0]);
                    exit(1);
                }
                if((fd=open(file,O_RDWR))==-1)
                {
                    printf("read file error\n");
                    exit(1);
                }
                dup2(fd,0);
                execvp(arg[0],arg);
                exit(0);
            } 
            break;
            case have_pipe:
            if(pid==0)
            {
                int pid2;
                int fd2;
                if((pid2=fork())<0)
                {
                    printf("fork2 error\n");
                    exit(1);
                }
                if(pid2==0)
                {
                    if(!find_command(arg[0]))
                    {
                        printf("未找到'%s'命令\n",arg[0]);
                        return;
                    }

                    if((fd2=open("/tmp/temp.txt",O_RDWR|O_CREAT|O_TRUNC,0644))==-1)
                    {
                        printf("open dir error\n");
                        exit(0);
                    }
                    dup2(fd2,1);
                    execvp(arg[0],arg);
                    exit(0);
                }

                if(waitpid(pid2,NULL,0)==-1)
                printf("wait for child process error\n");
                if(!find_command(argnext[0]))
                {
                    printf("未找到命令'%s'\n",argnext[0]);
                    return;
                }
                if((fd=open("/tmp/temp.txt",O_RDONLY))==-1)
                printf("open file error\n");
                dup2(fd,0);
                execvp(argnext[0],argnext);
                exit(0);
            }
        default:
            break;
        }
        if(background)
        {
            printf("[process id %d]\n",pid);
            return;
        }
    else
    if(waitpid(pid,NULL,0)==-1)
    {
        printf("wait for child process error\n");
        return;
    }


}
Esempio n. 19
0
static void run_monitored(char *executable, int argc, char **argv) {
  int pid;
  const char *t = getenv("KLEE_REPLAY_TIMEOUT");  
  if (!t)
    t = "10000000";  
  monitored_timeout = atoi(t);
  
  if (monitored_timeout==0) {
    fprintf(stderr, "ERROR: invalid timeout (%s)\n", t);
    _exit(1);
  }

  /* Kill monitored process(es) on SIGINT and SIGTERM */
  signal(SIGINT, int_handler);
  signal(SIGTERM, int_handler);
  
  signal(SIGALRM, timeout_handler);
  pid = fork();
  if (pid < 0) {
    perror("fork");
    _exit(66);
  } else if (pid == 0) {
    /* This process actually executes the target program.
     *  
     * Create a new process group for pid, and the process tree it may spawn. We
     * do this, because later on we might want to kill pid _and_ all processes
     * spawned by it and its descendants.
     */
    setpgrp();

    if (!rootdir) {
      execv(executable, argv);
      perror("execv");
      _exit(66);
    }

    fprintf(stderr, "rootdir: %s\n", rootdir);
    const char *msg;
    if ((msg = "chdir", chdir(rootdir) == 0) &&
      (msg = "chroot", chroot(rootdir) == 0)) {
      msg = "execv";
      executable = strip_root_dir(executable, rootdir);
      argv[0] = strip_root_dir(argv[0], rootdir);
      execv(executable, argv);
    }
    perror(msg);
    _exit(66);
  } else {
    /* Parent process which monitors the child. */
    int res, status;
    time_t start = time(0);
    sigset_t masked;

    sigemptyset(&masked);
    sigaddset(&masked, SIGALRM);

    monitored_pid = pid;
    alarm(monitored_timeout);
    do {
      res = waitpid(pid, &status, 0);
    } while (res < 0 && errno == EINTR);

    if (res < 0) {
      perror("waitpid");
      _exit(66);
    }
    
    /* Just in case, kill the process group of pid.  Since we called setpgrp()
       for pid, this will not kill us, or any of our ancestors */
    kill(-pid, SIGKILL);
    process_status(status, time(0) - start, 0);
  }
}
Esempio n. 20
0
int
doXferRcp(lsRcpXfer *lsXfer, int option )
{

    pid_t    pid;
    int    rcpp[2], sourceFh;
    char   errMsg[1024];
    char   szRshDest[MAXLINELEN];
    int    cc, i, local_errno, n, status;
    char fname[]="doXferRcp";

    if (   (lsXfer->iOptions & O_APPEND)
        || ( option & SPOOL_BY_LSRCP)

       ) {
        if (logclass & (LC_FILE))
            ls_syslog(LOG_DEBUG, "%s: using %s to copy '%s' to '%s'",
                    fname, RSHCMD, lsXfer->ppszHostFnames[0],
		    lsXfer->ppszDestFnames[0]);
        if (pipe(rcpp) < 0) {
            return -1;
        }

        switch(pid = fork()) {
            case 0:

		close(rcpp[0]);

                if (rcpp[1]) {
		    if (logclass & (LC_FILE))
                        ls_syslog(LOG_DEBUG,
				  "%s: child: re-directing stdout, stderr",
			          fname);
                    close(STDOUT_FILENO);
                    close(STDERR_FILENO);
                    if (dup2(rcpp[1],STDOUT_FILENO) < 0)
                        return -1;

                    if (dup2(rcpp[1],STDERR_FILENO) < 0)
                        return -1;

                    close(rcpp[1]);
                }

                if ((sourceFh =
			   open(lsXfer->ppszHostFnames[0], O_RDONLY, 0)) < 0) {
                    return -1;
                } else {
                    close(STDIN_FILENO);
                    if (dup2(sourceFh,STDIN_FILENO))
                        return -1;

                    close(sourceFh);
                }

                if ( ( option & SPOOL_BY_LSRCP ) ) {
                    sprintf(szRshDest, "cat > %s",lsXfer->ppszDestFnames[0]);
                } else {
                    sprintf(szRshDest, "cat >>! %s",lsXfer->ppszDestFnames[0]);
                }
                execlp(RSHCMD, RSHCMD, lsXfer->szDest, szRshDest, NULL);
                return -1;
                break;

            case -1:
		if (logclass & (LC_FILE))
                    ls_syslog(LOG_ERR,I18N_FUNC_FAIL_M,fname,"fork" );
                close(rcpp[0]);
                close(rcpp[1]);
                return -1;

            default:
                close(rcpp[1]);

                cc = read(rcpp[0], errMsg, 1024);
                for (i = cc; cc > 0;) {
                    cc = read(rcpp[0], errMsg+i, 1024-i);
                    if (cc > 0)
                        i += cc;
                }
                local_errno = errno;

                close(rcpp[0]);

                if (waitpid(pid, 0, 0) < 0 && errno != ECHILD) {
                    return -1;
                }

                if (cc < 0) {
                    fprintf(stderr, "%s\n", strerror(local_errno));
                    return -1;
                }

                if (i > 0) {
                    fprintf(stderr, "%s: %s", RSHCMD, errMsg);
                    return -1;
                }
                return 0;
            }
    } else {
	if (logclass & (LC_FILE))
            ls_syslog(LOG_DEBUG,"doXferRcp(), exec rcp");

        switch(pid = fork()) {
            case 0:
               execlp("rcp", "rcp","-p", lsXfer->szSourceArg, lsXfer->szDestArg, NULL);
               ls_syslog(LOG_ERR,I18N_FUNC_FAIL_M,fname,"execlp" );
               exit(-1);
               break;

            case -1:
               if (logclass & (LC_FILE))
                    ls_syslog(LOG_ERR,I18N_FUNC_FAIL_M,fname,"fork" );
               return -1;
               break;

            default:

               while ( (n = wait(&status)) < 0) {
                   if (errno != EINTR)
                       break;
               }

               if (WIFEXITED(status)) {
                       if ( WEXITSTATUS(status) == 0) return 0;
               }
              return -1;
       }

        return -1;
    }
}
Esempio n. 21
0
int main(void)
{
#ifdef _POSIX_MEMORY_PROTECTION
	char tmpfname[256];
	void *pa;
	size_t size = 1024;
	int fd;


	pid_t child;
	int status;
	int sig_num;

	snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_mmap_6_1_%d", getpid());
	unlink(tmpfname);
	fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);
	if (fd == -1) {
		printf("Error at open(): %s\n", strerror(errno));
		return PTS_UNRESOLVED;
	}
	unlink(tmpfname);

	child = fork();

	switch (child) {
	case 0:
		if (ftruncate(fd, size) == -1) {
			printf("Error at ftruncate(): %s\n",
			       strerror(errno));
			return PTS_UNRESOLVED;
		}

		pa = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
		if (pa == MAP_FAILED) {
			printf("Error at mmap: %s\n",
			       strerror(errno));
			return PTS_FAIL;
		}

		*(char *)pa = 'b';
		return 0;
	break;
	case -1:
		printf("Error at fork(): %s\n", strerror(errno));
		return PTS_UNRESOLVED;
	break;
	default:
	break;
	}

	waitpid(child, &status, WUNTRACED);
	close(fd);

	if (WIFSIGNALED(status)) {
		sig_num = WTERMSIG(status);
		printf("Child process terminated by signal %d\n", sig_num);
		if (sig_num == SIGSEGV) {
			printf("Got SIGSEGV when writing to the mapped memory, "
			       "without setting PROT_WRITE\n"
			       "Test PASSED\n");
			return PTS_PASS;
		}
	}

	if (WIFEXITED(status)) {
		if (WEXITSTATUS(status) == 0) {
			printf("Did not got SIGSEGV when writing to the mapped memory,"
			       " without setting PROT_WRITE\n"
			       "Test FAILED\n");
			return PTS_FAIL;
		}
	}

	printf("Test Unresolved\n");
	return PTS_UNRESOLVED;
#else
	printf("Test Unsupported, _POSIX_MEMORY_PROTECTION not defined\n");
	return PTS_UNSUPPORTED;
#endif
}
Esempio n. 22
0
bool Process::Wait()
{
	pid_t pid = waitpid(m_pid, &m_status, 0);
	return (pid != m_pid);
}
Esempio n. 23
0
void execute(char *cmdline, char **argv)
{
  char *cmd = cmdline;
  if(strlen(cmd) > 4)
  {
    if(strncmp(cmd, "res=", 4)==0)
    {
      point5(cmdline);
      return;
    }
  }

  if(strlen(cmdline)<=0)
    return;

  // 0 for stdout; 1 for redirect; 2 for pipeline
  int out_type = 0;

  char *childcmd[2];
  childcmd[0] = cmdline;

  while(*cmdline != '>' && *cmdline != '|' &&
      *cmdline != '$' &&
      *cmdline != '\0' && *cmdline != '\n')
  {
    cmdline++;
  }
  if(*cmdline=='>')
  {
    out_type = 1;
    *cmdline++ = '\0';
    childcmd[1] = cmdline;
  }
  else if(*cmdline=='|')
  {
    out_type = 2;
    *cmdline++ = '\0';
    childcmd[1] = cmdline;
  }
  else if(*cmdline=='$')
  {
    if(strncmp(cmdline, "$(", 2)==0)
    {
      out_type = 3;
      *cmdline++ = '\0';
      childcmd[1] = cmdline;
    }
  }

  int n = strlen(childcmd[0]) - 1;
  while(n>0)
  {
    if(childcmd[0][n]==' ')
    {
      childcmd[0][n]='\0';
    }
    else
      break;
    n--;
  }

  while(*childcmd[1] != '\0')
  {
    if(*childcmd[1]==' ')
      childcmd[1]++;
    else
      break;
  }

  parse_cmdline(childcmd[0], argv);

  int ret = handle_builtin(argv);
  if(ret==0)
    return;

  pid_t childpid;
  int status, options = 0;

  childpid = fork();
  if (childpid == -1)
  {
    perror("Cannot proceed. fork() error");
    exit(1);
  }
  else if (childpid == 0)
  {
    // This is child's process.
    if(out_type==0)
    {
      childexec(argv);
    }
    else if(out_type==1)
    {// output redirection here
      int fd;
      close(STDOUT);
      fd = open(childcmd[1], O_APPEND);
      if(fd<0)
      {
        fd = creat(childcmd[1], 0666);
        if(fd<0)
        {
          perror("create file failed");
          exit(-1);
        }
      }
      dup(fd);
      childexec(argv);
      close(fd);
    }
    else if(out_type==2)
    {// pipeline here
      int fd[2];
      pipe(&fd[0]);
      if(fork()!=0)
      {
        close(fd[0]);
        close(STDOUT);
        dup(fd[1]);
        childexec(argv);
        close(fd[1]);
      }
      else
      {
        close(fd[1]);
        close(STDIN);
        dup(fd[0]);
        parse_cmdline(childcmd[1], argv);
        childexec(argv);
        close(fd[0]);
      }
      puts("\n");
    }
    else if(out_type==3)
    {
      childcmd[1]++;
      size_t len = strlen(childcmd[1]);
      childcmd[1][len-1] = '\0';

      printf("childcmd[0]:%s\n", childcmd[0]);
      printf("childcmd[1]:%s\n", childcmd[1]);

      int fd[2];
      pipe(fd);
      if(fork()!=0)
      {
        close(fd[1]);
        close(STDIN);
        dup(fd[0]);
        childexecline(childcmd[0]);
        close(fd[0]);
      }
      else
        exec_pipelines(childcmd[1], fd,argv);
      /*
      parse_cmdline(childcmd[1], argv);

      int fd[2];
      pipe(&fd[0]);
      if(fork()!=0)
      {
        close(fd[0]);
        close(STDOUT);
        dup(fd[1]);
        childexec(argv);
        close(fd[1]);
      }
      else
      {
        close(fd[1]);
        close(STDIN);
        dup(fd[0]);
        parse_cmdline(childcmd[0], argv);
        childexec(argv);
        close(fd[0]);
      }
      */
      puts("\n");
    }
  }
  else
  {
    waitpid(childpid, &status, options);
    if (!WIFEXITED(status))
      printf("Parent: child has not terminated normally.\n");
  }
}
Esempio n. 24
0
/* Thread function */
void * threaded(void * arg)
{
	int ret, status;
	pid_t child, ctl;

	/* Wait main thread has registered the handler */
	ret = pthread_mutex_lock(&mtx);

	if (ret != 0)
	{
		UNRESOLVED(ret, "Failed to lock mutex");
	}

	ret = pthread_mutex_unlock(&mtx);

	if (ret != 0)
	{
		UNRESOLVED(ret, "Failed to unlock mutex");
	}

	/* fork */
	child = fork();

	if (child == -1)
	{
		UNRESOLVED(errno, "Failed to fork");
	}

	/* child */
	if (child == 0)
	{
		if (nerrors)
		{
			FAILED("Errors occured in the child");
		}

		/* We're done */
		exit(PTS_PASS);
	}

	/* Parent joins the child */
	ctl = waitpid(child, &status, 0);

	if (ctl != child)
	{
		UNRESOLVED(errno, "Waitpid returned the wrong PID");
	}

	if (!WIFEXITED(status) || (WEXITSTATUS(status) != PTS_PASS))
	{
		FAILED("Child exited abnormally");
	}

	if (nerrors)
	{
		FAILED("Errors occured in the parent (only)");
	}

	/* quit */
	return NULL;
}
Esempio n. 25
0
File: unix.c Progetto: someara/core
int Unix_ShellCommandReturnsZero(char *comm, int useshell)
{
    int status;
    pid_t pid;

    if (!useshell)
    {
        /* Build argument array */

    }

    if ((pid = fork()) < 0)
    {
        FatalError("Failed to fork new process");
    }
    else if (pid == 0)          /* child */
    {
        ALARM_PID = -1;

        if (useshell)
        {
            if (execl(SHELL_PATH, "sh", "-c", comm, NULL) == -1)
            {
                CfOut(cf_error, "execl", "Command %s failed", comm);
                exit(1);
            }
        }
        else
        {
            char **argv = ArgSplitCommand(comm);

            if (execv(argv[0], argv) == -1)
            {
                CfOut(cf_error, "execv", "Command %s failed", argv[0]);
                exit(1);
            }
        }
    }
    else                        /* parent */
    {
# ifndef HAVE_WAITPID
        pid_t wait_result;
# endif
        ALARM_PID = pid;

# ifdef HAVE_WAITPID

        while (waitpid(pid, &status, 0) < 0)
        {
            if (errno != EINTR)
            {
                return -1;
            }
        }

        return (WEXITSTATUS(status) == 0);

# else

        while ((wait_result = wait(&status)) != pid)
        {
            if (wait_result <= 0)
            {
                CfOut(cf_inform, "wait", " !! Wait for child failed\n");
                return false;
            }
        }

        if (WIFSIGNALED(status))
        {
            return false;
        }

        if (!WIFEXITED(status))
        {
            return false;
        }

        return (WEXITSTATUS(status) == 0);
# endif
    }

    return false;
}
Esempio n. 26
0
int main(int argc, char *argv[])
{
	int err, c, status;
	pid_t pid;
	unsigned char flags[LastOpt];
	struct mntent ent;
	char *dev, *mntpnt, *opts, *cwd;
	DIR *cur;

	if (argc < 3) {
		errno = EINVAL;
		AuFin(NULL);
	}

	memset(flags, 0, sizeof(flags));
	flags[Update] = 1;
	opts = NULL;

	/* mount(8) always passes the arguments in this order */
	dev = argv[1];
	mntpnt = argv[2];
	while ((c = getopt(argc - 2, argv + 2, "nvo:")) != -1) {
		switch (c) {
		case 'n':
			flags[Update] = 0;
			break;
		case 'v':
			flags[Verbose] = 1;
			break;
		case 'o':
			opts = optarg;
			break;
		case '?':
		case ':':
			errno = EINVAL;
			AuFin("internal error");
		}
	}

	cur = opendir(".");
	if (!cur)
		AuFin(".");
	err = chdir(mntpnt);
	if (err)
		AuFin(mntpnt);
	cwd = getcwd(NULL, 0); /* glibc */
	if (!cwd)
		AuFin("getcwd");
	err = fchdir(dirfd(cur));
	if (err)
		AuFin("fchdir");
	closedir(cur); /* ignore */

	if (opts)
		test_opts(opts, flags);

	if (!flags[Bind] && flags[Update]) {
		err = access(MTab, R_OK | W_OK);
		if (err)
			AuFin(MTab);
	}

	if (flags[Remount]) {
		errno = EINVAL;
		if (flags[Bind])
			AuFin("both of remount and bind are specified");
		flags[AuFlush] = test_flush(opts);
		if (flags[AuFlush]) {
			err = au_plink(cwd, AuPlink_FLUSH, 1, 1);
			if (err)
				AuFin(NULL);
		}
	}

	pid = fork();
	if (!pid) {
		/* actual mount operation */
		do_mount(dev, mntpnt, argc, argv, flags);
		return 0;
	} else if (pid < 0)
		AuFin("fork");

	err = waitpid(pid, &status, 0);
	if (err < 0)
		AuFin("child process");

	err = !WIFEXITED(status);
	if (!err)
		err = WEXITSTATUS(status);

	if (!err && !flags[Bind]) {
		if (flags[Update])
			err = au_update_mtab(cwd, flags[Remount],
					     flags[Verbose]);
		else if (flags[Verbose]) {
			/* withoug blocking plink */
			err = au_proc_getmntent(cwd, &ent);
			if (!err)
				au_print_ent(&ent);
			else
				AuFin("internal error");
		}
	}

	return err;
}
int
scan_cd (_main_data * main_data)
{
  pid_t pid;
  char **argv;
  char tmp[MAX_COMMAND_LENGTH];
  int null_fd, pty_fd, tty_fd;
  int return_value;

  GtkWidget *main_window = main_window_handler(MW_REQUEST_MW, NULL, NULL);

  /* Open a pty */
  if (openpty (&pty_fd, &tty_fd, NULL, NULL, NULL))
    {
      err_handler (GTK_WINDOW(main_window), PTY_OPEN_ERR, NULL);
      return -1;
    }

  /* Open /dev/null */
  if ((null_fd = open ("/dev/null", O_WRONLY)) < 0)
    {
      err_handler (GTK_WINDOW(main_window), NULL_OPEN_ERR, NULL);
      return -1;
    }

  /* Create argvs */
  sprintf (tmp, "%s -Q", (char *) config_read (CONF_RPR_RIPPER));
  if ((argv = create_argv_for_execution_using_shell (tmp)) == NULL)
    return -1;

  /* Fork */
  if ((pid = fork ()) < 0)
    {
      err_handler (GTK_WINDOW(main_window), FORK_ERR, NULL);
      return -1;
    }

  if (pid == 0)
    {
      int stderr_fd;

      /* This code will be excuted in the child process */
      /* Save stderr before attaching to the tty */
      stderr_fd = dup (2);
      dup2 (tty_fd, 2);

      /* Throw away stdout to the black hole */
      dup2 (null_fd, 1);

      /* Execute cdparanoia */
      execvp (argv[0], argv);

      dup2 (stderr_fd, 2);
      perror (_("Failed to exec cdparanoia :"));
      _exit (127);
    }

  close (null_fd);

  return_value = process_cd_contents_output (main_data, pty_fd);
  /* Kill again the zombie */
  waitpid (pid, NULL, 0);

  return return_value;
}
Esempio n. 28
0
EAPI void 
e_alert_show(int sig) 
{
   char *args[4];
   pid_t pid;

#define E_ALERT_EXE "/enlightenment/utils/enlightenment_alert"

   args[0] = alloca(strlen(e_prefix_lib_get()) + strlen(E_ALERT_EXE) + 1);
   strcpy(args[0], e_prefix_lib_get());
   strcat(args[0], E_ALERT_EXE);

   args[1] = alloca(10);
   snprintf(args[1], 10, "%d", sig);

   args[2] = alloca(21);
   snprintf(args[2], 21, "%lu", (long unsigned int)getpid());

   args[3] = alloca(21);
   snprintf(args[3], 21, "%lu", e_alert_composite_win);

   pid = fork();
   if (pid < -1)
     goto restart_e;

   if (pid == 0)
     {
        /* The child process */
        execvp(args[0], args);
     }
   else
     {
        /* The parent process */
        pid_t ret;
        int status = 0;

        do
          {
             ret = waitpid(pid, &status, 0);
             if (errno == ECHILD)
               break ;
          }
        while (ret != pid);

        if (status == 0)
          goto restart_e;

        if (!WIFEXITED(status))
          goto restart_e;

        if (WEXITSTATUS(status) == 1)
          goto restart_e;

        exit(-11);
     }

 restart_e:
   if (getenv("E_START_MTRACK"))
     e_util_env_set("MTRACK", "track");
   ecore_app_restart();
}
Esempio n. 29
0
File: test.c Progetto: melo/pocs
int main (void)
{
    void *context = zmq_init (1);
    pid_t pid = fork();
    
    if (pid) {
      void *responder = zmq_socket (context, ZMQ_REP);
      //  Socket to talk to clients
      zmq_bind (responder, "ipc://xpto.sock");

      while (1) {
          //  Wait for next request from client
          zmq_msg_t request;
          zmq_msg_init (&request);
          zmq_recv (responder, &request, 0);
          
          char payload[10];
          int size = zmq_msg_size(&request);
          memcpy(payload, zmq_msg_data(&request), size);
          payload[size] = '\0';
          if (strncmp(payload, "quit", 4) == 0) {
            printf("[%d] Received '%s', sleep a bit\n", getpid(), payload);
            sleep(4);
            break;
          }
          
          printf ("[%d] Received '%s'\n", getpid(), payload);
          zmq_msg_close (&request);

          //  Do some 'work'
          sleep (1);

          //  Send reply back to client
          zmq_msg_t reply;
          zmq_msg_init_size (&reply, 5);
          memcpy (zmq_msg_data (&reply), "World", 5);
          zmq_send (responder, &reply, 0);
          zmq_msg_close (&reply);
      }
      //  We never get here but if we did, this would be how we end
      printf("[%d] Parent is cleaning up\n", getpid());
      zmq_close (responder);
      zmq_term (context);

      printf("[%d] waiting for child\n", getpid());
      int status;
      int rpid = waitpid(pid, &status, 0);
      printf("[%d] waited for pid %d, got %d status %d\n", getpid(), pid, rpid, status);
      printf("[%d] Parent is exiting\n", getpid());
    }
    else {
      context = zmq_init (1);

      //  Socket to talk to server
      printf ("[%d] Connecting to hello world server...\n", getpid());
      void *requester = zmq_socket (context, ZMQ_REQ);
      zmq_connect (requester, "ipc://xpto.sock");

      int request_nbr;
      zmq_msg_t request;
      for (request_nbr = 0; request_nbr != 2; request_nbr++) {
          zmq_msg_init_size (&request, 5);
          memcpy (zmq_msg_data (&request), "Hello", 5);
          printf ("[%d] Sending Hello %d...\n", getpid(), request_nbr);
          zmq_send (requester, &request, 0);
          zmq_msg_close (&request);

          zmq_msg_t reply;
          zmq_msg_init (&reply);
          zmq_recv (requester, &reply, 0);
          printf ("[%d] Received World %d\n", getpid(), request_nbr);
          zmq_msg_close (&reply);
      }

      zmq_msg_init_size (&request, 4);
      memcpy (zmq_msg_data (&request), "quit", 4);
      printf ("[%d] Sending quit...\n", getpid());
      zmq_send (requester, &request, 0);
      zmq_msg_close (&request);
      
      sleep(1);

      printf("[%d] Child is cleaning up\n", getpid());
      zmq_close (requester);
      zmq_term (context);
      printf("[%d] Child is exiting()\n", getpid());
      exit(0);
    }

    return 0;
}
Esempio n. 30
0
/* The main test function. */
int main( int argc, char * argv[] )
{
	int ret, status;
	pid_t child, ctl;

	sem_t * sem_linked, *sem_unlinked;

	/* Initialize output */
	output_init();

	sem_linked = sem_open( "/fork_14_1a", O_CREAT, O_RDWR, 0 );

	if ( sem_linked == SEM_FAILED )
	{
		UNRESOLVED( errno, "Failed to create the named semaphore" );
	}

	sem_unlinked = sem_open( "/fork_14_1b", O_CREAT, O_RDWR, 0 );

	if ( sem_unlinked == SEM_FAILED )
	{
		UNRESOLVED( errno, "Failed to create the named semaphore" );
	}

	ret = sem_unlink( "/fork_14_1b" );

	if ( ret != 0 )
	{
		UNRESOLVED( errno, "Failed to unlink the semaphore" );
	}

	/* Create the child */
	child = fork();

	if ( child == ( pid_t ) - 1 )
	{
		UNRESOLVED( errno, "Failed to fork" );
	}

	/* child */
	if ( child == ( pid_t ) 0 )
	{
		do
		{
			ret = sem_post( sem_linked );
		}
		while ( ( ret != 0 ) && ( errno == EINTR ) );

		if ( ret != 0 )
		{
			UNRESOLVED( errno, "Failed to post semaphore A" );
		}

		do
		{
			ret = sem_post( sem_unlinked );
		}
		while ( ( ret != 0 ) && ( errno == EINTR ) );

		if ( ret != 0 )
		{
			UNRESOLVED( errno, "Failed to post semaphore B" );
		}


		/* We're done */
		exit( PTS_PASS );
	}

	/* Parent joins the child */
	ctl = waitpid( child, &status, 0 );

	if ( ctl != child )
	{
		UNRESOLVED( errno, "Waitpid returned the wrong PID" );
	}

	if ( ( !WIFEXITED( status ) ) || ( WEXITSTATUS( status ) != PTS_PASS ) )
	{
		FAILED( "Child exited abnormally" );
	}

	/* Check both semaphores have been posted */
	do
	{
		ret = sem_trywait( sem_linked );
	}
	while ( ( ret != 0 ) && ( errno == EINTR ) );

	if ( ret != 0 )
	{
		if ( errno == EAGAIN )
		{
			FAILED( "Child did not inherit the semaphore A" );
		}
		else
		{
			UNRESOLVED( errno, "sem_trywait failed" );
		}
	}

	do
	{
		ret = sem_trywait( sem_unlinked );
	}
	while ( ( ret != 0 ) && ( errno == EINTR ) );

	if ( ret != 0 )
	{
		if ( errno == EAGAIN )
		{
			FAILED( "Child did not inherit the semaphore B" );
		}
		else
		{
			UNRESOLVED( errno, "sem_trywait failed" );
		}
	}

	ret = sem_unlink( "/fork_14_1a" );

	if ( ret != 0 )
	{
		UNRESOLVED( errno, "Failed to unlink semaphore A" );
	}

	ret = sem_close( sem_linked );

	if ( ret != 0 )
	{
		UNRESOLVED( errno, "Failed to close semaphore A" );
	}

	ret = sem_close( sem_unlinked );

	if ( ret != 0 )
	{
		UNRESOLVED( errno, "Failed to close semaphore B" );
	}

	/* Test passed */
#if VERBOSE > 0

	output( "Test passed\n" );

#endif

	PASSED;
}