Ejemplo n.º 1
1
pid_t
forkpty(int *master, unused char *name, struct termios *tio, struct winsize *ws)
{
	int	slave = -1, fd, pipe_fd[2];
	char   *path, dummy;
	pid_t	pid;

	if (pipe(pipe_fd) == -1)
		return (-1);

	if ((*master = open("/dev/ptc", O_RDWR|O_NOCTTY)) == -1)
		goto out;

	if ((path = ttyname(*master)) == NULL)
		goto out;
	if ((slave = open(path, O_RDWR|O_NOCTTY)) == -1)
		goto out;

	switch (pid = fork()) {
	case -1:
		goto out;
	case 0:
		close(*master);

		close(pipe_fd[1]);
		while (read(pipe_fd[0], &dummy, 1) == -1) {
			if (errno != EINTR)
				break;
		}
		close(pipe_fd[0]);

		fd = open(_PATH_TTY, O_RDWR|O_NOCTTY);
		if (fd >= 0) {
			ioctl(fd, TIOCNOTTY, NULL);
			close(fd);
		}

		if (setsid() < 0)
			fatal("setsid");

		fd = open(_PATH_TTY, O_RDWR|O_NOCTTY);
		if (fd >= 0)
			fatalx("open succeeded (failed to disconnect)");

		fd = open(path, O_RDWR);
		if (fd < 0)
			fatal("open failed");
		close(fd);

		fd = open("/dev/tty", O_WRONLY);
		if (fd < 0)
			fatal("open failed");
		close(fd);

		if (tio != NULL && tcsetattr(slave, TCSAFLUSH, tio) == -1)
			fatal("tcsetattr failed");
		if (ioctl(slave, TIOCSWINSZ, ws) == -1)
			fatal("ioctl failed");

		dup2(slave, 0);
		dup2(slave, 1);
		dup2(slave, 2);
		if (slave > 2)
			close(slave);

		return (0);
	}

	close(slave);

	close(pipe_fd[0]);
	close(pipe_fd[1]);
	return (pid);

out:
	if (*master != -1)
		close(*master);
	if (slave != -1)
		close(slave);

	close(pipe_fd[0]);
	close(pipe_fd[1]);
	return (-1);
}
Ejemplo n.º 2
0
Archivo: sh.c Proyecto: i/xv6
// Execute cmd.  Never returns.
void
runcmd(struct cmd *cmd)
{
  int p[2];
  struct backcmd *bcmd;
  struct execcmd *ecmd;
  struct listcmd *lcmd;
  struct pipecmd *pcmd;
  struct redircmd *rcmd;

  if(cmd == 0)
    exit();

  switch(cmd->type){
  default:
    panic("runcmd");

  case EXEC:
    ecmd = (struct execcmd*)cmd;
    if(ecmd->argv[0] == 0)
      exit();
    exec(ecmd->argv[0], ecmd->argv);
    printf(2, "exec %s failed\n", ecmd->argv[0]);
    break;

  case REDIR:
    rcmd = (struct redircmd*)cmd;
    close(rcmd->fd);
    if(open(rcmd->file, rcmd->mode) < 0){
      printf(2, "open %s failed\n", rcmd->file);
      exit();
    }
    runcmd(rcmd->cmd);
    break;

  case LIST:
    lcmd = (struct listcmd*)cmd;
    if(fork1() == 0)
      runcmd(lcmd->left);
    wait();
    runcmd(lcmd->right);
    break;

  case PIPE:
    pcmd = (struct pipecmd*)cmd;
    if(pipe(p) < 0)
      panic("pipe");
    if(fork1() == 0){
      close(1);
      dup(p[1]);
      close(p[0]);
      close(p[1]);
      runcmd(pcmd->left);
    }
    if(fork1() == 0){
      close(0);
      dup(p[0]);
      close(p[0]);
      close(p[1]);
      runcmd(pcmd->right);
    }
    close(p[0]);
    close(p[1]);
    wait();
    wait();
    break;

  case BACK:
    bcmd = (struct backcmd*)cmd;
    if(fork1() == 0)
      runcmd(bcmd->cmd);
    break;
  }
  exit();
}
Ejemplo n.º 3
0
void* CloudPinyinCreate(FcitxInstance* instance)
{
    FcitxCloudPinyin *cloudpinyin = fcitx_utils_new(FcitxCloudPinyin);
    bindtextdomain("fcitx-cloudpinyin", LOCALEDIR);
    bind_textdomain_codeset("fcitx-cloudpinyin", "UTF-8");
    cloudpinyin->owner = instance;
    int pipe1[2];
    int pipe2[2];

    if (!CloudPinyinConfigLoad(&cloudpinyin->config))
    {
        free(cloudpinyin);
        return NULL;
    }

    if (pipe(pipe1) < 0)
    {
        free(cloudpinyin);
        return NULL;
    }

    if (pipe(pipe2) < 0) {
        close(pipe1[0]);
        close(pipe1[1]);
        free(cloudpinyin);
        return NULL;
    }

    cloudpinyin->pipeRecv = pipe1[0];
    cloudpinyin->pipeNotify = pipe2[1];

    fcntl(pipe1[0], F_SETFL, O_NONBLOCK);
    fcntl(pipe1[1], F_SETFL, O_NONBLOCK);
    fcntl(pipe2[0], F_SETFL, O_NONBLOCK);
    fcntl(pipe2[1], F_SETFL, O_NONBLOCK);

    cloudpinyin->pendingQueue = fcitx_utils_malloc0(sizeof(CurlQueue));
    cloudpinyin->finishQueue = fcitx_utils_malloc0(sizeof(CurlQueue));
    pthread_mutex_init(&cloudpinyin->pendingQueueLock, NULL);
    pthread_mutex_init(&cloudpinyin->finishQueueLock, NULL);

    FcitxFetchThread* fetch = fcitx_utils_malloc0(sizeof(FcitxFetchThread));
    cloudpinyin->fetch = fetch;
    fetch->owner = cloudpinyin;
    fetch->pipeRecv = pipe2[0];
    fetch->pipeNotify = pipe1[1];
    fetch->pendingQueueLock = &cloudpinyin->pendingQueueLock;
    fetch->finishQueueLock = &cloudpinyin->finishQueueLock;
    fetch->queue = fcitx_utils_malloc0(sizeof(CurlQueue));

    FcitxIMEventHook hook;
    hook.arg = cloudpinyin;
    hook.func = CloudPinyinAddCandidateWord;

    FcitxInstanceRegisterUpdateCandidateWordHook(instance, hook);

    hook.arg = cloudpinyin;
    hook.func = CloudPinyinHookForNewRequest;

    FcitxInstanceRegisterResetInputHook(instance, hook);
    FcitxInstanceRegisterInputFocusHook(instance, hook);
    FcitxInstanceRegisterInputUnFocusHook(instance, hook);
    FcitxInstanceRegisterTriggerOnHook(instance, hook);

    FcitxHotkeyHook hkhook;
    hkhook.arg = cloudpinyin;
    hkhook.hotkey = cloudpinyin->config.hkToggle.hotkey;
    hkhook.hotkeyhandle = CloudPinyinToggle;

    FcitxInstanceRegisterHotkeyFilter(instance, hkhook);

    pthread_create(&cloudpinyin->pid, NULL, FetchThread, fetch);

    CloudPinyinRequestKey(cloudpinyin);

    return cloudpinyin;
}
Ejemplo n.º 4
0
int start_command(struct child_process *cmd)
{
	int need_in, need_out, need_err;
	int fdin[2], fdout[2], fderr[2];
	int failed_errno;
	char *str;

	if (!cmd->argv)
		cmd->argv = cmd->args.argv;
	if (!cmd->env)
		cmd->env = cmd->env_array.argv;

	/*
	 * In case of errors we must keep the promise to close FDs
	 * that have been passed in via ->in and ->out.
	 */

	need_in = !cmd->no_stdin && cmd->in < 0;
	if (need_in) {
		if (pipe(fdin) < 0) {
			failed_errno = errno;
			if (cmd->out > 0)
				close(cmd->out);
			str = "standard input";
			goto fail_pipe;
		}
		cmd->in = fdin[1];
	}

	need_out = !cmd->no_stdout
		&& !cmd->stdout_to_stderr
		&& cmd->out < 0;
	if (need_out) {
		if (pipe(fdout) < 0) {
			failed_errno = errno;
			if (need_in)
				close_pair(fdin);
			else if (cmd->in)
				close(cmd->in);
			str = "standard output";
			goto fail_pipe;
		}
		cmd->out = fdout[0];
	}

	need_err = !cmd->no_stderr && cmd->err < 0;
	if (need_err) {
		if (pipe(fderr) < 0) {
			failed_errno = errno;
			if (need_in)
				close_pair(fdin);
			else if (cmd->in)
				close(cmd->in);
			if (need_out)
				close_pair(fdout);
			else if (cmd->out)
				close(cmd->out);
			str = "standard error";
fail_pipe:
			error("cannot create %s pipe for %s: %s",
				str, cmd->argv[0], strerror(failed_errno));
			argv_array_clear(&cmd->args);
			argv_array_clear(&cmd->env_array);
			errno = failed_errno;
			return -1;
		}
		cmd->err = fderr[0];
	}

	trace_argv_printf(cmd->argv, "trace: run_command:");
	fflush(NULL);

#ifndef GIT_WINDOWS_NATIVE
{
	int notify_pipe[2];
	if (pipe(notify_pipe))
		notify_pipe[0] = notify_pipe[1] = -1;

	cmd->pid = fork();
	failed_errno = errno;
	if (!cmd->pid) {
		/*
		 * Redirect the channel to write syscall error messages to
		 * before redirecting the process's stderr so that all die()
		 * in subsequent call paths use the parent's stderr.
		 */
		if (cmd->no_stderr || need_err) {
			int child_err = dup(2);
			set_cloexec(child_err);
			set_error_handle(fdopen(child_err, "w"));
		}

		close(notify_pipe[0]);
		set_cloexec(notify_pipe[1]);
		child_notifier = notify_pipe[1];
		atexit(notify_parent);

		if (cmd->no_stdin)
			dup_devnull(0);
		else if (need_in) {
			dup2(fdin[0], 0);
			close_pair(fdin);
		} else if (cmd->in) {
			dup2(cmd->in, 0);
			close(cmd->in);
		}

		if (cmd->no_stderr)
			dup_devnull(2);
		else if (need_err) {
			dup2(fderr[1], 2);
			close_pair(fderr);
		} else if (cmd->err > 1) {
			dup2(cmd->err, 2);
			close(cmd->err);
		}

		if (cmd->no_stdout)
			dup_devnull(1);
		else if (cmd->stdout_to_stderr)
			dup2(2, 1);
		else if (need_out) {
			dup2(fdout[1], 1);
			close_pair(fdout);
		} else if (cmd->out > 1) {
			dup2(cmd->out, 1);
			close(cmd->out);
		}

		if (cmd->dir && chdir(cmd->dir))
			die_errno("exec '%s': cd to '%s' failed", cmd->argv[0],
			    cmd->dir);
		if (cmd->env) {
			for (; *cmd->env; cmd->env++) {
				if (strchr(*cmd->env, '='))
					putenv((char *)*cmd->env);
				else
					unsetenv(*cmd->env);
			}
		}
		if (cmd->git_cmd)
			execv_git_cmd(cmd->argv);
		else if (cmd->use_shell)
			execv_shell_cmd(cmd->argv);
		else
			sane_execvp(cmd->argv[0], (char *const*) cmd->argv);
		if (errno == ENOENT) {
			if (!cmd->silent_exec_failure)
				error("cannot run %s: %s", cmd->argv[0],
					strerror(ENOENT));
			exit(127);
		} else {
			die_errno("cannot exec '%s'", cmd->argv[0]);
		}
	}
	if (cmd->pid < 0)
		error("cannot fork() for %s: %s", cmd->argv[0],
			strerror(errno));
	else if (cmd->clean_on_exit)
		mark_child_for_cleanup(cmd->pid);

	/*
	 * Wait for child's execvp. If the execvp succeeds (or if fork()
	 * failed), EOF is seen immediately by the parent. Otherwise, the
	 * child process sends a single byte.
	 * Note that use of this infrastructure is completely advisory,
	 * therefore, we keep error checks minimal.
	 */
	close(notify_pipe[1]);
	if (read(notify_pipe[0], &notify_pipe[1], 1) == 1) {
		/*
		 * At this point we know that fork() succeeded, but execvp()
		 * failed. Errors have been reported to our stderr.
		 */
		wait_or_whine(cmd->pid, cmd->argv[0]);
		failed_errno = errno;
		cmd->pid = -1;
	}
	close(notify_pipe[0]);
}
#else
{
	int fhin = 0, fhout = 1, fherr = 2;
	const char **sargv = cmd->argv;

	if (cmd->no_stdin)
		fhin = open("/dev/null", O_RDWR);
	else if (need_in)
		fhin = dup(fdin[0]);
	else if (cmd->in)
		fhin = dup(cmd->in);

	if (cmd->no_stderr)
		fherr = open("/dev/null", O_RDWR);
	else if (need_err)
		fherr = dup(fderr[1]);
	else if (cmd->err > 2)
		fherr = dup(cmd->err);

	if (cmd->no_stdout)
		fhout = open("/dev/null", O_RDWR);
	else if (cmd->stdout_to_stderr)
		fhout = dup(fherr);
	else if (need_out)
		fhout = dup(fdout[1]);
	else if (cmd->out > 1)
		fhout = dup(cmd->out);

	if (cmd->git_cmd)
		cmd->argv = prepare_git_cmd(cmd->argv);
	else if (cmd->use_shell)
		cmd->argv = prepare_shell_cmd(cmd->argv);

	cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, (char**) cmd->env,
			cmd->dir, fhin, fhout, fherr);
	failed_errno = errno;
	if (cmd->pid < 0 && (!cmd->silent_exec_failure || errno != ENOENT))
		error("cannot spawn %s: %s", cmd->argv[0], strerror(errno));
	if (cmd->clean_on_exit && cmd->pid >= 0)
		mark_child_for_cleanup(cmd->pid);

	if (cmd->git_cmd)
		free(cmd->argv);

	cmd->argv = sargv;
	if (fhin != 0)
		close(fhin);
	if (fhout != 1)
		close(fhout);
	if (fherr != 2)
		close(fherr);
}
#endif

	if (cmd->pid < 0) {
		if (need_in)
			close_pair(fdin);
		else if (cmd->in)
			close(cmd->in);
		if (need_out)
			close_pair(fdout);
		else if (cmd->out)
			close(cmd->out);
		if (need_err)
			close_pair(fderr);
		else if (cmd->err)
			close(cmd->err);
		argv_array_clear(&cmd->args);
		argv_array_clear(&cmd->env_array);
		errno = failed_errno;
		return -1;
	}

	if (need_in)
		close(fdin[0]);
	else if (cmd->in)
		close(cmd->in);

	if (need_out)
		close(fdout[1]);
	else if (cmd->out)
		close(cmd->out);

	if (need_err)
		close(fderr[1]);
	else if (cmd->err)
		close(cmd->err);

	return 0;
}
Ejemplo n.º 5
0
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
roken_detach_prep(int argc, char **argv, char *special_arg)
{
    pid_t child;
    char buf[1];
    ssize_t bytes;
    int status;

    pipefds[0] = -1;
    pipefds[1] = -1;

#ifdef WIN32
    if (_pipe(pipefds, 4, O_BINARY) == -1)
        err(1, "failed to setup to detach daemon (_pipe failed)");
#else
    if (pipe(pipefds) == -1)
        err(1, "failed to setup to detach daemon (pipe failed)");
#endif

#ifndef WIN32
    fflush(stdout);
    child = fork();
#else
    {
        intptr_t child_handle;
	int write_side;
        size_t i;
	char *fildes;
        char **new_argv;

        new_argv = calloc(argc + 2, sizeof(*new_argv));
        if (new_argv == NULL)
            err(1, "Out of memory");

	write_side = _dup(pipefds[1]); /* The new fd will be inherited */
	if (write_side == -1)
            err(1, "Out of memory");

	if (asprintf(&fildes, "%d", write_side) == -1 ||
	    fildes == NULL)
            err(1, "failed to setup to detach daemon (_dup failed)");

        new_argv[0] = argv[0];
        new_argv[1] = special_arg;
        new_argv[2] = fildes;
        for (i = 1; argv[i] != NULL; i++)
            new_argv[i + 1] = argv[i];
	new_argv[argc + 2] = NULL;

	_flushall();
	child_handle = spawnvp(_P_NOWAIT, argv[0], new_argv);
	if (child_handle == -1)
	  child = (pid_t)-1;
	else
	  child = GetProcessId((HANDLE)child_handle);
    }
#endif
    if (child == (pid_t)-1)
        err(1, "failed to setup to fork daemon (fork failed)");

#ifndef WIN32
    if (child == 0) {
        int fd;

        (void) close(pipefds[0]);
        pipefds[0] = -1;
        /*
         * Keep stdout/stderr for now so output and errors prior to
         * detach_finish() can be seen by the user.
         */
        fd = open(_PATH_DEVNULL, O_RDWR, 0);
        if (fd == -1)
            err(1, "failed to open /dev/null");
        (void) dup2(fd, STDIN_FILENO);
        if (fd > STDERR_FILENO)
            (void) close(fd);
        return;
    }
#endif

    (void) close(pipefds[1]);
    pipefds[1] = -1;
    do {
        bytes = read(pipefds[0], buf, sizeof(buf));
    } while (bytes == -1 && errno == EINTR);
    (void) close(pipefds[0]);
    pipefds[0] = -1;
    if (bytes == -1) {
        /*
         * No need to wait for the process.  We've killed it.  If it
         * doesn't want to exit, we'd have to wait potentially forever,
         * but we want to indicate failure to the user as soon as
         * possible.  A wait with timeout would end the same way
         * (attempting to kill the process).
         */
        err(1, "failed to setup daemon child (read from child pipe)");
    }
    if (bytes == 0) {
        warnx("daemon child preparation failed, waiting for child");
        status = wait_for_process(child);
        if (SE_IS_ERROR(status) || SE_PROCSTATUS(status) != 0)
            errx(SE_PROCSTATUS(status),
                 "daemon child preparation failed (child exited)");
    }
    _exit(0);
}
Ejemplo n.º 6
0
/*
 * Run an external program. Optionally wait a specified number
 *   of seconds. Program killed if wait exceeded. We open
 *   a bi-directional pipe so that the user can read from and
 *   write to the program.
 */
