示例#1
0
static pid_t spawn_ppp(struct cw_channel *chan, const char *argv[])
{
	/* Start by forking */
	pid_t pid;

#if defined(HAVE_WORKING_FORK)
    pid = fork();
#else
    pid = vfork();
#endif
	if (pid)
		return pid;

	dup2(chan->fds[0], STDIN_FILENO);

	int i;
	int max_fds = get_max_fds();
	for (i=STDERR_FILENO + 1; i < max_fds; i++)
		close(i);

	/* Restore original signal handlers */
	for (i=0; i<NSIG; i++)
		signal(i, SIG_DFL);

	/* Finally launch PPP */
	execv(PPP_EXEC, (char * const *)argv);
	fprintf(stderr, "Failed to exec pppd!: %s\n", strerror(errno));
	exit(1);
}
示例#2
0
/* Close all file descriptors starting with descriptor FIRST.  If
   EXCEPT is not NULL, it is expected to be a list of file descriptors
   which shall not be closed.  This list shall be sorted in ascending
   order with the end marked by -1.  */
void
close_all_fds (int first, int *except)
{
    int max_fd = get_max_fds ();
    int fd, i, except_start;

    if (except)
    {
        except_start = 0;
        for (fd=first; fd < max_fd; fd++)
        {
            for (i=except_start; except[i] != -1; i++)
            {
                if (except[i] == fd)
                {
                    /* If we found the descriptor in the exception list
                       we can start the next compare run at the next
                       index because the exception list is ordered.  */
                    except_start = i + 1;
                    break;
                }
            }
            if (except[i] == -1)
                close (fd);
        }
    }
    else
    {
        for (fd=first; fd < max_fd; fd++)
            close (fd);
    }

    gpg_err_set_errno (0);
}
示例#3
0
tcpdemux::tcpdemux():outdir("."),flow_counter(0),packet_counter(0),
		     xreport(0),pwriter(0),max_open_flows(),max_fds(get_max_fds()-NUM_RESERVED_FDS),
                     flow_map(),open_flows(),saved_flow_map(),
		     saved_flows(),start_new_connections(false),opt(),fs()
		     
{
}
示例#4
0
static pid_t spawn_ppp(
	struct ast_channel *chan,
	const char *argv[],
	int argc)
{
	/* Start by forking */
	pid_t pid = fork();
	if (pid)
		return pid;

	close(0);

	int i;
	int max_fds = get_max_fds();
	for (i=STDERR_FILENO + 1; i < max_fds; i++)
		close(i);

	/* Restore original signal handlers */
	for (i=0; i<NSIG; i++)
		signal(i, SIG_DFL);

	/* Finally launch PPP */
	execv(PPP_EXEC, (char * const *)argv);
	fprintf(stderr, "Failed to exec pppd!: %s\n", strerror(errno));
	exit(1);
}
示例#5
0
tcpdemux::tcpdemux():
#ifdef HAVE_SQLITE3
    db(),insert_flow(),
#endif
    outdir("."),flow_counter(0),packet_counter(0),
    xreport(0),pwriter(0),max_open_flows(),max_fds(get_max_fds()-NUM_RESERVED_FDS),
    flow_map(),open_flows(),saved_flow_map(),
    saved_flows(),start_new_connections(false),opt(),fs()
{
}
示例#6
0
文件: process.c 项目: InCNTRE/OFTT
/* Starts a subprocess with the arguments in the null-terminated argv[] array.
 * argv[0] is used as the name of the process.  Searches the PATH environment
 * variable to find the program to execute.
 *
 * All file descriptors are closed before executing the subprocess, except for
 * fds 0, 1, and 2 and the 'n_keep_fds' fds listed in 'keep_fds'.  Also, any of
 * the 'n_null_fds' fds listed in 'null_fds' are replaced by /dev/null.
 *
 * Returns 0 if successful, otherwise a positive errno value indicating the
 * error.  If successful, '*pp' is assigned a new struct process that may be
 * used to query the process's status.  On failure, '*pp' is set to NULL. */
int
process_start(char **argv,
              const int keep_fds[], size_t n_keep_fds,
              const int null_fds[], size_t n_null_fds,
              struct process **pp)
{
    sigset_t oldsigs;
    pid_t pid;
    int error;