BPIPE *open_bpipe(char *prog, int wait, const char *mode)
{
   char *bargv[MAX_ARGV];
   int bargc, i;
   int readp[2], writep[2];
   POOLMEM *tprog;
   int mode_read, mode_write;
   BPIPE *bpipe;
   int save_errno;

   bpipe = (BPIPE *)malloc(sizeof(BPIPE));
   memset(bpipe, 0, sizeof(BPIPE));
   mode_read = (mode[0] == 'r');
   mode_write = (mode[0] == 'w' || mode[1] == 'w');
   /* Build arguments for running program. */
   tprog = get_pool_memory(PM_FNAME);
   pm_strcpy(tprog, prog);
   build_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
#ifdef  xxxxxx
   printf("argc=%d\n", bargc);
   for (i=0; i<bargc; i++) {
      printf("argc=%d argv=%s:\n", i, bargv[i]);
   }
#endif

   /* Each pipe is one way, write one end, read the other, so we need two */
   if (mode_write && pipe(writep) == -1) {
      save_errno = errno;
      free(bpipe);
      free_pool_memory(tprog);
      errno = save_errno;
      return NULL;
   }
   if (mode_read && pipe(readp) == -1) {
      save_errno = errno;
      if (mode_write) {
         close(writep[0]);
         close(writep[1]);
      }
      free(bpipe);
      free_pool_memory(tprog);
      errno = save_errno;
      return NULL;
   }
   /* Start worker process */
   switch (bpipe->worker_pid = fork()) {
   case -1:                           /* error */
      save_errno = errno;
      if (mode_write) {
         close(writep[0]);
         close(writep[1]);
      }
      if (mode_read) {
         close(readp[0]);
         close(readp[1]);
      }
      free(bpipe);
      free_pool_memory(tprog);
      errno = save_errno;
      return NULL;

   case 0:                            /* child */
      if (mode_write) {
         close(writep[1]);
         dup2(writep[0], 0);          /* Dup our write to his stdin */
      }
      if (mode_read) {
         close(readp[0]);             /* Close unused child fds */
         dup2(readp[1], 1);           /* dup our read to his stdout */
         dup2(readp[1], 2);           /*   and his stderr */
      }
/* Note, the close log cause problems, see bug #1536 */
/*    closelog();                        close syslog if open */
      for (i=3; i<=32; i++) {         /* close any open file descriptors */
         close(i);
      }
      execvp(bargv[0], bargv);        /* call the program */
      /* Convert errno into an exit code for later analysis */
      for (i=0; i< num_execvp_errors; i++) {
         if (execvp_errors[i] == errno) {
            exit(200 + i);            /* exit code => errno */
         }
      }
      exit(255);                      /* unknown errno */

   default:                           /* parent */
      break;
   }
   free_pool_memory(tprog);
   if (mode_read) {
      close(readp[1]);                /* close unused parent fds */
      bpipe->rfd = fdopen(readp[0], "r"); /* open file descriptor */
   }
   if (mode_write) {
      close(writep[0]);
      bpipe->wfd = fdopen(writep[1], "w");
   }
   bpipe->worker_stime = time(NULL);
   bpipe->wait = wait;
   if (wait > 0) {
      bpipe->timer_id = start_child_timer(NULL, bpipe->worker_pid, wait);
   }
   return bpipe;
}
Ejemplo n.º 7
0
void
cmd_clipboard(const char *e_line, command *commands)
{
	xmlNodePtr		db_node = NULL;
	xmlChar			*key = NULL, *value = NULL, *value_nl = NULL, *value_line = NULL;
	char			*cmd_line = NULL, *cmd = NULL, *inv = NULL;
	unsigned long int	idx = 0, line_req = 1, lines = 0, value_line_len = 0, value_len = 0, i = 0;
	unsigned char		app = 0;	/* 1=tmux, 2=xclip PRIMARY, 3=xclip CLIPBOARD */

	char		**fork_argv = NULL;
	int		child;
	int		pipefd[2];


	cmd_line = strdup(e_line); malloc_check(cmd_line);

	cmd = strtok(cmd_line, " ");
	if (!cmd) {
		puts(commands->usage);

		free(cmd_line); cmd_line = NULL;
		return;
	}

	if (strcmp(cmd, "tmux") == 0)
		app = 1;
	else if (strcmp(cmd, "xclip") == 0)
		app = 2;
	else if (strcmp(cmd, "Xclip") == 0)
		app = 3;

	if (app == 0) {
		puts(commands->usage);

		free(cmd_line); cmd_line = NULL;
		return;
	}


	cmd = strtok(NULL, " ");	/* first parameter, the index number */
	if (!cmd) {
		puts(commands->usage);

		free(cmd_line); cmd_line = NULL;
		return;
	}

	errno = 0;
	idx = strtoul((const char *)cmd, &inv, 10);
	if (inv[0] != '\0'  ||  errno != 0  ||  cmd[0] == '-') {
		puts(commands->usage);

		free(cmd_line); cmd_line = NULL;
		return;
	}


	cmd = strtok(NULL, " ");	/* second, optional parameter, the requested line number */
	if (cmd) {
		errno = 0;
		line_req = strtoul((const char *)cmd, &inv, 10);
		if (inv[0] != '\0'  ||  errno != 0  ||  cmd[0] == '-') {
			puts(commands->usage);

			free(cmd_line); cmd_line = NULL;
			return;
		}
		if (line_req < 1) {
			puts(commands->usage);

			free(cmd_line); cmd_line = NULL;
			return;
		}
	}

	free(cmd_line); cmd_line = NULL;


	db_node = find_key(idx);
	if (db_node) {
		value = xmlGetProp(db_node, BAD_CAST "value");
		key = xmlGetProp(db_node, BAD_CAST "name");
		value_nl = parse_newlines(value, 0);
		xmlFree(value); value = NULL;

		/* count how many (new)lines are in the string */
		value_len = xmlStrlen(value_nl);
		for (i=0; i < value_len; i++)
			if (value_nl[i] == '\n')
				lines++;
		lines++;

		/* If the requested line number is greater than the
		 * maximum, use the maximum.
		 */
		if (line_req > lines)
			line_req = lines;

		/* get a line out from the value */
		value_line = get_line(value_nl, line_req);
		value_line_len = xmlStrlen(value_line);

		/* This is duplicated in cmd_getnum.c */
		switch (app) {
			case 1:
				/* Copy value to tmux paste buffer */
				switch (child = fork()) {
					case -1:
						perror("\nERROR: Couldn't fork(2) for tmux(1)");
						break;
					case 0:	/* Child */
#ifndef __OpenBSD__
						close(0);
#endif
						close(1);

						if (bio_chain)
							BIO_free_all(bio_chain);

						if (db_params.db_file) {
							if (close(db_params.db_file) == -1) {
								perror("ERROR: child: close(database file)");
								exit(EXIT_FAILURE);
							} else {
								db_params.db_file = -1;
							}
						}

						fork_argv = malloc(5 * sizeof(char *)); malloc_check(fork_argv);
						fork_argv[0] = "tmux";
						fork_argv[1] = "set-buffer";
						fork_argv[2] = "--";
						fork_argv[3] = (char *)value_line;
						fork_argv[4] = NULL;

						if (execvp(fork_argv[0], fork_argv) == -1)
							dprintf(STDERR_FILENO, "ERROR: tmux: %s\n", strerror(errno));

						quit(EXIT_FAILURE);

						break;
					default: /* Parent */
						printf("Copying #%lu from '%s' to tmux paste buffer.\n", line_req, key);
						break;
				}

				break;
			case 2:
			case 3:
				/* Copy value to X11 clipboard, using xclip(1) */

				pipe(pipefd);

				switch (child = fork()) {
					case -1:
						perror("\nERROR: Couldn't fork(2) for xclip(1)");
						break;
					case 0:	/* Child */
						close(0);
						close(1);
						close(pipefd[1]);

						if (bio_chain)
							BIO_free_all(bio_chain);

						if (db_params.db_file) {
							if (close(db_params.db_file) == -1) {
								perror("ERROR: child: close(database file)");
								exit(EXIT_FAILURE);
							} else {
								db_params.db_file = -1;
							}
						}

						fork_argv = malloc(4 * sizeof(char *)); malloc_check(fork_argv);
						fork_argv[0] = "xclip";
						fork_argv[1] = "-selection";
						if (app == 2) {
							fork_argv[2] = "primary";
						} else if (app == 3) {
							fork_argv[2] = "clipboard";
						}
						fork_argv[3] = NULL;

						/* stdin becomes the read end of the pipe in the child,
						 * and the exec'd process will have the same environment. */
						dup2(pipefd[0], 0);
						if (execvp(fork_argv[0], fork_argv) == -1)
							dprintf(STDERR_FILENO, "ERROR: xclip: %s\n", strerror(errno));

						quit(EXIT_FAILURE);

						break;
					default: /* Parent */
						/* Write the value to the pipe's write end, which will
						 * appear in the child's stdin (pipe's read end). */
						close(pipefd[0]);
						write(pipefd[1], value_line, value_line_len);
						close(pipefd[1]);

						printf("Copying #%lu from '%s' to X11 clipboard.\n", line_req, key);

						break;
				}

				break;
		}
	} else
		puts("Invalid index!");


	xmlFree(key); key = NULL;
	xmlFree(value_line); value_line = NULL;
	xmlFree(value_nl); value_nl = NULL;
} /* cmd_clipboard() */
Ejemplo n.º 8
0
/*
 *  The purpose of this function is to assign "long usage", short usage
 *  and version information to a shell variable.  Rather than wind our
 *  way through all the logic necessary to emit the text directly, we
 *  fork(), have our child process emit the text the normal way and
 *  capture the output in the parent process.
 */
static void
textToVariable(tOptions * pOpts, teTextTo whichVar, tOptDesc * pOD)
{
#   define _TT_(n) static char const z ## n [] = #n;
    TEXTTO_TABLE
#   undef _TT_
#   define _TT_(n) z ## n ,
      static char const * apzTTNames[] = { TEXTTO_TABLE };
#   undef _TT_

#if ! defined(HAVE_WORKING_FORK)
    printf("%1$s_%2$s_TEXT='no %2$s text'\n",
           pOpts->pzPROGNAME, apzTTNames[ whichVar ]);
#else
    int  pipeFd[2];

    fflush(stdout);
    fflush(stderr);

    if (pipe(pipeFd) != 0) {
        fprintf(stderr, zBadPipe, errno, strerror(errno));
        exit(EXIT_FAILURE);
    }

    switch (fork()) {
    case -1:
        fprintf(stderr, zForkFail, errno, strerror(errno), pOpts->pzProgName);
        exit(EXIT_FAILURE);
        break;

    case 0:
        /*
         * Send both stderr and stdout to the pipe.  No matter which
         * descriptor is used, we capture the output on the read end.
         */
        dup2(pipeFd[1], STDERR_FILENO);
        dup2(pipeFd[1], STDOUT_FILENO);
        close(pipeFd[0]);

        switch (whichVar) {
        case TT_LONGUSAGE:
            (*(pOpts->pUsageProc))(pOpts, EXIT_SUCCESS);
            /* NOTREACHED */

        case TT_USAGE:
            (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
            /* NOTREACHED */

        case TT_VERSION:
            if (pOD->fOptState & OPTST_ALLOC_ARG) {
                AGFREE(pOD->optArg.argString);
                pOD->fOptState &= ~OPTST_ALLOC_ARG;
            }
            pOD->optArg.argString = "c";
            optionPrintVersion(pOpts, pOD);
            /* NOTREACHED */

        default:
            exit(EXIT_FAILURE);
        }

    default:
        close(pipeFd[1]);
    }

    emit_var_text(pOpts->pzPROGNAME, apzTTNames[whichVar], pipeFd[0]);
#endif
}
Ejemplo n.º 9
0
//
//  OS_Create_Process: C
// 
// flags:
//     1: wait, is implied when I/O redirection is enabled
//     2: console
//     4: shell
//     8: info
//     16: show
// 
// input_type/output_type/err_type:
//     0: none
//     1: string
//     2: file
// 
// Return -1 on error, otherwise the process return code.
// 
// POSIX previous simple version was just 'return system(call);'
// This uses 'execvp' which is "POSIX.1 conforming, UNIX compatible"
//
int OS_Create_Process(
    const REBCHR *call,
    int argc,
    const REBCHR* argv[],
    u32 flags,
    u64 *pid,
    int *exit_code,
    u32 input_type,
    char *input,
    u32 input_len,
    u32 output_type,
    char **output,
    u32 *output_len,
    u32 err_type,
    char **err,
    u32 *err_len
) {
    REBOOL flag_wait = FALSE;
    REBOOL flag_console = FALSE;
    REBOOL flag_shell = FALSE;
    REBOOL flag_info = FALSE;
    int stdin_pipe[] = {-1, -1};
    int stdout_pipe[] = {-1, -1};
    int stderr_pipe[] = {-1, -1};
    int info_pipe[] = {-1, -1};
    int status = 0;
    int ret = 0;
    char *info = NULL;
    off_t info_size = 0;
    u32 info_len = 0;
    pid_t fpid = 0;

    const unsigned int R = 0;
    const unsigned int W = 1;

    // We want to be able to compile with all warnings as errors, and
    // we'd like to use -Wcast-qual if possible.  This is currently
    // the only barrier in the codebase...so we tunnel under the cast.
    char * const *argv_hack;

    if (flags & FLAG_WAIT) flag_wait = TRUE;
    if (flags & FLAG_CONSOLE) flag_console = TRUE;
    if (flags & FLAG_SHELL) flag_shell = TRUE;
    if (flags & FLAG_INFO) flag_info = TRUE;

    // suppress unused warnings but keep flags for future use
    (void)flag_info;
    (void)flag_console;

    // NOTE: pipe() is POSIX, but pipe2() is Linux-specific.

    if (input_type == STRING_TYPE
        || input_type == BINARY_TYPE) {
    #ifdef TO_LINUX
        if (pipe2(stdin_pipe, O_CLOEXEC | O_NONBLOCK) < 0) {
    #else
        if (pipe(stdin_pipe) < 0) {
    #endif
            goto stdin_pipe_err;
        }
    }
    if (output_type == STRING_TYPE || output_type == BINARY_TYPE) {
    #ifdef TO_LINUX
        if (pipe2(stdout_pipe, O_CLOEXEC | O_NONBLOCK) < 0) {
    #else
        if (pipe(stdout_pipe) < 0) {
    #endif
            goto stdout_pipe_err;
        }
    }
    if (err_type == STRING_TYPE || err_type == BINARY_TYPE) {
    #ifdef TO_LINUX
        if (pipe2(stderr_pipe, O_CLOEXEC | O_NONBLOCK) < 0) {
    #else
        if (pipe(stderr_pipe) < 0) {
    #endif
            goto stderr_pipe_err;
        }
    }

#ifdef TO_LINUX
    if (pipe2(info_pipe, O_CLOEXEC | O_NONBLOCK) < 0) {
#else
    if (pipe(info_pipe) < 0) {
#endif
        goto info_pipe_err;
    }

    fpid = fork();
    if (fpid == 0) {
        /* child */
        if (input_type == STRING_TYPE
            || input_type == BINARY_TYPE) {
            close(stdin_pipe[W]);
            if (dup2(stdin_pipe[R], STDIN_FILENO) < 0) {
                goto child_error;
            }
            close(stdin_pipe[R]);
        } else if (input_type == FILE_TYPE) {
            int fd = open(input, O_RDONLY);
            if (fd < 0) {
                goto child_error;
            }
            if (dup2(fd, STDIN_FILENO) < 0) {
                goto child_error;
            }
            close(fd);
        } else if (input_type == NONE_TYPE) {
            int fd = open("/dev/null", O_RDONLY);
            if (fd < 0) {
                goto child_error;
            }
            if (dup2(fd, STDIN_FILENO) < 0) {
                goto child_error;
            }
            close(fd);
        } else { /* inherit stdin from the parent */
        }

        if (output_type == STRING_TYPE
            || output_type == BINARY_TYPE) {
            close(stdout_pipe[R]);
            if (dup2(stdout_pipe[W], STDOUT_FILENO) < 0) {
                goto child_error;
            }
            close(stdout_pipe[W]);
        } else if (output_type == FILE_TYPE) {
            int fd = open(*output, O_CREAT|O_WRONLY, 0666);
            if (fd < 0) {
                goto child_error;
            }
            if (dup2(fd, STDOUT_FILENO) < 0) {
                goto child_error;
            }
            close(fd);
        } else if (output_type == NONE_TYPE) {
            int fd = open("/dev/null", O_WRONLY);
            if (fd < 0) {
                goto child_error;
            }
            if (dup2(fd, STDOUT_FILENO) < 0) {
                goto child_error;
            }
            close(fd);
        } else { /* inherit stdout from the parent */
        }

        if (err_type == STRING_TYPE
            || err_type == BINARY_TYPE) {
            close(stderr_pipe[R]);
            if (dup2(stderr_pipe[W], STDERR_FILENO) < 0) {
                goto child_error;
            }
            close(stderr_pipe[W]);
        } else if (err_type == FILE_TYPE) {
            int fd = open(*err, O_CREAT|O_WRONLY, 0666);
            if (fd < 0) {
                goto child_error;
            }
            if (dup2(fd, STDERR_FILENO) < 0) {
                goto child_error;
            }
            close(fd);
        } else if (err_type == NONE_TYPE) {
            int fd = open("/dev/null", O_WRONLY);
            if (fd < 0) {
                goto child_error;
            }
            if (dup2(fd, STDERR_FILENO) < 0) {
                goto child_error;
            }
            close(fd);
        } else {/* inherit stderr from the parent */
        }

        close(info_pipe[R]);

        //printf("flag_shell in child: %hhu\n", flag_shell);
        if (flag_shell) {
            const char* sh = NULL;
            const char ** argv_new = NULL;
            sh = getenv("SHELL");
            if (sh == NULL) {
                int err = 2; /* shell does not exist */
                if (write(info_pipe[W], &err, sizeof(err)) == -1) {
                    // Nothing we can do, but need to stop compiler warning
                    // (cast to void is insufficient for warn_unused_result)
                }
                exit(EXIT_FAILURE);
            }
            argv_new = c_cast(
                const char**, OS_ALLOC_N(const char*, argc + 3)
            );
            argv_new[0] = sh;
            argv_new[1] = "-c";
            memcpy(&argv_new[2], argv, argc * sizeof(argv[0]));
            argv_new[argc + 2] = NULL;

            memcpy(&argv_hack, &argv_new, sizeof(argv_hack));
            execvp(sh, argv_hack);
        } else {
            memcpy(&argv_hack, &argv, sizeof(argv_hack));
            execvp(argv[0], argv_hack);
        }

child_error:
        if (write(info_pipe[W], &errno, sizeof(errno)) == -1) {
            // Nothing we can do, but need to stop compiler warning
            // (cast to void is insufficient for warn_unused_result)
        }
        exit(EXIT_FAILURE); /* get here only when exec fails */
    }
    else if (fpid > 0) {
        /* parent */
#define BUF_SIZE_CHUNK 4096
        nfds_t nfds = 0;
        struct pollfd pfds[4];
        pid_t xpid;
        unsigned int i;
        ssize_t nbytes;
        off_t input_size = 0;
        off_t output_size = 0;
        off_t err_size = 0;
        int exited = 0;
        int valid_nfds;

        /* initialize outputs */
        if (output_type != NONE_TYPE
            && output_type != INHERIT_TYPE
            && (output == NULL
                || output_len == NULL)) {
            return -1;
        }
        if (output != NULL) *output = NULL;
        if (output_len != NULL) *output_len = 0;

        if (err_type != NONE_TYPE
            && err_type != INHERIT_TYPE
            && (err == NULL
                || err_len == NULL)) {
            return -1;
        }
        if (err != NULL) *err = NULL;
        if (err_len != NULL) *err_len = 0;

        // Only put the input pipe in the consideration if we can write to
        // it and we have data to send to it.
        if ((stdin_pipe[W] > 0) && (input_size = strlen(input)) > 0) {
            //printf("stdin_pipe[W]: %d\n", stdin_pipe[W]);
            /* the passed in input_len is in characters, not in bytes */
            input_len = 0;

            pfds[nfds].fd = stdin_pipe[W];
            pfds[nfds].events = POLLOUT;
            nfds++;

            close(stdin_pipe[R]);
            stdin_pipe[R] = -1;
        }
        if (stdout_pipe[R] > 0) {
            //printf("stdout_pipe[R]: %d\n", stdout_pipe[R]);
            output_size = BUF_SIZE_CHUNK;

            *output = OS_ALLOC_N(char, output_size);

            pfds[nfds].fd = stdout_pipe[R];
            pfds[nfds].events = POLLIN;
            nfds++;

            close(stdout_pipe[W]);
            stdout_pipe[W] = -1;
        }
        if (stderr_pipe[R] > 0) {
            //printf("stderr_pipe[R]: %d\n", stderr_pipe[R]);
            err_size = BUF_SIZE_CHUNK;

            *err = OS_ALLOC_N(char, err_size);

            pfds[nfds].fd = stderr_pipe[R];
            pfds[nfds].events = POLLIN;
            nfds++;

            close(stderr_pipe[W]);
            stderr_pipe[W] = -1;
        }

        if (info_pipe[R] > 0) {
            pfds[nfds].fd = info_pipe[R];
            pfds[nfds].events = POLLIN;
            nfds++;

            info_size = 4;

            info = OS_ALLOC_N(char, info_size);

            close(info_pipe[W]);
            info_pipe[W] = -1;
        }
static ngx_int_t
ngx_rtmp_exec_run(ngx_rtmp_exec_t *e)
{
#if !(NGX_WIN32)
    ngx_pid_t                       pid;
    int                             fd, maxfd;
    int                             pipefd[2];
    int                             ret;
    ngx_rtmp_exec_conf_t           *ec;
    ngx_str_t                      *arg, a;
    char                          **args;
    ngx_uint_t                      n;

    ec = e->conf;

    ngx_log_debug1(NGX_LOG_DEBUG_RTMP, e->log, 0,
                   "exec: starting child '%V'", &ec->cmd);

    if (e->active) {
        ngx_log_debug1(NGX_LOG_DEBUG_RTMP, e->log, 0,
                       "exec: already active '%V'", &ec->cmd);
        return NGX_OK;
    }

    if (pipe(pipefd) == -1) {
        ngx_log_error(NGX_LOG_INFO, e->log, ngx_errno,
                      "exec: pipe failed");
        return NGX_ERROR;
    }

    /* make pipe write end survive through exec */
    ret = fcntl(pipefd[1], F_GETFD);
    if (ret != -1) {
        ret &= ~FD_CLOEXEC;
        ret = fcntl(pipefd[1], F_SETFD, ret);
    }
    if (ret == -1) {
        close(pipefd[0]);
        close(pipefd[1]);
        ngx_log_error(NGX_LOG_INFO, e->log, ngx_errno,
                      "exec: fcntl failed");
        return NGX_ERROR;
    }

    pid = fork();
    switch (pid) {
        case -1:
            close(pipefd[0]);
            close(pipefd[1]);
            ngx_log_error(NGX_LOG_INFO, e->log, ngx_errno,
                          "exec: fork failed");
            return NGX_ERROR;

        case 0:
            /* child */

#if (NGX_LINUX)
            prctl(PR_SET_PDEATHSIG, e->kill_signal, 0, 0, 0);
#endif

            /* close all descriptors but pipe write end */
            maxfd = sysconf(_SC_OPEN_MAX);
            for (fd = 0; fd < maxfd; ++fd) {
                if (fd == pipefd[1]) {
                    continue;
                }

                close(fd);
            }

            fd = open("/dev/null", O_RDWR);            

            dup2(fd, STDIN_FILENO);
            dup2(fd, STDOUT_FILENO);
            dup2(fd, STDERR_FILENO);

            args = ngx_alloc((ec->args.nelts + 2) * sizeof(char *), e->log);
            if (args == NULL) {
                exit(1);
            }
            arg = ec->args.elts;
            args[0] = (char *) ec->cmd.data;
            for (n = 0; n < ec->args.nelts; ++n, ++arg) {
                if (e->session == NULL) {
                    a = *arg;
                } else {
                    ngx_rtmp_eval(e->session, arg, ngx_rtmp_exec_eval_p, &a);
                }
                args[n + 1] = (char *) a.data;
            }
            args[n + 1] = NULL;
            if (execvp((char *) ec->cmd.data, args) == -1) {
                exit(1);
            }
            break;

        default:
            /* parent */
            close(pipefd[1]);
            e->active = 1;
            e->pid = pid;
            e->pipefd = pipefd[0];
            if (e->save_pid) {
                *e->save_pid = pid;
            }

            e->dummy_conn.fd = e->pipefd;
            e->dummy_conn.data = e;
            e->dummy_conn.read  = &e->read_evt;
            e->dummy_conn.write = &e->write_evt;
            e->read_evt.data  = &e->dummy_conn;
            e->write_evt.data = &e->dummy_conn;

            e->read_evt.log = e->log;
            e->read_evt.handler = ngx_rtmp_exec_child_dead;

            if (ngx_add_event(&e->read_evt, NGX_READ_EVENT, 0) != NGX_OK) {
                ngx_log_error(NGX_LOG_INFO, e->log, ngx_errno,
                              "exec: failed to add child control event");
            }

            ngx_log_debug2(NGX_LOG_DEBUG_RTMP, e->log, 0,
                           "exec: child '%V' started pid=%i", 
                           &ec->cmd, (ngx_int_t) pid);
            break;
    }
#endif /* NGX_WIN32 */
    return NGX_OK;
}
Ejemplo n.º 11
0
int main(int argc, char **argv)
{
    /* UCP temporary vars */
    ucp_params_t ucp_params;
    ucp_worker_params_t worker_params;
    ucp_config_t *config;
    ucs_status_t status;

    /* UCP handler objects */
    ucp_context_h ucp_context;

    /* OOB connection vars */
    uint64_t addr_len = 0;
    char *server = NULL;
    int oob_sock = -1;
    int ret = -1;

    /* create the signalling pipe */
    pipe(signal_pipe);


    /* Parse the command line */
    if (parse_cmd(argc, argv, &server) != UCS_OK) {
        goto err;
    }
    /* UCP initialization */
    status = ucp_config_read(NULL, NULL, &config);
    if (status != UCS_OK) {
        goto err;
    }

    ucp_params.features = UCP_FEATURE_TAG;
    if (ucp_test_mode == TEST_MODE_WAIT || ucp_test_mode == TEST_MODE_EVENTFD) {
        ucp_params.features |= UCP_FEATURE_WAKEUP;
    }
    ucp_params.request_size    = sizeof(struct ucx_context);
    ucp_params.request_init    = request_init;
    ucp_params.request_cleanup = NULL;

    status = ucp_init(&ucp_params, config, &ucp_context);

    ucp_config_print(config, stdout, NULL, UCS_CONFIG_PRINT_CONFIG);

    ucp_config_release(config);
    if (status != UCS_OK) {
        goto err;
    }

    worker_params.field_mask  = UCP_WORKER_PARAM_FIELD_THREAD_MODE;
    worker_params.thread_mode = UCS_THREAD_MODE_SINGLE;

    status = ucp_worker_create(ucp_context, &worker_params, &ucp_worker);
    if (status != UCS_OK) {
        goto err_cleanup;
    }

    status = ucp_worker_get_address(ucp_worker, &local_addr, &local_addr_len);
    if (status != UCS_OK) {
        goto err_worker;
    }

    status = ucp_worker_get_efd(ucp_worker, &epoll_fd);
    if (status != UCS_OK) {
        goto err;
    }

    printf("[0x%x] local address length: %zu\n",
           (unsigned int)pthread_self(), local_addr_len);

    /* OOB connection establishment */
    if (server) {
        peer_addr_len = local_addr_len;

        oob_sock = run_client(server);
        if (oob_sock < 0) {
            goto err_addr;
        }

        ret = recv(oob_sock, &addr_len, sizeof(addr_len), 0);
        if (ret < 0) {
            fprintf(stderr, "failed to receive address length\n");
            goto err_addr;
        }

        peer_addr_len = addr_len;
        peer_addr = malloc(peer_addr_len);
        if (!peer_addr) {
            fprintf(stderr, "unable to allocate memory\n");
            goto err_addr;
        }

        ret = recv(oob_sock, peer_addr, peer_addr_len, 0);
        if (ret < 0) {
            fprintf(stderr, "failed to receive address\n");
            goto err_peer_addr;
        }
    } else {
        oob_sock = run_server();
        if (oob_sock < 0) {
            goto err_peer_addr;
        }

        addr_len = local_addr_len;
        ret = send(oob_sock, &addr_len, sizeof(addr_len), 0);
        if (ret < 0 || ret != sizeof(addr_len)) {
            fprintf(stderr, "failed to send address length\n");
            goto err_peer_addr;
        }

        ret = send(oob_sock, local_addr, local_addr_len, 0);
        if (ret < 0 || ret != local_addr_len) {
            fprintf(stderr, "failed to send address\n");
            goto err_peer_addr;
        }
    }

    ret = run_test(NULL == server);

    /* Make sure remote is disconnected before destroying local worker */
    barrier(oob_sock);
    close(oob_sock);

err_peer_addr:
    free(peer_addr);

err_addr:
    ucp_worker_release_address(ucp_worker, local_addr);

err_worker:
    ucp_worker_destroy(ucp_worker);

err_cleanup:
    ucp_cleanup(ucp_context);

err:
    return ret;
}
Ejemplo n.º 12
0
Archivo: Posix.c Proyecto: 8l/NxM
int
mypipe(int *fd)
{
	return pipe(fd);
}
Ejemplo n.º 13
0
static int exec_conf(void)
{
	int pipefd[2], stat, size;
	struct sigaction sa;
	sigset_t sset, osset;

	sigemptyset(&sset);
	sigaddset(&sset, SIGINT);
	sigprocmask(SIG_BLOCK, &sset, &osset);

	signal(SIGINT, SIG_DFL);

	sa.sa_handler = winch_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_RESTART;
	sigaction(SIGWINCH, &sa, NULL);

	*argptr++ = NULL;

	pipe(pipefd);
	pid = fork();
	if (pid == 0) {
		sigprocmask(SIG_SETMASK, &osset, NULL);
		dup2(pipefd[1], 2);
		close(pipefd[0]);
		close(pipefd[1]);
		execv(args[0], args);
		_exit(EXIT_FAILURE);
	}

	close(pipefd[1]);
	bufptr = input_buf;
	while (1) {
		size = input_buf + sizeof(input_buf) - bufptr;
		size = read(pipefd[0], bufptr, size);
		if (size <= 0) {
			if (size < 0) {
				if (errno == EINTR || errno == EAGAIN)
					continue;
				perror("read");
			}
			break;
		}
		bufptr += size;
	}
	*bufptr++ = 0;
	close(pipefd[0]);
	waitpid(pid, &stat, 0);

	if (do_resize) {
		init_wsize();
		do_resize = 0;
		sigprocmask(SIG_SETMASK, &osset, NULL);
		return -1;
	}
	if (WIFSIGNALED(stat)) {
		printf("\finterrupted(%d)\n", WTERMSIG(stat));
		exit(1);
	}
#if 0
	printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf);
	sleep(1);
#endif
	sigpending(&sset);
	if (sigismember(&sset, SIGINT)) {
		printf("\finterrupted\n");
		exit(1);
	}
	sigprocmask(SIG_SETMASK, &osset, NULL);

	return WEXITSTATUS(stat);
}
Ejemplo n.º 14
0
int
main(int argc, char *argv[])
{
    int                     n;
    int                     fd[2];
    pid_t                   pid;
    char                    *pager, *argv0;
    char                    line[1024];
    FILE                    *fp;

    if(argc != 2){
        printf("usage: a.out <pathname>\n");
        return -1;
    }

    if((fp = fopen(argv[1], "r")) == NULL){
        printf("open file [%s] error: %s\n", argv[1], strerror(errno));
        return -2;
    }
    
    if(pipe(fd) < 0){
        perror("pipe");
        return -3;
    }

    if((pid = fork()) < 0){
        perror("fork");
        return -4;
    }else if(pid > 0){
        close(fd[0]);
        while(fgets(line, sizeof(line), fp) != NULL){
            n = strlen(line);
            if(write(fd[1], line, n) != n){
                perror("write");
                return -5;
            }
        }
        if(ferror(fp)){ /*读文件结束或者读文件出错,fgets都会返回NULL,用ferror来判断是不是发生了错误*/
            printf("read file [%s] error\n", argv[1]);
            return -6;
        }

        close(fd[1]);

        /*等待子进程退出*/
        if(waitpid(pid, NULL, 0) < 0){
            perror("waitpid");
            return -7;
        }

        return 0;
    }else{
        close(fd[1]);
        /*要先判断是不相等了才进行文件符复制*/
        if(fd[0] != STDIN_FILENO){
            if(dup2(fd[0], STDIN_FILENO) != STDIN_FILENO){
                perror("dup2");
                return -8;
            }
            close(fd[0]);/*要关闭该文件描述符,因为被复制出来了,共享文件描述符,以后都不用了*/
        }
        /*文件描述符已被复制,子进程的标准输入是管道了,即复制前的fd[0]*/
        /*获取页的大小*/
        if((pager = getenv("PAGER")) == NULL)
            pager = DEF_PAGER;
        if((argv0 = strrchr(pager, '/')) != NULL)
            argv0++;
        else
            argv0 = pager;

        if(execl(pager, argv0, (char *)0) < 0){
            perror("execl");
            return -9;
        }
        return 0;
    }
    
}
int		proc_create(proc_obj_t* proc, char* bin_path, char** args)
{
  pid_t		child;
  int		pfd1[2], pfd2[2];
  char		c;
  ttevent_t	ev;

  ev.tte_events = TTEVT_SYSCALL|TTEVT_EXEC|TTEVT_EXIT|
    TTEVT_BPT_SSTEP|TTEVT_SIGNAL;
  ev.tte_opts = TTEO_NONE;

  /*
  ** Technique de Roumain avec des pipes
  ** pour synchoniser les deux process
  */
  if (pipe(pfd1) < 0 || pipe(pfd2) < 0)
    return (-1);
  switch ((child = fork()))
    {
    case -1:
      return (-1);

      /*
      ** Child Process
      */
    case 0:
      if (setpgid(0, 0) == -1)
	return (-1);
      if (ttrace(TT_PROC_SETTRC, 0, 0, 0, TT_VERSION, 0) == -1)
	return -1;
      /* tell parent we are SETTRC'ed */
      if (write(pfd2[1], (void *)&c, sizeof c) != sizeof c)
	return (-1);
      /* wait for exec event to be set*/
      if (read(pfd1[0], (void *)&c, sizeof c) != sizeof c)
	return (-1);
      close(pfd1[0]); close(pfd1[1]); close(pfd2[0]); close(pfd2[1]);
      if (execvp(bin_path, args) == -1)
	return (-1);
      return (-1);
    }
  /*
  ** Ftrace process
  */
  if (read(pfd2[0], (void *)&c, sizeof c) != sizeof c)
    return (-1);
  proc->pid = child;
  if (ttrace(TT_PROC_SET_EVENT_MASK, proc->pid, 0,
	     (uint64_t)&ev, sizeof ev, 0) == -1)
    return (-1);
  /* tell the child to exec */
  if (write(pfd1[1], (void *)&c, sizeof c) != sizeof c)
    return (-1);
  close(pfd1[0]); close(pfd1[1]); close(pfd2[0]); close(pfd2[1]);

  /*
  ** TODO:
  ** Attendre la fin de l'exec()
  ** set des breakpoints
  */

  proc->luse = NULL;
  if (proc_wait_debug_event(proc, NULL) == -1)
    return (-1);

  return child;
}
Ejemplo n.º 16
0
static int
do_one_test (void)
{
  in_sh_body = 0;
  cleanups = 0;
  if (pipe (fd) != 0 || pipe (fd + 2) != 0)
    {
      puts ("pipe failed");
      return 1;
    }

  pthread_t th;
  if (pthread_create (&th, NULL, tf, NULL) != 0)
    {
      puts ("create failed");
      return 1;
    }

  int r = pthread_barrier_wait (&b);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      puts ("parent thread: barrier_wait failed");
      return 1;
    }

  sleep (1);

  r = pthread_kill (th, SIGHUP);
  if (r)
    {
      errno = r;
      printf ("pthread_kill failed %m\n");
      return 1;
    }

  while (in_sh_body == 0)
    sleep (1);

  if (pthread_cancel (th) != 0)
    {
      puts ("cancel failed");
      return 1;
    }

  /* This will cause the read in the child to return.  */
  close (fd[0]);
  close (fd[1]);
  close (fd[2]);
  close (fd[3]);

  void *ret;
  if (pthread_join (th, &ret) != 0)
    {
      puts ("join failed");
      return 1;
    }

  if (ret != PTHREAD_CANCELED)
    {
      puts ("result is wrong");
      return 1;
    }

  if (cleanups != 0x1234L)
    {
      printf ("called cleanups %lx\n", cleanups);
      return 1;
    }

  return 0;
}
Ejemplo n.º 17
0
int main(int argc[], char *argv[]){
	int dimensao;
	float **matriz;
    float *vetorIndependente;
    
    int i, j, t, l, status_t, tam, *vet;
	int linha = 0;
	pid_t pid = 1;


    printf("Digite o dimensao da matriz seguido dos elementos e do vetor independente:");
    scanf("%d", &dimensao);

    int TAM_BUFFER = dimensao+3;	
	
	matriz = le_matriz(dimensao, dimensao);

    vetorIndependente = le_vetor(dimensao);

    //criação dos filhos
	
	int REF = 1;
	int inicio = 0;
	
	while(REF != dimensao){
		int fd[2];
		float buffer[TAM_BUFFER];
		if(pipe(fd) == -1) printf("Erro na funcao que cria o descritor de arquivo!\n");
		
		for(i=0; i<(dimensao-REF); i++){
			if(pid!=0){
				sleep(10);
				pid = fork();
				inicio = i+REF;		// inicio vai determinar a linha que será usada como referencia
			}
		}

		if(pid == 0){
		float constante = (matriz[inicio][REF-1]) / (matriz[REF-1][REF-1]);
		float *vetor_auxiliar;
		vetor_auxiliar =  calloc(dimensao+2,sizeof(float));
		
		int w = REF-1;
		for(i=(REF-1); i<dimensao; i++){
				vetor_auxiliar[w] = matriz[inicio][i] - ((matriz[REF-1][i])*constante);
				w++;
		}
		vetor_auxiliar[w] = vetorIndependente[inicio] - ((vetorIndependente[REF-1])*constante);
		vetor_auxiliar[w+1] = inicio;
		
		close(fd[0]);
		write(fd[1], vetor_auxiliar, (TAM_BUFFER)*sizeof(float));
		exit(0);
		sleep(5);
		}
		

		// FIM DA EXECUÇÃO DOS FILHOS


		if (pid != 0){
			close(fd[1]);
			
			for (l=0; l<dimensao-REF; l++){
				read(fd[0], buffer, sizeof(buffer));
				
				linha = (buffer[dimensao+1]);
				int y = 0;
				for(i=0; i<dimensao+1; i++){
					matriz[linha][i] = buffer[y];
					y++;
				}
				vetorIndependente[linha] = buffer[dimensao];
			}

		}
		REF += 1;
	}
	sleep(5);

	// REALIZANDO A ELIMINAÇÃO

	float *vetor_resultados = NULL;
    
    vetor_resultados = (float *) calloc(dimensao, sizeof(float));
	float soma = 0;

	for (i = dimensao; i>0; i=i-1){
		soma = vetorIndependente[i-1];
	
		for (j=i; j<dimensao; j++){
			soma += (matriz[i-1][j]*vetor_resultados[j]) * (-1);
		}
	
		vetor_resultados[i-1] = soma / matriz[i-1][i-1];
	}

	// REALIZANDO A ELIMINAÇÃO

	printf("\n");
	
	//Imprimindo o vetor resultado
	for(i=0; i<dimensao; i++){
        printf("%f ",vetor_resultados[i]);
	}
	
	free_matrix(dimensao, matriz);
	free_vector(vetorIndependente);
	

	return 0;

}
Ejemplo n.º 18
0
/** Fork and exec entire filter chain.
 *  @param chain The head of the chain.
 *  @return true on success.
 */
bool filter_apply_chain (struct filter * chain)
{
	int     pid, pipes[2];
	int     r;
	const int readsz = 512;
	char   *buf;


	/* Tricky recursion, since we want to begin the chain
	 * at the END. Why? Because we need all the forked processes
	 * to be children of the main flex process.
	 */
	if (chain)
		filter_apply_chain (chain->next);
	else
		return true;

	/* Now we are the right-most unprocessed link in the chain.
	 */

	fflush (stdout);
	fflush (stderr);


	if (pipe (pipes) == -1)
		flexerror (_("pipe failed"));

	if ((pid = fork ()) == -1)
		flexerror (_("fork failed"));

	if (pid == 0) {
		/* child */

        /* We need stdin (the FILE* stdin) to connect to this new pipe.
         * There is no portable way to set stdin to a new file descriptor,
         * as stdin is not an lvalue on some systems (BSD).
         * So we dup the new pipe onto the stdin descriptor and use a no-op fseek
         * to sync the stream. This is a Hail Mary situation. It seems to work.
         */
		close (pipes[1]);
clearerr(stdin);
		if (dup2 (pipes[0], fileno (stdin)) == -1)
			flexfatal (_("dup2(pipes[0],0)"));
		close (pipes[0]);
        fseek (stdin, 0, SEEK_CUR);

		/* run as a filter, either internally or by exec */
		if (chain->filter_func) {
			int     r;

			if ((r = chain->filter_func (chain)) == -1)
				flexfatal (_("filter_func failed"));
			exit (0);
		}
		else {
			execvp (chain->argv[0],
				(char **const) (chain->argv));
            lerrsf_fatal ( _("exec of %s failed"),
                    chain->argv[0]);
		}

		exit (1);
	}

	/* Parent */
	close (pipes[0]);
	if (dup2 (pipes[1], fileno (stdout)) == -1)
		flexfatal (_("dup2(pipes[1],1)"));
	close (pipes[1]);
    fseek (stdout, 0, SEEK_CUR);

	return true;
}
Ejemplo n.º 19
0
static int
do_test (void)
{
  int result = 0;
  int piped[2];

  /* Make a pipe that we will never write to, so we can block reading it.  */
  if (pipe (piped) < 0)
    {
      perror ("pipe");
      return 1;
    }

  /* Test for aio_cancel() detecting invalid file descriptor.  */
  {
    struct aiocb cb;
    int fd = -1;

    cb.aio_fildes = fd;
    cb.aio_offset = 0;
    cb.aio_buf = NULL;
    cb.aio_nbytes = 0;
    cb.aio_reqprio = 0;
    cb.aio_sigevent.sigev_notify = SIGEV_NONE;

    errno = 0;

    /* Case one: invalid fds that match.  */
    if (aio_cancel (fd, &cb) != -1 || errno != EBADF)
      {
	if (errno == ENOSYS)
	  {
	    puts ("no aio support in this configuration");
	    return 0;
	  }

	puts ("aio_cancel( -1, {-1..} ) did not return -1 or errno != EBADF");
	++result;
      }

    cb.aio_fildes = -2;
    errno = 0;

    /* Case two: invalid fds that do not match; just print warning.  */
    if (aio_cancel (fd, &cb) != -1 || errno != EBADF)
      puts ("aio_cancel( -1, {-2..} ) did not return -1 or errno != EBADF");
  }

  /* Test for aio_fsync() detecting bad fd.  */
  {
    struct aiocb cb;
    int fd = -1;

    cb.aio_fildes = fd;
    cb.aio_offset = 0;
    cb.aio_buf = NULL;
    cb.aio_nbytes = 0;
    cb.aio_reqprio = 0;
    cb.aio_sigevent.sigev_notify = SIGEV_NONE;

    errno = 0;

    /* Case one: invalid fd.  */
    if (aio_fsync (O_SYNC, &cb) != -1 || errno != EBADF)
      {
	puts ("aio_fsync( op, {-1..} ) did not return -1 or errno != EBADF");
	++result;
      }
  }

  /* Test for aio_suspend() suspending even if completed elements in list.  */
  {
#define BYTES 8
    const int ELEMS = 2;
    int i, r, fd;
    static char buff[BYTES];
    char name[] = "/tmp/aio7.XXXXXX";
    struct timespec timeout;
    static struct aiocb cb0, cb1;
    struct aiocb *list[ELEMS];

    fd = mkstemp (name);
    if (fd < 0)
      error (1, errno, "creating temp file");

    if (unlink (name))
      error (1, errno, "unlinking temp file");

    if (write (fd, "01234567", BYTES) != BYTES)
      error (1, errno, "writing to temp file");

    cb0.aio_fildes = fd;
    cb0.aio_offset = 0;
    cb0.aio_buf = buff;
    cb0.aio_nbytes = BYTES;
    cb0.aio_reqprio = 0;
    cb0.aio_sigevent.sigev_notify = SIGEV_NONE;

    r = aio_read (&cb0);
    if (r != 0)
      error (1, errno, "reading from file");

    while (aio_error (&(cb0)) == EINPROGRESS)
      usleep (10);

    for (i = 0; i < BYTES; i++)
      printf ("%c ", buff[i]);
    printf ("\n");

    /* At this point, the first read is completed, so start another one on
       the read half of a pipe on which nothing will be written.  */
    cb1.aio_fildes = piped[0];
    cb1.aio_offset = 0;
    cb1.aio_buf = buff;
    cb1.aio_nbytes = BYTES;
    cb1.aio_reqprio = 0;
    cb1.aio_sigevent.sigev_notify = SIGEV_NONE;

    r = aio_read (&cb1);
    if (r != 0)
      error (1, errno, "reading from file");

    /* Now call aio_suspend() with the two reads.  It should return
     * immediately according to the POSIX spec.
     */
    list[0] = &cb0;
    list[1] = &cb1;
    timeout.tv_sec = 3;
    timeout.tv_nsec = 0;
    r = aio_suspend ((const struct aiocb * const *) list, ELEMS, &timeout);

    if (r == -1 && errno == EAGAIN)
      {
	puts ("aio_suspend([done,blocked],2,3) suspended thread");
	++result;
      }

    /* Note that CB1 is still pending, and so cannot be an auto variable.
       Thus we also test that exiting with an outstanding request works.  */
  }

  return result;
}
Ejemplo n.º 20
0
void
startcmd(Conn *c, char *cmd, int *kidpid, int *kidin)
{
	int i, pid, kpid;
	int pfd[3][2];
	char *dir;
	char *sysname, *tz;
	Msg *m;
	Waitmsg *w;

	for(i=0; i<3; i++)
		if(pipe(pfd[i]) < 0)
			sysfatal("pipe: %r");

	sysname = getenv("sysname");
	tz = getenv("timezone");

	switch(pid = rfork(RFPROC|RFMEM|RFNOWAIT)){
	case -1:
		sysfatal("fork: %r");
	case 0:
		switch(kpid = rfork(RFPROC|RFNOTEG|RFENVG|RFFDG)){
		case -1:
			sysfatal("fork: %r");
		case 0:
			for(i=0; i<3; i++){
				if(dup(pfd[i][1], i) < 0)
					sysfatal("dup: %r");
				close(pfd[i][0]);
				close(pfd[i][1]);
			}
			putenv("user", c->user);
			if(sysname)
				putenv("sysname", sysname);
			if(tz)
				putenv("tz", tz);
	
			dir = smprint("/usr/%s", c->user);
			if(dir == nil || chdir(dir) < 0)
				chdir("/");
			if(cmd){
				putenv("service", "rx");
				execl("/bin/rc", "rc", "-lc", cmd, nil);
				sysfatal("cannot exec /bin/rc: %r");
			}else{
				putenv("service", "con");
				execl("/bin/ip/telnetd", "telnetd", "-tn", nil);
				sysfatal("cannot exec /bin/ip/telnetd: %r");
			}
		default:
			*kidpid = kpid;
			rendezvous(kidpid, 0);
			for(;;){
				if((w = wait()) == nil)
					sysfatal("wait: %r");
				if(w->pid == kpid)
					break;
				free(w);
			}
			if(w->msg[0]){
				m = allocmsg(c, SSH_MSG_DISCONNECT, 4+strlen(w->msg));
				putstring(m, w->msg);
				sendmsg(m);
			}else{
				m = allocmsg(c, SSH_SMSG_EXITSTATUS, 4);
				putlong(m, 0);
				sendmsg(m);
			}
			for(i=0; i<3; i++)
				close(pfd[i][0]);
			free(w);
			exits(nil);	
			break;
		}
	default:
		atexitkill(pid);
		rendezvous(kidpid, 0);
		break;
	}

	for(i=0; i<3; i++)
		close(pfd[i][1]);

	copyout(c, pfd[1][0], SSH_SMSG_STDOUT_DATA);
	copyout(c, pfd[2][0], SSH_SMSG_STDERR_DATA);
	*kidin = pfd[0][0];
}
Ejemplo n.º 21
0
int forkinet(int port) {
    FILE *fp;
    char logbuf[256];

    int sock;
    int pipeid[2];
    pid_t cpid; /* process id of the child */
    pid_t pid;

    /* create the pipe */

    if (pipe(pipeid) <0) return -1;

    /*
      The pipe was non-blocking, but this causes a problem if the client
      cannot cope with the incoming data rate from multiplexed streams.


        if ((status=fcntl(pipeid[1],F_GETFL))==-1) return -1;
        status|=O_NONBLOCK;
        if ((status=fcntl(pipeid[1],F_SETFL,status))==-1) return -1;
    */

    if ((cpid=fork()) !=0) {
        close(pipeid[0]);
        return pipeid[1];
    }

    close(pipeid[1]);

    loginfo(logfname,"Child Server Process Starting");

    sock=createsocket(&port);

    if (sock==-1) {
        loginfo(logfname,"Failed to create socket");
        close(pipeid[0]);
        exit(0);
    }

    fp=fopen(pname,"w");
    fprintf(fp,"%d\n",port);
    fclose(fp);
    sprintf(logbuf,"Listening on port %d.",port);
    loginfo(logfname,logbuf);
    sprintf(logbuf,"Port number recorded in file %s.",pname);
    loginfo(logfname,logbuf);
    sprintf(logbuf,"Time of last packet recorded in file %s.",timefname);
    loginfo(logfname,logbuf);
    fp=fopen(pidname,"w");
    pid=getppid();
    sprintf(logbuf,"Process ID recorded in file %s.",pidname);
    loginfo(logfname,logbuf);
    sprintf(logbuf,"Parent PID %d.",(int) pid);
    loginfo(logfname,logbuf);
    fprintf(fp,"%d\n",(int) pid);
    pid=getpid();
    sprintf(logbuf,"Child PID %d.",(int) pid);
    loginfo(logfname,logbuf);
    fprintf(fp,"%d\n",(int) pid);
    fclose(fp);

    processsocket(sock,pipeid[0]);
    close(sock);
    close(pipeid[0]);
    loginfo(logfname,"Child Server Process Terminating");
    exit(0);
    return -1;
}
Ejemplo n.º 22
0
int main(){

	int a2b[2], b2a[2];
	pipe(a2b); pipe(b2a);

	int num;
	printf("Enter number: ");
	scanf("%d", &num);

	//forking
	switch(fork()) {

		//error handling
		case -1:
			printf("Error at forking\n!");
			break;


		//child
		case 0:
			close(a2b[W]); close(b2a[R]);
			
			while(1){
			read(a2b[R], &num, sizeof(int));
				if( num % 2 == 0) {
					num = num / 2;
					printf("S number: %d\n", num);
					write(b2a[W], &num, sizeof(int));
				}
				else {
					printf("DONE");
					break;
					}
			}

			close(a2b[R]); close(b2a[W]);
			exit(0);
			
			break;


		default:
			close(a2b[R]); close(b2a[W]);
	
			write(a2b[W], &num, sizeof(int));
			while(1){
				read(b2a[R], &num, sizeof(int));
				if(num / 3 != 0){
					num = num /3;
					printf("F. number: %d\n", num);
					write(a2b[W], &num, sizeof(int));
				} else {
					printf("Done");
					break;
					}
				}
			close(a2b[W]); close(b2a[R]);
			wait(0);
			break;

		}


		return 0;

		}
int main(int argc, char *argv[]){

  //DO NOT EDIT
  char * cmd[] = {"cat", NULL};
  int cpid;
  int pfd_1[2] = {-1,-1} ,pfd_2[2] = {-1,-1};
  char c;

  //TODO: add neccesary pipeline code
  if ( pipe(pfd_1) < 0){
    perror("pipe");
    return 1;
  }

  if ( pipe(pfd_2) < 0){
    perror("pipe");
    return 1;
  }
  
  if( (cpid = fork()) ) {
    /* CHILD 1 */

    //TODO: add neccesary pipeline code
    close(0);
    close(1);
    dup2(pfd_1[0], 0);
    dup2(pfd_2[1], 1);



    if( (cpid = fork()) ) {
      /* CHILD 2*/

      //TODO: add neccesary pipeline code
      
      close(0);

      //duplicate reading end to stdin
      dup2(pfd_2[0], 0);

      //close the writing end
      close(pfd_2[1]);




      //DO NOT EDIT/////////////////////////
      //read from pfd_2 and write to stdout
      while(1){
	if(read(pfd_2[0],&c,1) > 0){
	  write(1,&c,1);
	}else{
	  exit(0);
	}
      }
      ////////////////////////////////////

    }else if(cpid == 0){
      /* CHILD 1 */


      //TODO: add neccesary pipeline code
      close(pfd_2[0]);
    
      //close(pfd_2[1]);
      close(0);
      close(1);

      //DO NOT EDIT/////////////////////////
      //read from pfd_1 and write to pfd_2
      while(1){
	if(read(pfd_1[0],&c,1) > 0){
	  write(pfd_2[1],&c,1);
	}else{
	  exit(0);
	}
      }
      ////////////////////////////////////
    }      

  }else if(cpid == 0){
    /* PARENT */

    //close stdout should duplicate pipe onto it
    close(1);

    //TODO: add neccesary pipeline and duplication
    dup2(pfd_1[1], 1);

    close(pfd_1[0]);
   
   
    //DO NOT EDIT/////////////////////////
    //execute the cat command
    execvp(cmd[0], cmd);
    perror("exec failure");
    _exit(1);
    ////////////////////////////////////
  }

}
Ejemplo n.º 24
0
int
lisp_pipe(int pipefd[2])
{
  return pipe(pipefd);
}
Ejemplo n.º 25
0
const
size_t assemble_armv7(
		uint8_t *const bytecode,
		const size_t bytecode_sz,
		const char *const assembly,
		const size_t asm_sz)
{
	size_t sz = 0;

	char path[PATH_MAX];
	snprintf(path, sizeof(path), "/tmp/rappel-output.XXXXXX");

	const int t = mkstemp(path);

	if (t == -1) {
		perror("mkstemp");
		exit(EXIT_FAILURE);
	}

	REQUIRE (unlink(path) == 0);

	int fildes[2] = {-1, -1};
	REQUIRE (pipe(fildes) == 0);

	const pid_t asm_pid = fork();

	if (asm_pid < 0) {
		perror("fork");
		exit(EXIT_FAILURE);
	} else if (asm_pid == 0) {
		_child_assemble(fildes, t);
		// Not reached
		abort();
	}

	verbose_printf("as is pid %d\n", asm_pid);

	REQUIRE (close(fildes[0]) == 0);

	write_data(fildes[1], (uint8_t *)assembly, asm_sz);

	REQUIRE (close(fildes[1]) == 0);

	int asm_status = -1;
	REQUIRE (waitpid(asm_pid, &asm_status, 0) != -1);

	if (WIFSIGNALED(asm_status)) {
		fprintf(stderr, "as exited with signal %d.\n", WTERMSIG(asm_status));
	} else if (WIFEXITED(asm_status) && WEXITSTATUS(asm_status)) {
		fprintf(stderr, "as exited %d.\n", WEXITSTATUS(asm_status));
		goto exit;
	}

	REQUIRE (lseek(t, SEEK_SET, 0) != -1);

	int results[2] = {-1, -1};
	REQUIRE (pipe(results) == 0);

	const pid_t objcopy_pid = fork();

	if (objcopy_pid < 0) {
		perror("fork");
		exit(EXIT_FAILURE);
	} else if (objcopy_pid == 0) {
		_child_objcopy(results, t);
		// Not reached
		abort();
	}

	verbose_printf("objcopy is pid %d\n", objcopy_pid);

	REQUIRE (close(results[1]) == 0);

	mem_assign(bytecode, bytecode_sz, TRAP, TRAP_SZ);

	sz = read_data(results[0], bytecode, bytecode_sz);

	REQUIRE (close(results[0]) == 0);

	if (sz >= bytecode_sz) {
		fprintf(stderr, "Too much bytecode to handle, exiting...\n");
		exit(EXIT_FAILURE);
	}

	int objcopy_status = -1;
	REQUIRE (waitpid(objcopy_pid, &objcopy_status, 0) != -1);

	if (WIFEXITED(objcopy_status) && WIFSIGNALED(objcopy_status))
		fprintf(stderr, "objcopy exited with signal %d.\n", WTERMSIG(objcopy_status));
	else if (WIFEXITED(objcopy_status) && WEXITSTATUS(objcopy_status))
		fprintf(stderr, "objcopy exited %d.\n", WEXITSTATUS(objcopy_status));

exit:
	REQUIRE (close(t) == 0);

	return sz;
}
Ejemplo n.º 26
0
/** A work queue is a mechanism to allow thread-to-thread
 *  communication in a libevent-based, multithreaded system.
 *
 *  One thread can send work to another thread.  The receiving thread
 *  should be libevent-based, with a processing loop handled by
 *  libevent.
 *
 *  Use work_queue_init() to initialize a work_queue structure,
 *  where the work_queue structure memory is owned by the caller.
 *
 *  Returns true on success.
 */
bool work_queue_init(work_queue *m, struct event_base *event_base) {
    assert(m != NULL);

    memset(m, 0, sizeof(work_queue));

    pthread_mutex_init(&m->work_lock, NULL);

    m->work_head = NULL;
    m->work_tail = NULL;

    m->num_items = 0;
    m->tot_sends = 0;
    m->tot_recvs = 0;

    m->event_base = event_base;
    assert(m->event_base != NULL);

    int fds[2] = {0};
#ifdef WIN32
    struct sockaddr_in serv_addr;
    int sockfd;

    if ((sockfd = createLocalListSock(&serv_addr)) < 0 ||
        createLocalSocketPair(sockfd,fds,&serv_addr) == -1)
    {
        fprintf(stderr, "Can't create notify pipe: %s", strerror(errno));
        return false;
    }
#else
    if (pipe(fds)) {
        perror("Can't create notify pipe");
        return false;
    }
#endif

    m->recv_fd = fds[0];
    m->send_fd = fds[1];

    event_set(&m->event, m->recv_fd,
              EV_READ | EV_PERSIST, work_recv, m);
    event_base_set(m->event_base, &m->event);

    if (event_add(&m->event, 0) == 0) {
#ifdef WORK_DEBUG
            moxi_log_write("work_queue_init %x %x %x %d %d %u %llu\n",
                    (int) pthread_self(),
                    (int) m,
                    (int) m->event_base,
                    m->send_fd,
                    m->recv_fd,
                    m->work_head != NULL,
                    m->tot_sends);
#endif

        return true;
    }

#ifdef WORK_DEBUG
    moxi_log_write("work_queue_init error\n");
#endif

    return false;
}
Ejemplo n.º 27
0
int start_async(struct async *async)
{
	int need_in, need_out;
	int fdin[2], fdout[2];
	int proc_in, proc_out;

	need_in = async->in < 0;
	if (need_in) {
		if (pipe(fdin) < 0) {
			if (async->out > 0)
				close(async->out);
			return error("cannot create pipe: %s", strerror(errno));
		}
		async->in = fdin[1];
	}

	need_out = async->out < 0;
	if (need_out) {
		if (pipe(fdout) < 0) {
			if (need_in)
				close_pair(fdin);
			else if (async->in)
				close(async->in);
			return error("cannot create pipe: %s", strerror(errno));
		}
		async->out = fdout[0];
	}

	if (need_in)
		proc_in = fdin[0];
	else if (async->in)
		proc_in = async->in;
	else
		proc_in = -1;

	if (need_out)
		proc_out = fdout[1];
	else if (async->out)
		proc_out = async->out;
	else
		proc_out = -1;

#ifdef NO_PTHREADS
	/* Flush stdio before fork() to avoid cloning buffers */
	fflush(NULL);

	async->pid = fork();
	if (async->pid < 0) {
		error("fork (async) failed: %s", strerror(errno));
		goto error;
	}
	if (!async->pid) {
		if (need_in)
			close(fdin[1]);
		if (need_out)
			close(fdout[0]);
		git_atexit_clear();
		exit(!!async->proc(proc_in, proc_out, async->data));
	}

	mark_child_for_cleanup(async->pid);

	if (need_in)
		close(fdin[0]);
	else if (async->in)
		close(async->in);

	if (need_out)
		close(fdout[1]);
	else if (async->out)
		close(async->out);
#else
	if (!main_thread_set) {
		/*
		 * We assume that the first time that start_async is called
		 * it is from the main thread.
		 */
		main_thread_set = 1;
		main_thread = pthread_self();
		pthread_key_create(&async_key, NULL);
		pthread_key_create(&async_die_counter, NULL);
		set_die_routine(die_async);
		set_die_is_recursing_routine(async_die_is_recursing);
	}

	if (proc_in >= 0)
		set_cloexec(proc_in);
	if (proc_out >= 0)
		set_cloexec(proc_out);
	async->proc_in = proc_in;
	async->proc_out = proc_out;
	{
		int err = pthread_create(&async->tid, NULL, run_thread, async);
		if (err) {
			error("cannot create thread: %s", strerror(err));
			goto error;
		}
	}
#endif
	return 0;

error:
	if (need_in)
		close_pair(fdin);
	else if (async->in)
		close(async->in);

	if (need_out)
		close_pair(fdout);
	else if (async->out)
		close(async->out);
	return -1;
}
Ejemplo n.º 28
0
/*
 * invoke RSH
 */
int rsh_exec(struct socket *so, struct socket *ns,
	char *user, char *host, char *args)
{
	int fd[2];
	int fd0[2];
	int s;
	char buff[256];
	
	DEBUG_CALL("rsh_exec");
	DEBUG_ARG("so = %lx", (long)so);
	
	if (pipe(fd)<0) {
          lprint("Error: pipe failed: %s\n", strerror(errno));
          return 0;
	}
/* #ifdef HAVE_SOCKETPAIR */
#if 1
        if (socketpair(PF_UNIX,SOCK_STREAM,0, fd0) == -1) {
          close(fd[0]);
          close(fd[1]);
          lprint("Error: openpty failed: %s\n", strerror(errno));
          return 0;
        }
#else
        if (slirp_openpty(&fd0[0], &fd0[1]) == -1) {
          close(fd[0]);
          close(fd[1]);
          lprint("Error: openpty failed: %s\n", strerror(errno));
          return 0;
        }
#endif
	
	switch(fork()) {
	 case -1:
           lprint("Error: fork failed: %s\n", strerror(errno));
           close(fd[0]);
           close(fd[1]);
           close(fd0[0]);
           close(fd0[1]);
           return 0;
           
	 case 0:
           close(fd[0]);
           close(fd0[0]);
           
		/* Set the DISPLAY */
           if (x_port >= 0) {
#ifdef HAVE_SETENV
             sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
             setenv("DISPLAY", buff, 1);
#else
             sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
             putenv(buff);
#endif
           }
           
           dup2(fd0[1], 0);
           dup2(fd0[1], 1);
           dup2(fd[1], 2);
           for (s = 3; s <= 255; s++)
             close(s);
           
           execlp("rsh","rsh","-l", user, host, args, NULL);
           
           /* Ooops, failed, let's tell the user why */
           
           sprintf(buff, "Error: execlp of %s failed: %s\n", 
                   "rsh", strerror(errno));
           write(2, buff, strlen(buff)+1);
           close(0); close(1); close(2); /* XXX */
           exit(1);
           
        default:
          close(fd[1]);
          close(fd0[1]);
          ns->s=fd[0];
          so->s=fd0[0];
          
          return 1;
	}
}
Ejemplo n.º 29
0
int spawn(char *program, char *argv[], int sin, int sout, int serr,
          int search, char *envp[], char *pty_name, int wait, char *pwd)
{
    pid_t pid;
    int fd;
    int channel[2];
    sigset_t sset;
    int failure_code = 2;

    channel[0] = -1;
    channel[1] = -1;
    if (!pipe(channel)) {
        if (-1==fcntl(channel[1], F_SETFD,  FD_CLOEXEC)) {
            close(channel[1]);
            channel[1] = -1;
        }
    }

    pid = fork();
    if (pid) {
        if ((-1 != pid) && (-1 != channel[1])) {
            int child_errno = 0;
            int bytes = sizeof(int);
            int n;
            char *p = (char*)&child_errno;
            close(channel[1]);
            /* Try to read child errno from channel. */
            while ((bytes > 0) &&
                   (n = read(channel[0], p, bytes))) {
                if (-1 == n) {
                    if (EINTR == errno) {
                        continue;
                    } else {
                        break;
                    }
                } else {
                    bytes -= n;
                    p += n;
                }
            }
            close(channel[0]);
            if (child_errno) {
                int status;
                waitpid(pid, &status, 0);
                /* Our convention to tell Lisp that it was the exec or
                   chdir that failed, not the fork. */
                /* FIXME: there are other values waitpid(2) can return. */
                if (WIFEXITED(status)) {
                  pid = -WEXITSTATUS(status);
                }
                errno = child_errno;
            }
        }
        return pid;
    }
    close (channel[0]);

    /* Put us in our own process group, but only if we need not
     * share stdin with our parent. In the latter case we claim
     * control of the terminal. */
    if (sin >= 0) {
#if defined(LISP_FEATURE_HPUX) || defined(LISP_FEATURE_OPENBSD)
      setsid();
#elif defined(LISP_FEATURE_DARWIN)
      setpgid(0, getpid());
#elif defined(SVR4) || defined(__linux__) || defined(__osf__) || defined(__GLIBC__)
      setpgrp();
#else
      setpgrp(0, getpid());
#endif
    } else {
      tcsetpgrp(0, getpgrp());
    }

    /* unblock signals */
    sigemptyset(&sset);
    sigprocmask(SIG_SETMASK, &sset, NULL);

    /* If we are supposed to be part of some other pty, go for it. */
    if (pty_name)
        set_pty(pty_name);
    else {
    /* Set up stdin, stdout, and stderr */
    if (sin >= 0)
        dup2(sin, 0);
    if (sout >= 0)
        dup2(sout, 1);
    if (serr >= 0)
        dup2(serr, 2);
    }
    /* Close all other fds. */
#ifdef SVR4
    for (fd = sysconf(_SC_OPEN_MAX)-1; fd >= 3; fd--)
        if (fd != channel[1]) close(fd);
#else
    for (fd = getdtablesize()-1; fd >= 3; fd--)
        if (fd != channel[1]) close(fd);
#endif

    if (pwd && chdir(pwd) < 0) {
       failure_code = 3;
    } else {
        if (envp) {
            environ = envp;
        }
        /* Exec the program. */
        if (search)
            execvp(program, argv);
        else
            execv(program, argv);
    }

    /* When exec or chdir fails and channel is available, send the errno value. */
    if (-1 != channel[1]) {
        int our_errno = errno;
        int bytes = sizeof(int);
        int n;
        char *p = (char*)&our_errno;
        while ((bytes > 0) &&
               (n = write(channel[1], p, bytes))) {
            if (-1 == n) {
                if (EINTR == errno) {
                    continue;
                } else {
                    break;
                }
            } else {
                bytes -= n;
                p += n;
            }
        }
        close(channel[1]);
    }
    _exit(failure_code);
}
Ejemplo n.º 30
0
void ANativeActivity_onCreate(ANativeActivity* activity,
      void* savedState, size_t savedStateSize)
{
   int msgpipe[2];
   struct android_app* android_app;

   (void)savedState;
   (void)savedStateSize;

   RARCH_LOG("Creating Native Activity: %p\n", activity);
   activity->callbacks->onDestroy = onDestroy;
   activity->callbacks->onStart = onStart;
   activity->callbacks->onResume = onResume;
   activity->callbacks->onSaveInstanceState = NULL;
   activity->callbacks->onPause = onPause;
   activity->callbacks->onStop = onStop;
   activity->callbacks->onConfigurationChanged = onConfigurationChanged;
   activity->callbacks->onLowMemory = NULL;
   activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
   activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
   activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
   activity->callbacks->onInputQueueCreated = onInputQueueCreated;
   activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;

   // these are set only for the native activity, and are reset when it ends
   ANativeActivity_setWindowFlags(activity, AWINDOW_FLAG_KEEP_SCREEN_ON | AWINDOW_FLAG_FULLSCREEN, 0);

   if (pthread_key_create(&thread_key, jni_thread_destruct))
      RARCH_ERR("Error initializing pthread_key\n");

   android_app = (struct android_app*)calloc(1, sizeof(*android_app));
   if (!android_app)
   {
      RARCH_ERR("Failed to initialize android_app\n");
      return;
   }

   memset(android_app, 0, sizeof(struct android_app));
   android_app->activity = activity;

   android_app->mutex = slock_new();
   android_app->cond  = scond_new();

   if (pipe(msgpipe))
   {
      RARCH_ERR("could not create pipe: %s.\n", strerror(errno));
      activity->instance = NULL;
   }
   android_app->msgread = msgpipe[0];
   android_app->msgwrite = msgpipe[1];

   android_app->thread = sthread_create(android_app_entry, android_app);

   // Wait for thread to start.
   slock_lock(android_app->mutex);
   while (!android_app->running)
      scond_wait(android_app->cond, android_app->mutex);
   slock_unlock(android_app->mutex);

   activity->instance = android_app;
}