    *pp = NULL;
    COVERAGE_INC(process_start);
    error = process_prestart(argv);
    if (error) {
        return error;
    }

    block_sigchld(&oldsigs);
    pid = fork();
    if (pid < 0) {
        unblock_sigchld(&oldsigs);
        VLOG_WARN("fork failed: %s", strerror(errno));
        return errno;
    } else if (pid) {
        /* Running in parent process. */
        *pp = process_register(argv[0], pid);
        unblock_sigchld(&oldsigs);
        return 0;
    } else {
        /* Running in child process. */
        int fd_max = get_max_fds();
        int fd;

        fatal_signal_fork();
        unblock_sigchld(&oldsigs);
        for (fd = 0; fd < fd_max; fd++) {
            if (is_member(fd, null_fds, n_null_fds)) {
                /* We can't use get_null_fd() here because we might have
                 * already closed its fd. */
                int nullfd = open("/dev/null", O_RDWR);
                dup2(nullfd, fd);
                close(nullfd);
            } else if (fd >= 3 && !is_member(fd, keep_fds, n_keep_fds)) {
                close(fd);
            }
        }
        execvp(argv[0], argv);
        fprintf(stderr, "execvp(\"%s\") failed: %s\n",
                argv[0], strerror(errno));
        _exit(1);
    }
}
示例#7
0
tcpdemux::tcpdemux():outdir("."),flow_counter(0),packet_counter(0),
    xreport(0),max_fds(10),flow_map(),start_new_connections(false),
    openflows(),
    opt(),fs()

{
    /* Find out how many files we can have open safely...subtract 4 for
     * stdin, stdout, stderr, and the packet filter; one for breathing
     * room (we open new files before closing old ones), and one more to
     * be safe.
     */
    max_fds = get_max_fds() - NUM_RESERVED_FDS;
}
示例#8
0
/* Returns an array with all currently open file descriptors.  The end
   of the array is marked by -1.  The caller needs to release this
   array using the *standard free* and not with xfree.  This allow the
   use of this fucntion right at startup even before libgcrypt has
   been initialized.  Returns NULL on error and sets ERRNO
   accordingly.  */
int *
get_all_open_fds (void)
{
  int *array;
  size_t narray;
  int fd, max_fd, idx;
#ifndef HAVE_STAT
  array = calloc (1, sizeof *array);
  if (array)
    array[0] = -1;
#else /*HAVE_STAT*/
  struct stat statbuf;

  max_fd = get_max_fds ();
  narray = 32;  /* If you change this change also t-exechelp.c.  */
  array = calloc (narray, sizeof *array);
  if (!array)
    return NULL;

  /* Note:  The list we return is ordered.  */
  for (idx=0, fd=0; fd < max_fd; fd++)
    if (!(fstat (fd, &statbuf) == -1 && errno == EBADF))
      {
        if (idx+1 >= narray)
          {
            int *tmp;

            narray += (narray < 256)? 32:256;
            tmp = realloc (array, narray * sizeof *array);
            if (!tmp)
              {
                free (array);
                return NULL;
              }
            array = tmp;
          }
        array[idx++] = fd;
      }
  array[idx] = -1;
#endif /*HAVE_STAT*/
  return array;
}
示例#9
0
文件: flow.c 项目: CoolCold/tcpflow
/* Initialize our structures */
void init_flow_state()
{
  int i;

  /* Find out how many files we can have open safely...subtract 4 for
   * stdin, stdout, stderr, and the packet filter; one for breathing
   * room (we open new files before closing old ones), and one more to
   * be safe. */
  max_fds = get_max_fds() - NUM_RESERVED_FDS;

  fd_ring = MALLOC(flow_state_t *, max_fds);

  for (i = 0; i < max_fds; i++)
    fd_ring[i] = NULL;

  for (i = 0; i < HASH_SIZE; i++)
    flow_hash[i] = NULL;

  next_slot = -1;
  current_time = 0;
}
示例#10
0
int main(int argc, char *argv[])
{ 
  if (argc == 1)
    print_usage();
  
  int in_guard_mode = 0;
  int dump_core = 0;
  int children_instance = 0;
  char *run_as_user = NULL;

  // parse args
  int c = -1;
  extern char *optarg;
  extern int optopt;

  const char *opt = ":gvu:Cs:ep:h";
  while((c = getopt(argc, argv, opt)) != -1)
  {
    switch (c)
    {
    case 'v':        // version
      fprintf(stderr, "\033[0;32m%s %s\033[0m\n", SVC_EDITION, BIN_V);
      return 0;
    case 'g':
      in_guard_mode = 1;
      break;
    case 'u':
      run_as_user = optarg;
      break;
    case 'C':
      dump_core = 1;
      break;
    case 'e':
      children_instance = 1;
      break;
    case 'p':
      break;
    case ':':
      fprintf(stderr, 
              "\n\033[0;35mOption -%c requires an operand\033[0m\n",
              optopt);
    case 'h':
    default:
      print_usage();
    }
  }

  const int max_clients = 1024*4;
  set_max_fds(max_clients);
  g_max_fds = get_max_fds();

  if (run_as_user && runas(run_as_user) != 0)
  {
    fprintf(stderr, "\033[0;35mSudo to %s error!\033[0m\n", 
            run_as_user);
    return -1;
  }

  if (dump_core && dump_corefile() != 0)
  {
    fprintf(stderr, "\033[0;35mSet dump corefile error!\033[0m\n");
    return -1;
  }

  if (in_guard_mode)
  {
    if (children_instance == 0)
      guard_process(g_svc_name, argc, argv);

    clean_fds();
  }else
    output_pid(g_svc_name);

  //= child process
  child_sig_handle();

  sys::r = new reactor();
  if (sys::r->open(max_clients, max_clients + 16) != 0)
  {
    fprintf(stderr, "Error: reactor - open failed!\n");
    return -1;
  }

  if (sys::init_svc() != 0)
  {
    fprintf(stderr, "Error: init_svc - init failed!\n");
    return -1;
  }

  s_log->rinfo("launch ok! max fds:%d", g_max_fds);
  e_log->rinfo("launch ok! max fds:%d", g_max_fds);

  // reactor event loop
  sys::r->run_reactor_event_loop();
  return 1;
}
示例#11
0
/* That is a very crude test.  To do a proper test we would need to
   fork a test process and best return information by some other means
   than file descriptors. */
static void
test_close_all_fds (void)
{
  int max_fd = get_max_fds ();
  int *array;
  int fd;
  int initial_count, count, n;
#if 0
  char buffer[100];

  snprintf (buffer, sizeof buffer, "/bin/ls -l /proc/%d/fd", (int)getpid ());
  system (buffer);
#endif

  printf ("max. file descriptors: %d\n", max_fd);
  array = xget_all_open_fds ();
  print_open_fds (array);
  for (initial_count=n=0; array[n] != -1; n++)
    initial_count++;
  free (array);

  /* Some dups to get more file descriptors and close one. */
  dup (1);
  dup (1);
  fd = dup (1);
  dup (1);
  close (fd);

  array = xget_all_open_fds ();
  if (verbose)
    print_open_fds (array);
  for (count=n=0; array[n] != -1; n++)
    count++;
  if (count != initial_count+3)
    {
      fprintf (stderr, "%s:%d: dup or close failed\n",
               __FILE__, __LINE__);
      exit (1);
    }
  free (array);

  /* Close the non standard ones.  */
  close_all_fds (3, NULL);

  /* Get a list to check whether they are all closed.  */
  array = xget_all_open_fds ();
  if (verbose)
    print_open_fds (array);
  for (count=n=0; array[n] != -1; n++)
    count++;
  if (count > initial_count)
    {
      fprintf (stderr, "%s:%d: not all files were closed\n",
               __FILE__, __LINE__);
      exit (1);
    }
  initial_count = count;
  free (array);

  /* Now let's check the realloc we use.  We do this and the next
     tests only if we are allowed to open enought descriptors.  */
  if (get_max_fds () > 32)
    {
      int except[] = { 20, 23, 24, -1 };

      for (n=initial_count; n < 31; n++)
        dup (1);
      array = xget_all_open_fds ();
      if (verbose)
        print_open_fds (array);
      free (array);
      for (n=0; n < 5; n++)
        {
          dup (1);
          array = xget_all_open_fds ();
          if (verbose)
            print_open_fds (array);
          free (array);
        }
      
      /* Check whether the except list works.  */
      close_all_fds (3, except);
      array = xget_all_open_fds ();
      if (verbose)
        print_open_fds (array);
      for (count=n=0; array[n] != -1; n++)
        count++;
      free (array);

      if (count != initial_count + DIM(except)-1)
        {
          fprintf (stderr, "%s:%d: close_all_fds failed\n",
                   __FILE__, __LINE__);
          exit (1);
        }
    }

}
示例#12
0
文件: process.c 项目: InCNTRE/OFTT
/* Starts the process whose arguments are given in the null-terminated array
 * 'argv' and waits for it to exit.  On success returns 0 and stores the
 * process exit value (suitable for passing to process_status_msg()) in
 * '*status'.  On failure, returns a positive errno value and stores 0 in
 * '*status'.
 *
 * If 'stdout_log' is nonnull, then the subprocess's output to stdout (up to a
 * limit of PROCESS_MAX_CAPTURE bytes) is captured in a memory buffer, which
 * when this function returns 0 is stored as a null-terminated string in
 * '*stdout_log'.  The caller is responsible for freeing '*stdout_log' (by
 * passing it to free()).  When this function returns an error, '*stdout_log'
 * is set to NULL.
 *
 * If 'stderr_log' is nonnull, then it is treated like 'stdout_log' except
 * that it captures the subprocess's output to stderr. */
int
process_run_capture(char **argv, char **stdout_log, char **stderr_log,
                    int *status)
{
    struct stream s_stdout, s_stderr;
    sigset_t oldsigs;
    pid_t pid;
    int error;

    COVERAGE_INC(process_run_capture);
    if (stdout_log) {
        *stdout_log = NULL;
    }
    if (stderr_log) {
        *stderr_log = NULL;
    }
    *status = 0;
    error = process_prestart(argv);
    if (error) {
        return error;
    }

    error = stream_open(&s_stdout);
    if (error) {
        return error;
    }

    error = stream_open(&s_stderr);
    if (error) {
        stream_close(&s_stdout);
        return error;
    }

    block_sigchld(&oldsigs);
    pid = fork();
    if (pid < 0) {
        int error = errno;

        unblock_sigchld(&oldsigs);
        VLOG_WARN("fork failed: %s", strerror(error));

        stream_close(&s_stdout);
        stream_close(&s_stderr);
        *status = 0;
        return error;
    } else if (pid) {
        /* Running in parent process. */
        struct process *p;

        p = process_register(argv[0], pid);
        unblock_sigchld(&oldsigs);

        close(s_stdout.fds[1]);
        close(s_stderr.fds[1]);
        while (!process_exited(p)) {
            stream_read(&s_stdout);
            stream_read(&s_stderr);

            stream_wait(&s_stdout);
            stream_wait(&s_stderr);
            process_wait(p);
            poll_block();
        }
        stream_read(&s_stdout);
        stream_read(&s_stderr);

        if (stdout_log) {
            *stdout_log = ds_steal_cstr(&s_stdout.log);
        }
        if (stderr_log) {
            *stderr_log = ds_steal_cstr(&s_stderr.log);
        }

        stream_close(&s_stdout);
        stream_close(&s_stderr);

        *status = process_status(p);
        process_destroy(p);
        return 0;
    } else {
        /* Running in child process. */
        int max_fds;
        int i;

        fatal_signal_fork();
        unblock_sigchld(&oldsigs);

        dup2(get_null_fd(), 0);
        dup2(s_stdout.fds[1], 1);
        dup2(s_stderr.fds[1], 2);

        max_fds = get_max_fds();
        for (i = 3; i < max_fds; i++) {
            close(i);
        }

        execvp(argv[0], argv);
        fprintf(stderr, "execvp(\"%s\") failed: %s\n",
                argv[0], strerror(errno));
        exit(EXIT_FAILURE);
    }
}