Ejemplo n.º 1
0
// FILE *debugfp=NULL;
int _evalpid(char *const argv[], char *path, int timeout, int *ppid)
{
	pid_t pid;
	int status;
	int fd;
	int flags;
	int sig;

	// if (debugfp==NULL)
	// debugfp = fopen("/tmp/evallog.log","wb");
	// char buf[254] = "";
#ifndef HAVE_X86		//we must disable this on x86 since nvram is not available at startup

	if (nvram_match("console_debug", "1")) {
		int i = 0;

		while (argv[i] != NULL) {
			fprintf(stderr, "%s ", argv[i++]);
			flog("%s ", argv[i - 1]);
		}
		fprintf(stderr, "\n");
		flog("\n");
	}
#ifndef HAVE_SILENCE
	int i = 0;

	while (argv[i] != NULL) {
		fprintf(stderr, "%s ", argv[i++]);
	}
	fprintf(stderr, "\n");

#endif
#endif

	switch (pid = fork()) {
	case -1:		/* error */
		perror("fork");
		return errno;
	case 0:		/* child */
		/*
		 * Reset signal handlers set for parent process 
		 */
		for (sig = 0; sig < (_NSIG - 1); sig++)
			signal(sig, SIG_DFL);

		/*
		 * Clean up 
		 */
		ioctl(0, TIOCNOTTY, 0);
		close(STDIN_FILENO);
		close(STDOUT_FILENO);
		close(STDERR_FILENO);
		setsid();

		/*
		 * We want to check the board if exist UART? , add by honor
		 * 2003-12-04 
		 */
		if ((fd = open("/dev/console", O_RDWR)) < 0) {
			(void)open("/dev/null", O_RDONLY);
			(void)open("/dev/null", O_WRONLY);
			(void)open("/dev/null", O_WRONLY);
		} else {
			close(fd);
			(void)open("/dev/console", O_RDONLY);
			(void)open("/dev/console", O_WRONLY);
			(void)open("/dev/console", O_WRONLY);
		}

		/*
		 * Redirect stdout to <path> 
		 */
		if (path) {
			flags = O_WRONLY | O_CREAT;
			if (!strncmp(path, ">>", 2)) {
				/*
				 * append to <path> 
				 */
				flags |= O_APPEND;
				path += 2;
			} else if (!strncmp(path, ">", 1)) {
				/*
				 * overwrite <path> 
				 */
				flags |= O_TRUNC;
				path += 1;
			}
			if ((fd = open(path, flags, 0644)) < 0)
				perror(path);
			else {
				dup2(fd, STDOUT_FILENO);
				close(fd);
			}
		}

		/*
		 * execute command 
		 */
		// for (i = 0; argv[i]; i++)
		// snprintf (buf + strlen (buf), sizeof (buf), "%s ", argv[i]);
		// cprintf("cmd=[%s]\n", buf);
		setenv("PATH", "/sbin:/bin:/usr/sbin:/usr/bin", 1);
		alarm(timeout);
		execvp(argv[0], argv);
		perror(argv[0]);
		exit(errno);
	default:		/* parent */
		if (ppid) {
			*ppid = pid;
			return 0;
		} else {
			waitpid(pid, &status, 0);
			if (WIFEXITED(status))
				return WEXITSTATUS(status);
			else
				return status;
		}
	}
}
Ejemplo n.º 2
0
Archivo: a.c Proyecto: 1024er/popush
int main(int argc, char **argv)
{
    pid_t npid, cpid;
    int s, ns, cs, fc, cc, scn, scr, i;
    if(argc < 3){
        return 1;
    }
    _max = atoi(argv[1]);
    if(_max < 0){
        return 1;
    }
    setsid();
    for(i = 0; i < sizeof(_sig) / sizeof(int); ++i){
        signal(_sig[i], handler);
    }
    //limit(RLIMIT_NPROC, 64);
    if(_max == 0){
        limit(RLIMIT_AS, 32 * 1024 * 1024);
    }
    limit(RLIMIT_CPU, 1);
    _pid = fork();
    if(_pid < 0){
        return 1;
    }
    if(_pid == 0){
        if(_max <= 1){
            ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        }
        execv(argv[2], argv + 2);
    }
    cc = 1;
    fc = 0;
    while(cc > 0){
        cpid = wait3(&cs, 0, NULL);
        if(WIFEXITED(cs)){
            --cc;
            if(cpid == _pid){
                s = cs;
            }
            continue;
        }
        if(WIFSIGNALED(cs)){
            kill(0, WTERMSIG(cs));
        }
        if(_max <= 1){
            scn = ptrace(PTRACE_PEEKUSER, cpid, SCN, NULL);
            if(_bad[scn] == FORK){
                scr = ptrace(PTRACE_PEEKUSER, cpid, SCR, NULL);
                if(scr > 0){
                    ++cc;
                    if(!_max){
                        ptrace(PTRACE_ATTACH, scr, NULL, NULL);
                    }
                    ptrace(PTRACE_SYSCALL, cpid, NULL, NULL);
                }else if(fc < _max){
                    ++fc;
                    ptrace(PTRACE_SYSCALL, cpid, NULL, NULL);   
                }else{
                    kill(0, SIGKILL);
                }
            }else if(_bad[scn]){
                kill(0, SIGKILL);
            }else{
                ptrace(PTRACE_SYSCALL, cpid, NULL, NULL);
            }        
        }
    }
    return WEXITSTATUS(s);
}
Ejemplo n.º 3
0
/**
 * \param[in] rUser user name
 * \return true = success, false = failure
 * 
 * \attention This function is very complex and may contain
 *            various bugs including security ones. Please keep
 *            it in mind..
 */
bool edit_table(const std::string& rUser)
{
  std::string tp(IncronTab::GetUserTablePath(rUser));
  
  struct passwd* ppwd = getpwnam(rUser.c_str());
  if (ppwd == NULL) {
    fprintf(stderr, "cannot find user '%s': %s\n", rUser.c_str(), strerror(errno));
    return false;
  }
  
  uid_t uid = ppwd->pw_uid;
  uid_t gid = ppwd->pw_gid;
  
  char s[NAME_MAX];
  strcpy(s, "/tmp/incron.table-XXXXXX");
  
  uid_t iu = geteuid();
  uid_t ig = getegid();

  if (setegid(gid) != 0 || seteuid(uid) != 0) {
    fprintf(stderr, "cannot change effective UID/GID for user '%s': %s\n", rUser.c_str(), strerror(errno));
    return false;
  }
  
  int fd = mkstemp(s);
  if (fd == -1) {
    fprintf(stderr, "cannot create temporary file: %s\n", strerror(errno));
    return false;
  }
  
  bool ok = false;
  FILE* out = NULL;
  FILE* in = NULL;
  time_t mt = (time_t) 0;
  const char* e = NULL;
  std::string ed;
  
  if (setegid(ig) != 0 || seteuid(iu) != 0) {
    fprintf(stderr, "cannot change effective UID/GID: %s\n", strerror(errno));
    close(fd);
    goto end;
  }
    
  out = fdopen(fd, "w");
  if (out == NULL) {
    fprintf(stderr, "cannot write to temporary file: %s\n", strerror(errno));
    close(fd);
    goto end;
  }
  
  in = fopen(tp.c_str(), "r");
  if (in == NULL) {
    if (errno == ENOENT) {
      in = fopen("/dev/null", "r");
      if (in == NULL) {
        fprintf(stderr, "cannot get empty table for '%s': %s\n", rUser.c_str(), strerror(errno));
        fclose(out);
        goto end;
      }
    }
    else {
      fprintf(stderr, "cannot read old table for '%s': %s\n", rUser.c_str(), strerror(errno));
      fclose(out);
      goto end;
    }
  }
  
  char buf[1024];
  while (fgets(buf, 1024, in) != NULL) {
    fputs(buf, out);
  }
  fclose(in);
  fclose(out);
  
  struct stat st;
  if (stat(s, &st) != 0) {
    fprintf(stderr, "cannot stat temporary file: %s\n", strerror(errno));
    goto end;
  }
  
  mt = st.st_mtime; // save modification time for detecting its change
  
  // Editor selecting algorithm:
  // 1. Check EDITOR environment variable
  // 2. Check VISUAL environment variable
  // 3. Try to get from configuration
  // 4. Check presence of /etc/alternatives/editor
  // 5. Use hard-wired editor
  
  e = getenv("EDITOR");
  if (e == NULL) {
    e = getenv("VISUAL");
    if (e == NULL) {
      
      if (!IncronCfg::GetValue("editor", ed))
        throw InotifyException("configuration is corrupted", EINVAL);
      
      if (!ed.empty()) {
        e = ed.c_str();
      }
      else {
        if (access(INCRON_ALT_EDITOR, X_OK) == 0)
          e = INCRON_ALT_EDITOR;
        else
          e = INCRON_DEFAULT_EDITOR;
      }
    }
  }
  
  // this block is explicite due to gotos' usage simplification
  {
    pid_t pid = fork();
    if (pid == 0) {
      if (setgid(gid) != 0 || setuid(uid) != 0) {
        fprintf(stderr, "cannot set user '%s': %s\n", rUser.c_str(), strerror(errno));
        goto end;
      }    
      
      execlp(e, e, s, NULL);
      _exit(1);
    }
    else if (pid > 0) {
      int status;
      if (wait(&status) != pid) {
        perror("error while waiting for editor");
        goto end;
      }
      if (!(WIFEXITED(status)) || WEXITSTATUS(status) != 0) {
        perror("editor finished with error");
        goto end;
      }
    }
    else {
      perror("cannot start editor");
      goto end;
    }
  }
  
  if (stat(s, &st) != 0) {
    fprintf(stderr, "cannot stat temporary file: %s\n", strerror(errno));
    goto end;
  }
  
  if (st.st_mtime == mt) {
    fprintf(stderr, "table unchanged\n");
    ok = true;
    goto end;
  }
  
  {
    IncronTab ict;
    if (ict.Load(s) && ict.Save(tp)) {
      if (chmod(tp.c_str(), S_IRUSR | S_IWUSR) != 0) {
        fprintf(stderr, "cannot change mode of temporary file: %s\n", strerror(errno));
      }
    }
    else {
      fprintf(stderr, "cannot move temporary table: %s\n", strerror(errno));
      goto end;
    }
    
  }
  
  ok = true;
  fprintf(stderr, "table updated\n");
  
end:  
  
  unlink(s);
  return ok;
}
Ejemplo n.º 4
0
static SolverImpl::SolverRunStatus
runAndGetCexForked(::VC vc, STPBuilder *builder, ::VCExpr q,
                   const std::vector<const Array *> &objects,
                   std::vector<std::vector<unsigned char> > &values,
                   bool &hasSolution, double timeout) {
    unsigned char *pos = shared_memory_ptr;
    unsigned sum = 0;
    for (std::vector<const Array *>::const_iterator it = objects.begin(),
            ie = objects.end();
            it != ie; ++it)
        sum += (*it)->size;
    if (sum >= shared_memory_size)
        llvm::report_fatal_error("not enough shared memory for counterexample");

    fflush(stdout);
    fflush(stderr);
    int pid = fork();
    if (pid == -1) {
        klee_warning("fork failed (for STP)");
        if (!IgnoreSolverFailures)
            exit(1);
        return SolverImpl::SOLVER_RUN_STATUS_FORK_FAILED;
    }

    if (pid == 0) {
        if (timeout) {
            ::alarm(0); /* Turn off alarm so we can safely set signal handler */
            ::signal(SIGALRM, stpTimeoutHandler);
            ::alarm(std::max(1, (int)timeout));
        }
        unsigned res = vc_query(vc, q);
        if (!res) {
            for (std::vector<const Array *>::const_iterator it = objects.begin(),
                    ie = objects.end();
                    it != ie; ++it) {
                const Array *array = *it;
                for (unsigned offset = 0; offset < array->size; offset++) {
                    ExprHandle counter =
                        vc_getCounterExample(vc, builder->getInitialRead(array, offset));
                    *pos++ = getBVUnsigned(counter);
                }
            }
        }
        _exit(res);
    } else {
        int status;
        pid_t res;

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

        if (res < 0) {
            klee_warning("waitpid() for STP failed");
            if (!IgnoreSolverFailures)
                exit(1);
            return SolverImpl::SOLVER_RUN_STATUS_WAITPID_FAILED;
        }

        // From timed_run.py: It appears that linux at least will on
        // "occasion" return a status when the process was terminated by a
        // signal, so test signal first.
        if (WIFSIGNALED(status) || !WIFEXITED(status)) {
            klee_warning("STP did not return successfully.  Most likely you forgot "
                         "to run 'ulimit -s unlimited'");
            if (!IgnoreSolverFailures) {
                exit(1);
            }
            return SolverImpl::SOLVER_RUN_STATUS_INTERRUPTED;
        }

        int exitcode = WEXITSTATUS(status);
        if (exitcode == 0) {
            hasSolution = true;
        } else if (exitcode == 1) {
            hasSolution = false;
        } else if (exitcode == 52) {
            klee_warning("STP timed out");
            // mark that a timeout occurred
            return SolverImpl::SOLVER_RUN_STATUS_TIMEOUT;
        } else {
            klee_warning("STP did not return a recognized code");
            if (!IgnoreSolverFailures)
                exit(1);
            return SolverImpl::SOLVER_RUN_STATUS_UNEXPECTED_EXIT_CODE;
        }

        if (hasSolution) {
            values = std::vector<std::vector<unsigned char> >(objects.size());
            unsigned i = 0;
            for (std::vector<const Array *>::const_iterator it = objects.begin(),
                    ie = objects.end();
                    it != ie; ++it) {
                const Array *array = *it;
                std::vector<unsigned char> &data = values[i++];
                data.insert(data.begin(), pos, pos + array->size);
                pos += array->size;
            }
        }

        if (true == hasSolution) {
            return SolverImpl::SOLVER_RUN_STATUS_SUCCESS_SOLVABLE;
        } else {
            return SolverImpl::SOLVER_RUN_STATUS_SUCCESS_UNSOLVABLE;
        }
    }
}
Ejemplo n.º 5
0
int main()
{
    sigset_t sigset;
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGCHLD);
    if (sigprocmask(SIG_BLOCK, &sigset, NULL) < 0) {
        fprintf(stderr, "Unable to mask SIGCHLD");
        return 1;
    }
    signal(SIGCHLD, sig_hand);
    
    int fd[2];
    if (pipe(fd) == -1){
        fprintf(stderr, "Unable to open pipe ");
        return 1;
    }
    pid_t child = fork();
    if (child) 
    {
        // Parent proc
        close(fd[1]);          // Close unused write end 

        struct timespec timeout;
        timeout.tv_sec = 120;
        timeout.tv_nsec = 0;
        char buf[2];
        
        read(fd[0], &buf, 1); // wait until child activate timer 
        close(fd[0]);
        
        // This process waits enough for the child process to complete
        if (sigtimedwait(&sigset, NULL, &timeout) < 0) 
        {
            if (errno == EAGAIN) 
            {
                fprintf(stderr, "Timeout, killing child\n");
                kill (child, SIGKILL);
                return 1;
            }
            else 
            {
                fprintf(stderr, "Error in sigtimedwait");
                return 1;
            }
        }
        int status;
        
        // In case child process is still running the test fails (assuming deadlock occurred)
        if (waitpid(child, &status, 0) < 0) {
            fprintf(stderr, "Error on waitpid");
            return 1;
        }
        if(WIFEXITED(status) && WEXITSTATUS(status)==0)
        {
            fprintf(stderr, "Parent - terminate OK\n");
            return 0;
        }
        return 1;
    }
    else
    {
        // inside child
        close(fd[0]);          // Close unused read end 
        struct sigaction sigact;
        struct itimerval itval;
        pthread_t tid;

        sigact.sa_handler = Handle;
        sigact.sa_flags = 0;
        sigemptyset(&sigact.sa_mask);

        if (sigaction(SIGVTALRM, &sigact, 0) == -1)
        {
            fprintf(stderr, "Child - Unable to set up handler\n");
            return 1;
        }

        // Create a new thread that calls a system call in a loop
        if (pthread_create(&tid, 0, DoSysCallTillSignalsDone, 0) != 0)
        {
            fprintf(stderr, "Child - Unable to create thread\n");
            return 1;
        }

        // Set timer to create an async signals
        itval.it_interval.tv_sec = 0;
        itval.it_interval.tv_usec = USLEEP_TIME;
        itval.it_value.tv_sec = 0;
        itval.it_value.tv_usec = USLEEP_TIME;
        if (setitimer(ITIMER_VIRTUAL, &itval, 0) == -1)
        {
            fprintf(stderr, "Child - Unable to set up timer\n");
            return 1;
        }
        
        close(fd[1]); // send EOF to signal parent that timer is on
        
        /*
        * Call an analysis function in a loop .
        */
        while (SigCount < COUNT)
        {
            volatile PF doToolAnalysis = DoToolAnalysis;
            doToolAnalysis();
        }

        itval.it_value.tv_sec = 0;
        itval.it_value.tv_usec = 0;
        if (setitimer(ITIMER_VIRTUAL, &itval, 0) == -1)
        {
            fprintf(stderr, "Child - Unable to disable timer\n");
            return 1;
        }

        pthread_join(tid, 0);
        fprintf(stderr, "Child - terminate OK\n");
        return 0;
    }
}
Ejemplo n.º 6
0
int jl_process_exited(int status)      { return WIFEXITED(status); }
Ejemplo n.º 7
0
ErrorCode Process::wait() {
  int status, signal;
  ProcessInfo info;
  ThreadId tid;

  // We have at least one thread when we start waiting on a process.
  DS2ASSERT(!_threads.empty());

  while (!_threads.empty()) {
    tid = blocking_waitpid(-1, &status, __WALL);
    DS2LOG(Debug, "wait tid=%d status=%#x", tid, status);

    if (tid <= 0)
      return kErrorProcessNotFound;

    auto threadIt = _threads.find(tid);

    if (threadIt == _threads.end()) {
      // If we don't know about this thread yet, but it has a WIFEXITED() or a
      // WIFSIGNALED() status (i.e.: it terminated), it means we already
      // cleaned up the thread object (e.g.: in Process::suspend), but we
      // hadn't waitpid()'d it yet. Avoid re-creating a Thread object here.
      if (WIFEXITED(status) || WIFSIGNALED(status)) {
        goto continue_waiting;
      }

      // A new thread has appeared that we didn't know about. Create the
      // Thread object and return.
      DS2LOG(Debug, "creating new thread tid=%d", tid);
      _currentThread = new Thread(this, tid);
      return kSuccess;
    } else {
      _currentThread = threadIt->second;
    }

    _currentThread->updateStopInfo(status);

    switch (_currentThread->_stopInfo.event) {
    case StopInfo::kEventNone:
      _currentThread->resume();
      goto continue_waiting;

    case StopInfo::kEventExit:
    case StopInfo::kEventKill:
      DS2LOG(Debug, "thread %d is exiting", tid);

      //
      // Killing the main thread?
      //
      // Note(sas): This might be buggy; the main thread exiting
      // doesn't mean that the process is dying.
      //
      if (tid == _pid && _threads.size() == 1) {
        DS2LOG(Debug, "last thread is exiting");
        break;
      }

      //
      // Remove and release the thread associated with this pid.
      //
      removeThread(tid);
      goto continue_waiting;

    case StopInfo::kEventStop:
      signal = _currentThread->_stopInfo.signal;

      DS2LOG(Debug, "stopped tid=%d status=%#x signal=%s", tid, status,
             Stringify::Signal(signal));

      if (_passthruSignals.find(signal) != _passthruSignals.end()) {
        _currentThread->resume(signal);
        goto continue_waiting;
      } else {
        //
        // This is a signal that we want to transmit back to the
        // debugger.
        //
        break;
      }
    }

    break;

  continue_waiting:
    _currentThread = nullptr;
    continue;
  }

  if (!(WIFEXITED(status) || WIFSIGNALED(status)) || tid != _pid) {
    //
    // Suspend the process, this must be done after updating
    // the thread trap info.
    //
    suspend();
  }

  if ((WIFEXITED(status) || WIFSIGNALED(status)) && tid == _pid) {
    _terminated = true;
  }

  return kSuccess;
}
Ejemplo n.º 8
0
gboolean
g_spawn_command_line_sync (const gchar *command_line,
				gchar **standard_output,
				gchar **standard_error,
				gint *exit_status,
				GError **error)
{
#ifdef G_OS_WIN32
#else
	pid_t pid;
	gchar **argv;
	gint argc;
	int stdout_pipe [2] = { -1, -1 };
	int stderr_pipe [2] = { -1, -1 };
	int status;
	int res;
	
	if (!g_shell_parse_argv (command_line, &argc, &argv, error))
		return FALSE;

	if (standard_output && !create_pipe (stdout_pipe, error))
		return FALSE;

	if (standard_error && !create_pipe (stderr_pipe, error)) {
		if (standard_output) {
			CLOSE_PIPE (stdout_pipe);
		}
		return FALSE;
	}

	pid = fork ();
	if (pid == 0) {
		gint i;

		if (standard_output) {
			close (stdout_pipe [0]);
			dup2 (stdout_pipe [1], STDOUT_FILENO);
		}

		if (standard_error) {
			close (stderr_pipe [0]);
			dup2 (stderr_pipe [1], STDERR_FILENO);
		}
		for (i = g_getdtablesize () - 1; i >= 3; i--)
			close (i);

		/* G_SPAWN_SEARCH_PATH is always enabled for g_spawn_command_line_sync */
		if (!g_path_is_absolute (argv [0])) {
			gchar *arg0;

			arg0 = g_find_program_in_path (argv [0]);
			if (arg0 == NULL) {
				exit (1);
			}
			//g_free (argv [0]);
			argv [0] = arg0;
		}
		execv (argv [0], argv);
		exit (1); /* TODO: What now? */
	}

	g_strfreev (argv);
	if (standard_output)
		close (stdout_pipe [1]);

	if (standard_error)
		close (stderr_pipe [1]);

	if (standard_output || standard_error) {
		res = read_pipes (stdout_pipe [0], standard_output, stderr_pipe [0], standard_error, error);
		if (res) {
			waitpid (pid, &status, WNOHANG); /* avoid zombie */
			return FALSE;
		}
	}

	NO_INTR (res, waitpid (pid, &status, 0));

	/* TODO: What if error? */
	if (WIFEXITED (status) && exit_status) {
		*exit_status = WEXITSTATUS (status);
	}
#endif
	return TRUE;
}
Ejemplo n.º 9
0
static void do_master_child(void)
{
	int lc;
	int pid;
	int status;

	if (SETUID(NULL, ltpuser->pw_uid) == -1) {
		tst_brkm(TBROK, NULL,
			 "setuid failed to set the effective uid to %d",
			 ltpuser->pw_uid);
	}

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		int tst_fd;

		tst_count = 0;

		TEST(tst_fd = open(testfile, O_RDWR));

		if (TEST_RETURN != -1) {
			tst_resm(TFAIL, "call succeeded unexpectedly");
			close(tst_fd);
		}

		if (TEST_ERRNO == EACCES) {
			tst_resm(TPASS, "open returned errno EACCES");
		} else {
			tst_resm(TFAIL, "open returned unexpected errno - %d",
				 TEST_ERRNO);
			continue;
		}

		pid = FORK_OR_VFORK();
		if (pid < 0)
			tst_brkm(TBROK, NULL, "Fork failed");

		if (pid == 0) {
			int tst_fd2;

			/* Test to open the file in son process */
			TEST(tst_fd2 = open(testfile, O_RDWR));

			if (TEST_RETURN != -1) {
				tst_resm(TFAIL, "call succeeded unexpectedly");
				close(tst_fd2);
			}

			TEST_ERROR_LOG(TEST_ERRNO);

			if (TEST_ERRNO == EACCES) {
				tst_resm(TPASS, "open returned errno EACCES");
			} else {
				tst_resm(TFAIL,
					 "open returned unexpected errno - %d",
					 TEST_ERRNO);
			}
			tst_exit();
		} else {
			/* Wait for son completion */
			waitpid(pid, &status, 0);
			if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
				exit(WEXITSTATUS(status));
		}
	}
	tst_exit();
}
Ejemplo n.º 10
0
static void
mgt_reap_child(void)
{
	int i;
	int status = 0xffff;
	struct vsb *vsb;
	pid_t r = 0;

	assert(child_pid != -1);

	/*
	 * Close the CLI connections
	 * This signals orderly shut down to child
	 */
	mgt_cli_stop_child();
	if (child_cli_out >= 0)
		closex(&child_cli_out);
	if (child_cli_in >= 0)
		closex(&child_cli_in);

	/* Stop the poker */
	if (ev_poker != NULL) {
		vev_del(mgt_evb, ev_poker);
		free(ev_poker);
	}
	ev_poker = NULL;

	/* Stop the listener */
	if (ev_listen != NULL) {
		vev_del(mgt_evb, ev_listen);
		free(ev_listen);
		ev_listen = NULL;
	}

	/* Compose obituary */
	vsb = VSB_new_auto();
	XXXAN(vsb);

	/* Wait for child to die */
	for (i = 0; i < mgt_param.cli_timeout; i++) {
		r = waitpid(child_pid, &status, WNOHANG);
		if (r == child_pid)
			break;
		(void)sleep(1);
	}
	if (r == 0) {
		VSB_printf(vsb, "Child (%jd) not dying, killing", (intmax_t)r);

		/* Kick it Jim... */
		if (MGT_FEATURE(FEATURE_NO_COREDUMP))
			(void)kill(child_pid, SIGKILL);
		else
			(void)kill(child_pid, SIGQUIT);
		r = waitpid(child_pid, &status, 0);
	}
	if (r != child_pid)
		fprintf(stderr, "WAIT 0x%jx\n", (uintmax_t)r);
	assert(r == child_pid);

	MAC_reopen_sockets(NULL);

	VSB_printf(vsb, "Child (%jd) %s", (intmax_t)r,
	    status ? "died" : "ended");
	if (WIFEXITED(status) && WEXITSTATUS(status)) {
		VSB_printf(vsb, " status=%d", WEXITSTATUS(status));
		exit_status |= 0x20;
		if (WEXITSTATUS(status) == 1)
			VSC_C_mgt->child_exit = ++static_VSC_C_mgt.child_exit;
		else
			VSC_C_mgt->child_stop = ++static_VSC_C_mgt.child_stop;
	}
	if (WIFSIGNALED(status)) {
		VSB_printf(vsb, " signal=%d", WTERMSIG(status));
		exit_status |= 0x40;
		VSC_C_mgt->child_died = ++static_VSC_C_mgt.child_died;
	}
#ifdef WCOREDUMP
	if (WCOREDUMP(status)) {
		VSB_printf(vsb, " (core dumped)");
		exit_status |= 0x80;
		VSC_C_mgt->child_dump = ++static_VSC_C_mgt.child_dump;
	}
#endif
	AZ(VSB_finish(vsb));
	MGT_complain(status ? C_ERR : C_INFO, "%s", VSB_data(vsb));
	VSB_delete(vsb);

	/* Dispose of shared memory but evacuate panic messages first */
	if (heritage.panic_str[0] != '\0') {
		mgt_panic_record(r);
		mgt_SHM_Destroy(1);
		VSC_C_mgt->child_panic = ++static_VSC_C_mgt.child_panic;
	} else {
		mgt_SHM_Destroy(MGT_DO_DEBUG(DBG_VSM_KEEP));
	}
	mgt_SHM_Create();
	mgt_SHM_Commit();

	if (child_state == CH_RUNNING)
		child_state = CH_DIED;

	/* Pick up any stuff lingering on stdout/stderr */
	(void)child_listener(NULL, EV_RD);
	closex(&child_output);
	VLU_Destroy(child_std_vlu);

	child_pid = -1;

	MGT_complain(C_DEBUG, "Child cleanup complete");

	if (child_state == CH_DIED && mgt_param.auto_restart)
		mgt_launch_child(NULL);
	else if (child_state == CH_DIED)
		child_state = CH_STOPPED;
	else if (child_state == CH_STOPPING)
		child_state = CH_STOPPED;
}
Ejemplo n.º 11
0
/* Handle breakpoints - we expect to see breakpoints in the dynamic linker
 * (which we set ourselves) as well as profiler marks (embedded in the
 * profiled application's code).
 */
static int ProcessBreakpoint( pid_t pid, u_long ip )
{
    static int  ld_state = RT_CONSISTENT;   // This ought to be per-pid
    int         ptrace_sig = 0;

#if defined( MD_x86 )
    user_regs_struct    regs;

    // on x86, when breakpoint was hit the EIP points to the next
    // instruction, so we must be careful
    ptrace( PTRACE_GETREGS, pid, NULL, &regs );

    if( ip == Rdebug.r_brk + sizeof( opcode_type ) ) {
#elif defined( MD_ppc )
    if( ip == Rdebug.r_brk ) {
#endif
        opcode_type         brk_opcode = BRKPOINT;
        int                 status;
        int                 ret;

        /* The dynamic linker breakpoint was hit, meaning that
         * libraries are being loaded or unloaded. This gets a bit
         * tricky because we must restore the original code that was
         * at the breakpoint and execute it, but we still want to
         * keep the breakpoint.
         */
        if( WriteMem( pid, &saved_opcode, Rdebug.r_brk, sizeof( saved_opcode ) ) != sizeof( saved_opcode ) )
            printf( "WriteMem() #1 failed\n" );
        ReadMem( pid, &Rdebug, (addr_off)DbgRdebug, sizeof( Rdebug ) );
        dbg_printf( "ld breakpoint hit, state is " );
        switch( Rdebug.r_state ) {
        case RT_ADD:
            dbg_printf( "RT_ADD\n" );
            AddLibrary( pid, Rdebug.r_map );
            ld_state = RT_ADD;
            break;
        case RT_DELETE:
            dbg_printf( "RT_DELETE\n" );
            ld_state = RT_DELETE;
            break;
        case RT_CONSISTENT:
            dbg_printf( "RT_CONSISTENT\n" );
            if( ld_state == RT_DELETE )
                RemoveLibrary( pid, Rdebug.r_map );
            ld_state = RT_CONSISTENT;
            break;
        default:
            dbg_printf( "error!\n" );
            break;
        }
#if defined( MD_x86 )
        regs.eip--;
        ptrace( PTRACE_SETREGS, pid, NULL, &regs );
#endif
        // unset breakpoint, single step, re-set breakpoint
        if( ptrace( PTRACE_SINGLESTEP, pid, NULL, (void *)ptrace_sig ) < 0 )
            perror( "ptrace()" );
        do {    // have to loop since SIGALRM can interrupt us here
            ret = waitpid( pid, &status, 0 );
        } while( (ret < 0) && (errno == EINTR) );
        if( ret == -1)
            perror( "waitpid()" );
        if( WriteMem( pid, &brk_opcode, Rdebug.r_brk, sizeof( brk_opcode ) ) != sizeof( brk_opcode ) )
            dbg_printf( "WriteMem() #2 failed with errno %d for pid %d, %d bytes (at %p)!\n", errno, pid, sizeof( brk_opcode ), Rdebug.r_brk );
        return( TRUE ); // indicate this was our breakpoint
    } else {
        dbg_printf( "Not an ld breakpoint, assuming mark\n" );
#if defined( MD_x86 )
        if( ProcessMark( pid, &regs ) )
            return( TRUE );
#endif
    }
    return( FALSE );
}


/*
 * Real time signal (SIGALRM) handler. All we really need to do is wake up
 * periodically to interrupt waitpid(), the signal handler need not do much
 * at all.
 */
static void alarm_handler( int signo )
{
    TimerTicked = TRUE;
}


/* Install periodic real time alarm signal */
static void InstSigHandler( int msec_period )
{
    struct sigaction    sigalrm;
    struct itimerval    timer;

    sigalrm.sa_handler = (void *)alarm_handler;
    sigemptyset( &sigalrm.sa_mask );
    sigalrm.sa_flags = 0;

    sigaction( SIGALRM, &sigalrm, NULL );

    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_usec = msec_period * 1000;
    timer.it_value.tv_sec = 0;
    timer.it_value.tv_usec = msec_period * 1000;

    if( setitimer( ITIMER_REAL, &timer, NULL ) ) {
        InternalError( MsgArray[MSG_SAMPLE_6 - ERR_FIRST_MESSAGE] );
    }
}


/*
 * Main sampler loop. We run the profiled application under the control of
 * ptrace(). The sampler installs a SIGALRM handler which ticks at the desired
 * rate. Whenever the SIGALRM interrupts our own waitpid(), we send a SIGSTOP
 * to the profiled app and when the child app notifies us of the SIGSTOP, we
 * remember the current execution point and continue the profiled app. Note
 * that we may miss some ticks but this is not a problem - the ticks don't
 * even need to be regular to provide usable results.
 */
static void SampleLoop( pid_t pid )
{
    static int          ptrace_sig = 0;
    static int          do_cont = TRUE;
    int                 status;
    user_regs_struct    regs;
    bool                sample_continue = TRUE;
    int                 ret;
    opcode_type         brk_opcode = BRKPOINT;

    TimerTicked = FALSE;
    InstSigHandler( SleepTime );

    do {
        if( do_cont && ptrace( PTRACE_CONT, pid, NULL, (void *)ptrace_sig ) == -1)
            perror( "ptrace()" );
        ret = waitpid( pid, &status, 0 );
        if( (ret < 0) && (errno == EINTR) ) {
            /* did we get woken up by SIGALRM? */
            if( TimerTicked ) {
                TimerTicked = FALSE;
                /* interrupt child process - next waitpid() will see this */
                kill( pid, SIGSTOP );
            } else {
                dbg_printf( "who the hell interrupted waitpid()?\n" );
            }
            do_cont = FALSE;
            continue;
        }
        if( ret < 0 )
            perror( "waitpid()" );
        do_cont = TRUE;

        /* record current execution point */
#if defined( MD_x86 )
        ptrace( PTRACE_GETREGS, pid, NULL, &regs );
#elif defined( MD_ppc )
        regs.eip = ptrace( PTRACE_PEEKUSER, pid, REGSIZE * PT_NIP, NULL );
#endif
        if( WIFSTOPPED( status ) ) {
            /* If debuggee has dynamic section, try getting the r_debug struct
             * every time the child process stops. The r_debug data may not be
             * available immediately after the child process first loads.
             */
            if( !HaveRdebug && (DbgDyn != NULL) ) {
                if( Get_ld_info( pid, DbgDyn, &Rdebug, &DbgRdebug ) ) {

                    AddLibrary( pid, Rdebug.r_map );
                    HaveRdebug = TRUE;

                    /* Set a breakpoint in dynamic linker. That way we can be
                     * informed on dynamic library load/unload events.
                     */
                    ReadMem( pid, &saved_opcode, Rdebug.r_brk, sizeof( saved_opcode ) );
                    dbg_printf( "setting ld breakpoint at %p, old opcode was %X\n", Rdebug.r_brk, saved_opcode );
                    WriteMem( pid, &brk_opcode, Rdebug.r_brk, sizeof( brk_opcode ) );
                }
            }

            sample_continue = FALSE;
            switch( (ptrace_sig = WSTOPSIG( status )) ) {
            case SIGSEGV:
                dbg_printf( "SIGSEGV at %p\n", regs.eip );
                sample_continue = TRUE;
                break;
            case SIGILL:
                dbg_printf( "SIGILL at %p\n", regs.eip );
                sample_continue = TRUE;
                break;
            case SIGABRT:
                dbg_printf( "SIGABRT at %p\n", regs.eip );
                sample_continue = TRUE;
                break;
            case SIGINT:
                dbg_printf( "SIGINT at %p\n", regs.eip );
                sample_continue = TRUE;
                break;
            case SIGTRAP:
                dbg_printf( "SIGTRAP at %p\n", regs.eip );
                if( ProcessBreakpoint( pid, regs.eip ) ) {
                    // don't pass on SIGTRAP if we expected this breakpoint
                    ptrace_sig = 0;
                }
                sample_continue = TRUE;
                break;
            case SIGSTOP:
                /* presumably we were behind this SIGSTOP */
                RecordSample( regs.eip, 1 );
                ptrace_sig = 0;
                sample_continue = TRUE;
                break;
            default:
                /* all other signals get passed down to the child and we let
                 * the child handle them (or not handle and die)
                 */
                sample_continue = TRUE;
                break;
            }
        } else if( WIFEXITED( status ) ) {
            dbg_printf( "WIFEXITED pid %d\n", pid );
            report();
            sample_continue = FALSE;
        } else if( WIFSIGNALED( status ) ) {
            dbg_printf( "WIFSIGNALED pid %d\n", pid );
            report();
            sample_continue = FALSE;
        }
    } while( sample_continue );
}


static int GetExeNameFromPid( pid_t pid, char *buffer, int max_len )
{
    char        procfile[24];
    int         len;

    sprintf( procfile, "/proc/%d/exe", pid );
    len = readlink( procfile, buffer, max_len );
    if( len < 0 )
        len = 0;
    buffer[len] = '\0';
    return( len );
}
Ejemplo n.º 12
0
void
seed_rng(void)
{
#ifndef OPENSSL_PRNG_ONLY
	int devnull;
	int p[2];
	pid_t pid;
	int ret;
	unsigned char buf[RANDOM_SEED_SIZE];
	mysig_t old_sigchld;

	if (RAND_status() == 1) {
		debug3("RNG is ready, skipping seeding");
		return;
	}

	debug3("Seeding PRNG from %s", SSH_RAND_HELPER);

	if ((devnull = open("/dev/null", O_RDWR)) == -1)
		fatal("Couldn't open /dev/null: %s", strerror(errno));
	if (pipe(p) == -1)
		fatal("pipe: %s", strerror(errno));

	old_sigchld = signal(SIGCHLD, SIG_DFL);
	if ((pid = fork()) == -1)
		fatal("Couldn't fork: %s", strerror(errno));
	if (pid == 0) {
		dup2(devnull, STDIN_FILENO);
		dup2(p[1], STDOUT_FILENO);
		/* Keep stderr open for errors */
		close(p[0]);
		close(p[1]);
		close(devnull);

		if (original_uid != original_euid &&
		    ( seteuid(getuid()) == -1 ||
		      setuid(original_uid) == -1) ) {
			fprintf(stderr, "(rand child) setuid(%li): %s\n",
			    (long int)original_uid, strerror(errno));
			_exit(1);
		}

		execl(SSH_RAND_HELPER, "ssh-rand-helper", NULL);
		fprintf(stderr, "(rand child) Couldn't exec '%s': %s\n",
		    SSH_RAND_HELPER, strerror(errno));
		_exit(1);
	}

	close(devnull);
	close(p[1]);

	memset(buf, '\0', sizeof(buf));
	ret = atomicio(read, p[0], buf, sizeof(buf));
	if (ret == -1)
		fatal("Couldn't read from ssh-rand-helper: %s",
		    strerror(errno));
	if (ret != sizeof(buf))
		fatal("ssh-rand-helper child produced insufficient data");

	close(p[0]);

	if (waitpid(pid, &ret, 0) == -1)
		fatal("Couldn't wait for ssh-rand-helper completion: %s",
		    strerror(errno));
	signal(SIGCHLD, old_sigchld);

	/* We don't mind if the child exits upon a SIGPIPE */
	if (!WIFEXITED(ret) &&
	    (!WIFSIGNALED(ret) || WTERMSIG(ret) != SIGPIPE))
		fatal("ssh-rand-helper terminated abnormally");
	if (WEXITSTATUS(ret) != 0)
		fatal("ssh-rand-helper exit with exit status %d", ret);

	RAND_add(buf, sizeof(buf), sizeof(buf));
	memset(buf, '\0', sizeof(buf));

#endif /* OPENSSL_PRNG_ONLY */
	if (RAND_status() != 1)
		fatal("PRNG is not seeded");
}
Ejemplo n.º 13
0
int main(int argc, char* argv[]){

    long i;
    long iterations = DEFAULT_ITERATIONS;
    struct sched_param param;
    int policy, num_processes, status;
    double x, y;
    double inCircle = 0.0;
    double inSquare = 0.0;
    double pCircle = 0.0;
    double piCalc = 0.0;
    pid_t pid, wpid;
    int j = 0;

    /* Set default policy if not supplied */
    if(argc < 2){
        policy = SCHED_OTHER;
    }

    /* Set default number of processes */
    if(argc < 3){
        num_processes = LOW;
    }
    /* Set policy if supplied */
    if(argc > 1){
	if(!strcmp(argv[1], "SCHED_OTHER")){
	    policy = SCHED_OTHER;
	}
	else if(!strcmp(argv[1], "SCHED_FIFO")){
	    policy = SCHED_FIFO;
	}
	else if(!strcmp(argv[1], "SCHED_RR")){
	    policy = SCHED_RR;
	}
	else {
	    fprintf(stderr, "Unhandeled scheduling policy\n");
	    exit(EXIT_FAILURE);
	}
    }

    /* Set # Of Processes */
    if(argc > 2){
        if(!strcmp(argv[2], "LOW")){
            num_processes = LOW;
        }
        else if(!strcmp(argv[2], "MEDIUM")){
            num_processes = MEDIUM;
        }
        else if(!strcmp(argv[2], "HIGH")){
            num_processes = HIGH;
        }
        else{
            fprintf(stderr, "Unhandeled number of processes\n");
            exit(EXIT_FAILURE);
        }
    }
    
    /* Set process to max prioty for given scheduler */
    param.sched_priority = sched_get_priority_max(policy);
    
    /* Set new scheduler policy */
    fprintf(stdout, "Current Scheduling Policy: %d\n", sched_getscheduler(0));
    fprintf(stdout, "Setting Scheduling Policy to: %d\n", policy);
    if(sched_setscheduler(0, policy, &param)){
		perror("Error setting scheduler policy");
		exit(EXIT_FAILURE);
    }
    fprintf(stdout, "New Scheduling Policy: %d\n", sched_getscheduler(0));

    /* Fork number of processes specified */
    printf("Number of processes to be forked %d \n", num_processes);
    for(i = 0; i < num_processes; i++){
        if((pid = fork()) == -1){
            fprintf(stderr, "Error Forking Child Process");
            exit(EXIT_FAILURE); 
        } 
        // only if pid is 0, we are in child
        if(pid == 0){ 
            for(i=0; i<iterations; i++){
				x = (random() % (RADIUS * 2)) - RADIUS;
				y = (random() % (RADIUS * 2)) - RADIUS;
            if(zeroDist(x,y) < RADIUS){
                inCircle++;
            }
            inSquare++;
            }

            /* Finish calculation */
            pCircle = inCircle/inSquare;
            piCalc = pCircle * 4.0;

            /* Print result */
            fprintf(stdout, "pi = %f\n", piCalc);

            exit(0);
        }
    }
    // terminate all children until wpid is 0
    while((wpid = wait(&status)) > 0){
        if(WIFEXITED(status)){ 
			printf("Exit status of child process %d was normal \n", wpid);
			j++;
        }
    }
    printf("Total # of Processes terminated was %d\n", j);
    return EXIT_SUCCESS;  
}
Ejemplo n.º 14
0
static bool client_exec_script(struct master_service_connection *conn)
{
	const char *const *args;
	string_t *input;
	void *buf;
	size_t prev_size, scanpos;
	bool header_complete = FALSE;
	ssize_t ret;
	int status;
	pid_t pid;

	net_set_nonblock(conn->fd, FALSE);
	input = buffer_create_dynamic(pool_datastack_create(), IO_BLOCK_SIZE);

	/* Input contains:

	   VERSION .. <lf>
	   [alarm=<secs> <lf>]
	   "noreply" | "-" (or anything really) <lf>

	   arg 1 <lf>
	   arg 2 <lf>
	   ...
	   <lf>
	   DATA

	   This is quite a horrible protocol. If alarm is specified, it MUST be
	   before "noreply". If "noreply" isn't given, something other string
	   (typically "-") must be given which is eaten away.
	*/		
	alarm(SCRIPT_READ_TIMEOUT_SECS);
	scanpos = 1;
	while (!header_complete) {
		const unsigned char *pos, *end;

		prev_size = input->used;
		buf = buffer_append_space_unsafe(input, IO_BLOCK_SIZE);

		/* peek in socket input buffer */
		ret = recv(conn->fd, buf, IO_BLOCK_SIZE, MSG_PEEK);
		if (ret <= 0) {
			buffer_set_used_size(input, prev_size);
			if (strchr(str_c(input), '\n') != NULL)
				script_verify_version(t_strcut(str_c(input), '\n'));

			if (ret < 0)
				i_fatal("recv(MSG_PEEK) failed: %m");

			i_fatal("recv(MSG_PEEK) failed: disconnected");
		}

		/* scan for final \n\n */
		pos = CONST_PTR_OFFSET(input->data, scanpos);
		end = CONST_PTR_OFFSET(input->data, prev_size + ret);
		for (; pos < end; pos++) {
			if (pos[-1] == '\n' && pos[0] == '\n') {
				header_complete = TRUE;
				pos++;
				break;
			}
		}
		scanpos = pos - (const unsigned char *)input->data;

		/* read data for real (up to and including \n\n) */
		ret = recv(conn->fd, buf, scanpos-prev_size, 0);
		if (prev_size+ret != scanpos) {
			if (ret < 0)
				i_fatal("recv() failed: %m");
			if (ret == 0)
				i_fatal("recv() failed: disconnected");
			i_fatal("recv() failed: size of definitive recv() differs from peek");
		}
		buffer_set_used_size(input, scanpos);
	}
	alarm(0);

	/* drop the last two LFs */
	buffer_set_used_size(input, scanpos-2);

	args = t_strsplit(str_c(input), "\n");
	script_verify_version(*args); args++;
	if (*args != NULL) {
		if (strncmp(*args, "alarm=", 6) == 0) {
			unsigned int seconds;
			if (str_to_uint(*args + 6, &seconds) < 0)
				i_fatal("invalid alarm option");
			alarm(seconds);
			args++;
		}
		if (strcmp(*args, "noreply") == 0) {
			/* no need to fork and check exit status */
			exec_child(conn, args + 1);
			i_unreached();
		}
		if (**args == '\0')
			i_fatal("empty options");
		args++;
	}

	if ((pid = fork()) == (pid_t)-1) {
		i_error("fork() failed: %m");
		return FALSE;
	}

	if (pid == 0) {
		/* child */
		exec_child(conn, args);
		i_unreached();
	}

	/* parent */

	/* check script exit status */
	if (waitpid(pid, &status, 0) < 0) {
		i_error("waitpid() failed: %m");
		return FALSE;
	} else if (WIFEXITED(status)) {
		ret = WEXITSTATUS(status);
		if (ret != 0) {
			i_error("Script terminated abnormally, exit status %d", (int)ret);
			return FALSE;
		}
	} else if (WIFSIGNALED(status)) {
		i_error("Script terminated abnormally, signal %d", WTERMSIG(status));
		return FALSE;
	} else if (WIFSTOPPED(status)) {
		i_fatal("Script stopped, signal %d", WSTOPSIG(status));
		return FALSE;
	} else {
		i_fatal("Script terminated abnormally, return status %d", status);
		return FALSE;
	}
	return TRUE;
}
Ejemplo n.º 15
0
bool f_pcntl_wifexited(int status) { return WIFEXITED(status);}
Ejemplo n.º 16
0
/*
 * Scan the specified file system to check quota(s) present on it.
 */
int
chkquota(const char *vfstype, const char *fsname, const char *mntpt,
    void *auxarg, pid_t *pidp)
{
	struct quotaname *qnp = auxarg;
	struct fileusage *fup;
	union dinode *dp;
	int cg, i, mode, errs = 0, status;
	ino_t ino, inosused;
	pid_t pid;
	char *cp;

	switch (pid = fork()) {
	case -1:	/* error */
		warn("fork");
		return 1;
	case 0:		/* child */
		if ((fi = open(fsname, O_RDONLY, 0)) < 0)
			err(1, "%s", fsname);
		sync();
		dev_bsize = 1;
		for (i = 0; sblock_try[i] != -1; i++) {
			bread(sblock_try[i], (char *)&sblock, (long)SBLOCKSIZE);
			if ((sblock.fs_magic == FS_UFS1_MAGIC ||
			     (sblock.fs_magic == FS_UFS2_MAGIC &&
			      sblock.fs_sblockloc == sblock_try[i])) &&
			    sblock.fs_bsize <= MAXBSIZE &&
			    sblock.fs_bsize >= sizeof(struct fs))
				break;
		}
		if (sblock_try[i] == -1) {
			warn("Cannot find file system superblock");
			return (1);
		}
		dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
		maxino = sblock.fs_ncg * sblock.fs_ipg;
		for (cg = 0; cg < sblock.fs_ncg; cg++) {
			ino = cg * sblock.fs_ipg;
			setinodebuf(ino);
			bread(fsbtodb(&sblock, cgtod(&sblock, cg)),
			    (char *)(&cgblk), sblock.fs_cgsize);
			if (sblock.fs_magic == FS_UFS2_MAGIC)
				inosused = cgblk.cg_initediblk;
			else
				inosused = sblock.fs_ipg;
			/*
			 * If we are using soft updates, then we can trust the
			 * cylinder group inode allocation maps to tell us which
			 * inodes are allocated. We will scan the used inode map
			 * to find the inodes that are really in use, and then
			 * read only those inodes in from disk.
			 */
			if (sblock.fs_flags & FS_DOSOFTDEP) {
				if (!cg_chkmagic(&cgblk))
					errx(1, "CG %d: BAD MAGIC NUMBER\n", cg);
				cp = &cg_inosused(&cgblk)[(inosused - 1) / CHAR_BIT];
				for ( ; inosused > 0; inosused -= CHAR_BIT, cp--) {
					if (*cp == 0)
						continue;
					for (i = 1 << (CHAR_BIT - 1); i > 0; i >>= 1) {
						if (*cp & i)
							break;
						inosused--;
					}
					break;
				}
				if (inosused <= 0)
					continue;
			}
			for (i = 0; i < inosused; i++, ino++) {
				if ((dp = getnextinode(ino)) == NULL ||
				    ino < ROOTINO ||
				    (mode = DIP(dp, di_mode) & IFMT) == 0)
					continue;
				if (qnp->flags & HASGRP) {
					fup = addid(DIP(dp, di_gid),
					    GRPQUOTA, NULL);
					fup->fu_curinodes++;
					if (mode == IFREG || mode == IFDIR ||
					    mode == IFLNK)
						fup->fu_curblocks +=
						    DIP(dp, di_blocks);
				}
				if (qnp->flags & HASUSR) {
					fup = addid(DIP(dp, di_uid),
					    USRQUOTA, NULL);
					fup->fu_curinodes++;
					if (mode == IFREG || mode == IFDIR ||
					    mode == IFLNK)
						fup->fu_curblocks +=
						    DIP(dp, di_blocks);
				}
			}
		}
		freeinodebuf();
		if (flags&(CHECK_DEBUG|CHECK_VERBOSE)) {
			(void)printf("*** Checking ");
			if (qnp->flags & HASUSR) {
				(void)printf("%s", qfextension[USRQUOTA]);
				if (qnp->flags & HASGRP)
					(void)printf(" and ");
			}
			if (qnp->flags & HASGRP)
				(void)printf("%s", qfextension[GRPQUOTA]);
			(void)printf(" quotas for %s (%s), %swait\n",
			    fsname, mntpt, pidp? "no" : "");
		}
		if (qnp->flags & HASUSR)
			errs += update(mntpt, qnp->usrqfname, USRQUOTA);
		if (qnp->flags & HASGRP)
			errs += update(mntpt, qnp->grpqfname, GRPQUOTA);
		close(fi);
		exit (errs);
		break;
	default:	/* parent */
		if (pidp != NULL) {
			*pidp = pid;
			return 0;
		}
		if (waitpid(pid, &status, 0) < 0) {
			warn("waitpid");
			return 1;
		}
		if (WIFEXITED(status)) {
			if (WEXITSTATUS(status) != 0)
				return WEXITSTATUS(status);
		} else if (WIFSIGNALED(status)) {
			warnx("%s: %s", fsname, strsignal(WTERMSIG(status)));
			return 1;
		}
		break;
	}
	return (0);
}
Ejemplo n.º 17
0
void
doit ()
{
  int err, i;
  int sockets[2];
  const char *srcdir;
  char *pub_key_path, *priv_key_path;
  pid_t child;

  gnutls_global_init ();

  srcdir = getenv ("srcdir") ? getenv ("srcdir") : ".";

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

      if (i <= 1)
        key_id = NULL;          /* try using the master key */
      else if (i == 2)
        key_id = "auto";        /* test auto */
      else if (i == 3)
        key_id = "f30fd423c143e7ba";

      if (debug)
        {
          gnutls_global_set_log_level (5);
          gnutls_global_set_log_function (log_message);
        }

      err = socketpair (AF_UNIX, SOCK_STREAM, 0, sockets);
      if (err != 0)
        fail ("socketpair %s\n", strerror (errno));

      pub_key_path = alloca (strlen (srcdir) + strlen (pub_key_file) + 2);
      strcpy (pub_key_path, srcdir);
      strcat (pub_key_path, "/");
      strcat (pub_key_path, pub_key_file);

      priv_key_path = alloca (strlen (srcdir) + strlen (priv_key_file) + 2);
      strcpy (priv_key_path, srcdir);
      strcat (priv_key_path, "/");
      strcat (priv_key_path, priv_key_file);

      child = fork ();
      if (child == -1)
        fail ("fork %s\n", strerror (errno));

      if (child == 0)
        {
          /* Child process (client).  */
          gnutls_session_t session;
          gnutls_certificate_credentials_t cred;
          ssize_t sent;

          if (debug)
            printf ("client process %i\n", getpid ());

          err = gnutls_init (&session, GNUTLS_CLIENT);
          if (err != 0)
            fail ("client session %d\n", err);

          if (i==0) /* we use the primary key which is RSA. Test the RSA ciphersuite */
            gnutls_priority_set_direct (session,
                                      "NONE:+VERS-TLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+RSA:+CTYPE-OPENPGP",
                                      NULL);
          else
            gnutls_priority_set_direct (session,
                                      "NONE:+VERS-TLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+DHE-DSS:+DHE-RSA:+CTYPE-OPENPGP",
                                      NULL);
          gnutls_transport_set_ptr (session,
                                    (gnutls_transport_ptr_t) (intptr_t)
                                    sockets[0]);

          err = gnutls_certificate_allocate_credentials (&cred);
          if (err != 0)
            fail ("client credentials %d\n", err);

          err =
            gnutls_certificate_set_openpgp_key_file2 (cred,
                                                      pub_key_path,
                                                      priv_key_path, key_id,
                                                      GNUTLS_OPENPGP_FMT_BASE64);
          if (err != 0)
            fail ("client openpgp keys %s\n", gnutls_strerror (err));

          err =
            gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, cred);
          if (err != 0)
            fail ("client credential_set %d\n", err);

          gnutls_dh_set_prime_bits (session, 1024);

          err = gnutls_handshake (session);
          if (err != 0)
            fail ("client handshake %s (%d) \n", gnutls_strerror (err), err);
          else if (debug)
            printf ("client handshake successful\n");

          sent = gnutls_record_send (session, message, sizeof (message));
          if (sent != sizeof (message))
            fail ("client sent %li vs. %li\n",
                  (long) sent, (long) sizeof (message));

          err = gnutls_bye (session, GNUTLS_SHUT_RDWR);
          if (err != 0)
            fail ("client bye %d\n", err);

          if (debug)
            printf ("client done\n");
          
          gnutls_deinit(session);
          gnutls_certificate_free_credentials (cred);
        }
      else
        {
          /* Parent process (server).  */
          gnutls_session_t session;
          gnutls_dh_params_t dh_params;
          gnutls_certificate_credentials_t cred;
          char greetings[sizeof (message) * 2];
          ssize_t received;
          pid_t done;
          int status;
          const gnutls_datum_t p3 = { (void *) pkcs3, strlen (pkcs3) };

          if (debug)
            printf ("server process %i (child %i)\n", getpid (), child);

          err = gnutls_init (&session, GNUTLS_SERVER);
          if (err != 0)
            fail ("server session %d\n", err);

          gnutls_priority_set_direct (session,
                                      "NONE:+VERS-TLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+DHE-DSS:+DHE-RSA:+RSA:+CTYPE-OPENPGP",
                                      NULL);
          gnutls_transport_set_ptr (session,
                                    (gnutls_transport_ptr_t) (intptr_t)
                                    sockets[1]);

          err = gnutls_certificate_allocate_credentials (&cred);
          if (err != 0)
            fail ("server credentials %d\n", err);

          err =
            gnutls_certificate_set_openpgp_key_file2 (cred,
                                                      pub_key_path,
                                                      priv_key_path, key_id,
                                                      GNUTLS_OPENPGP_FMT_BASE64);
          if (err != 0)
            fail ("server openpgp keys %s\n", gnutls_strerror (err));

          err = gnutls_dh_params_init (&dh_params);
          if (err)
            fail ("server DH params init %d\n", err);

          err =
            gnutls_dh_params_import_pkcs3 (dh_params, &p3,
                                           GNUTLS_X509_FMT_PEM);
          if (err)
            fail ("server DH params generate %d\n", err);

          gnutls_certificate_set_dh_params (cred, dh_params);

          err =
            gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, cred);
          if (err != 0)
            fail ("server credential_set %d\n", err);

          gnutls_certificate_server_set_request (session,
                                                 GNUTLS_CERT_REQUIRE);

          err = gnutls_handshake (session);
          if (err != 0)
            fail ("server handshake %s (%d) \n", gnutls_strerror (err), err);

          received =
            gnutls_record_recv (session, greetings, sizeof (greetings));
          if (received != sizeof (message)
              || memcmp (greetings, message, sizeof (message)))
            fail ("server received %li vs. %li\n", (long) received,
                  (long) sizeof (message));

          err = gnutls_bye (session, GNUTLS_SHUT_RDWR);
          if (err != 0)
            fail ("server bye %s (%d) \n", gnutls_strerror (err), err);

          if (debug)
            printf ("server done\n");

          gnutls_deinit(session);
          gnutls_certificate_free_credentials (cred);
          gnutls_dh_params_deinit (dh_params);

          done = wait (&status);
          if (done < 0)
            fail ("wait %s\n", strerror (errno));

          if (done != child)
            fail ("who's that?! %d\n", done);

          if (WIFEXITED (status))
            {
              if (WEXITSTATUS (status) != 0)
                fail ("child exited with status %d\n", WEXITSTATUS (status));
            }
          else if (WIFSIGNALED (status))
            fail ("child stopped by signal %d\n", WTERMSIG (status));
          else
            fail ("child failed: %d\n", status);
        }

    }

  gnutls_global_deinit ();
}
Ejemplo n.º 18
0
int Sudo::parent()
{
    //set the FD as non-blocking
    if (0 != fcntl(mPwdFd, F_SETFL, O_NONBLOCK))
    {
        QMessageBox(QMessageBox::Critical, mDlg->windowTitle()
                , tr("Failed to set non-block: %1").arg(strerror(errno)), QMessageBox::Ok).exec();
        return 1;
    }

    FILE * pwd_f = fdopen(mPwdFd, "r+");
    if (nullptr == pwd_f)
    {
        QMessageBox(QMessageBox::Critical, mDlg->windowTitle()
                , tr("Failed to fdopen: %1").arg(strerror(errno)), QMessageBox::Ok).exec();
        return 1;
    }

    QTextStream child_str{pwd_f};

    QObject::connect(mDlg.data(), &QDialog::finished, [&] (int result)
        {
            if (QDialog::Accepted == result)
            {
                child_str << mDlg->password().append(nl);
                child_str.flush();
            } else
            {
                stopChild();
                lxqtApp->quit();
            }
        });

    QString last_line;
    QScopedPointer<QSocketNotifier> pwd_watcher{new QSocketNotifier{mPwdFd, QSocketNotifier::Read}};
    QObject::connect(pwd_watcher.data(), &QSocketNotifier::activated, [&]
        {
            QString line = child_str.readAll();
            if (line.isEmpty())
            {
                pwd_watcher.reset(nullptr);
                QString const & prog = BACK_SU == mBackend ? su_prog : sudo_prog;
                if (last_line.startsWith(QStringLiteral("%1:").arg(prog)))
                {
                    pwd_watcher.reset(nullptr); //stop the notifications events
                    stopChild();
                    QMessageBox(QMessageBox::Critical, mDlg->windowTitle()
                            , tr("Child '%1' process failed!\n%2").arg(prog).arg(last_line), QMessageBox::Ok).exec();
                }
                lxqtApp->quit();
            } else
            {
                if (line.endsWith(pwd_prompt_end))
                {
                    //if now echo is turned off, su/sudo requests password
                    struct termios tios;
                    //loop to be sure we don't miss the flag (we can afford such small delay in "normal" output processing)
                    for (size_t cnt = 10; 0 < cnt && 0 == tcgetattr(mPwdFd, &tios) && (ECHO & tios.c_lflag); --cnt)
                        QThread::msleep(10);
                    if (!(ECHO & tios.c_lflag))
                    {
                        mDlg->show();
                        return;
                    }
                }
                QTextStream{stderr, QIODevice::WriteOnly} << line;
                //assuming text oriented output
                QStringList lines = line.split(nl, QString::SkipEmptyParts);
                last_line = lines.isEmpty() ? QString() : lines.back();
            }

        });

    lxqtApp->exec();

    if (0 < mChildPid)
    {
        int res, status;
        res = waitpid(mChildPid, &status, 0);
        mRet = (mChildPid == res && WIFEXITED(status)) ? WEXITSTATUS(status) : 1;
    }

    return mRet;
}
Ejemplo n.º 19
0
/*
 * Performs the interactive session.  This handles data transmission between
 * the client and the program.  Note that the notion of stdin, stdout, and
 * stderr in this function is sort of reversed: this function writes to
 * stdin (of the child program), and reads from stdout and stderr (of the
 * child program).
 */
void
server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
{
	fd_set *readset = NULL, *writeset = NULL;
	int max_fd = 0;
	u_int nalloc = 0;
	int wait_status;	/* Status returned by wait(). */
	pid_t wait_pid;		/* pid returned by wait(). */
	int waiting_termination = 0;	/* Have displayed waiting close message. */
	u_int max_time_milliseconds;
	u_int previous_stdout_buffer_bytes;
	u_int stdout_buffer_bytes;
	int type;

	debug("Entering interactive session.");

	/* Initialize the SIGCHLD kludge. */
	child_terminated = 0;
	mysignal(SIGCHLD, sigchld_handler);

	if (!use_privsep) {
		signal(SIGTERM, sigterm_handler);
		signal(SIGINT, sigterm_handler);
		signal(SIGQUIT, sigterm_handler);
	}

	/* Initialize our global variables. */
	fdin = fdin_arg;
	fdout = fdout_arg;
	fderr = fderr_arg;

	/* nonblocking IO */
	set_nonblock(fdin);
	set_nonblock(fdout);
	/* we don't have stderr for interactive terminal sessions, see below */
	if (fderr != -1)
		set_nonblock(fderr);

	if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin))
		fdin_is_tty = 1;

	connection_in = packet_get_connection_in();
	connection_out = packet_get_connection_out();

	notify_setup();

	previous_stdout_buffer_bytes = 0;

	/* Set approximate I/O buffer size. */
	if (packet_is_interactive())
		buffer_high = 4096;
	else
		buffer_high = 64 * 1024;

#if 0
	/* Initialize max_fd to the maximum of the known file descriptors. */
	max_fd = MAX(connection_in, connection_out);
	max_fd = MAX(max_fd, fdin);
	max_fd = MAX(max_fd, fdout);
	if (fderr != -1)
		max_fd = MAX(max_fd, fderr);
#endif

	/* Initialize Initialize buffers. */
	buffer_init(&stdin_buffer);
	buffer_init(&stdout_buffer);
	buffer_init(&stderr_buffer);

	/*
	 * If we have no separate fderr (which is the case when we have a pty
	 * - there we cannot make difference between data sent to stdout and
	 * stderr), indicate that we have seen an EOF from stderr.  This way
	 * we don't need to check the descriptor everywhere.
	 */
	if (fderr == -1)
		fderr_eof = 1;

	server_init_dispatch();

	/* Main loop of the server for the interactive session mode. */
	for (;;) {

		/* Process buffered packets from the client. */
		process_buffered_input_packets();

		/*
		 * If we have received eof, and there is no more pending
		 * input data, cause a real eof by closing fdin.
		 */
		if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) {
			if (fdin != fdout)
				close(fdin);
			else
				shutdown(fdin, SHUT_WR); /* We will no longer send. */
			fdin = -1;
		}
		/* Make packets from buffered stderr data to send to the client. */
		make_packets_from_stderr_data();

		/*
		 * Make packets from buffered stdout data to send to the
		 * client. If there is very little to send, this arranges to
		 * not send them now, but to wait a short while to see if we
		 * are getting more data. This is necessary, as some systems
		 * wake up readers from a pty after each separate character.
		 */
		max_time_milliseconds = 0;
		stdout_buffer_bytes = buffer_len(&stdout_buffer);
		if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 &&
		    stdout_buffer_bytes != previous_stdout_buffer_bytes) {
			/* try again after a while */
			max_time_milliseconds = 10;
		} else {
			/* Send it now. */
			make_packets_from_stdout_data();
		}
		previous_stdout_buffer_bytes = buffer_len(&stdout_buffer);

		/* Send channel data to the client. */
		if (packet_not_very_much_data_to_write())
			channel_output_poll();

		/*
		 * Bail out of the loop if the program has closed its output
		 * descriptors, and we have no more data to send to the
		 * client, and there is no pending buffered data.
		 */
		if (fdout_eof && fderr_eof && !packet_have_data_to_write() &&
		    buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) {
			if (!channel_still_open())
				break;
			if (!waiting_termination) {
				const char *s = "Waiting for forwarded connections to terminate...\r\n";
				char *cp;
				waiting_termination = 1;
				buffer_append(&stderr_buffer, s, strlen(s));

				/* Display list of open channels. */
				cp = channel_open_message();
				buffer_append(&stderr_buffer, cp, strlen(cp));
				xfree(cp);
			}
		}
		max_fd = MAX(connection_in, connection_out);
		max_fd = MAX(max_fd, fdin);
		max_fd = MAX(max_fd, fdout);
		max_fd = MAX(max_fd, fderr);
		max_fd = MAX(max_fd, notify_pipe[0]);

		/* Sleep in select() until we can do something. */
		wait_until_can_do_something(&readset, &writeset, &max_fd,
		    &nalloc, max_time_milliseconds);

		if (received_sigterm) {
			logit("Exiting on signal %d", received_sigterm);
			/* Clean up sessions, utmp, etc. */
			cleanup_exit(255);
		}

		/* Process any channel events. */
		channel_after_select(readset, writeset);

		/* Process input from the client and from program stdout/stderr. */
		process_input(readset);

		/* Process output to the client and to program stdin. */
		process_output(writeset);
	}
	if (readset)
		xfree(readset);
	if (writeset)
		xfree(writeset);

	/* Cleanup and termination code. */

	/* Wait until all output has been sent to the client. */
	drain_output();

	debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.",
	    stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes);

	/* Free and clear the buffers. */
	buffer_free(&stdin_buffer);
	buffer_free(&stdout_buffer);
	buffer_free(&stderr_buffer);

	/* Close the file descriptors. */
	if (fdout != -1)
		close(fdout);
	fdout = -1;
	fdout_eof = 1;
	if (fderr != -1)
		close(fderr);
	fderr = -1;
	fderr_eof = 1;
	if (fdin != -1)
		close(fdin);
	fdin = -1;

	channel_free_all();

	/* We no longer want our SIGCHLD handler to be called. */
	mysignal(SIGCHLD, SIG_DFL);

	while ((wait_pid = waitpid(-1, &wait_status, 0)) < 0)
		if (errno != EINTR)
			packet_disconnect("wait: %.100s", strerror(errno));
	if (wait_pid != pid)
		error("Strange, wait returned pid %ld, expected %ld",
		    (long)wait_pid, (long)pid);

	/* Check if it exited normally. */
	if (WIFEXITED(wait_status)) {
		/* Yes, normal exit.  Get exit status and send it to the client. */
		debug("Command exited with status %d.", WEXITSTATUS(wait_status));
		packet_start(SSH_SMSG_EXITSTATUS);
		packet_put_int(WEXITSTATUS(wait_status));
		packet_send();
		packet_write_wait();

		/*
		 * Wait for exit confirmation.  Note that there might be
		 * other packets coming before it; however, the program has
		 * already died so we just ignore them.  The client is
		 * supposed to respond with the confirmation when it receives
		 * the exit status.
		 */
		do {
			type = packet_read();
		}
		while (type != SSH_CMSG_EXIT_CONFIRMATION);

		debug("Received exit confirmation.");
		return;
	}
	/* Check if the program terminated due to a signal. */
	if (WIFSIGNALED(wait_status))
		packet_disconnect("Command terminated on signal %d.",
				  WTERMSIG(wait_status));

	/* Some weird exit cause.  Just exit. */
	packet_disconnect("wait returned status %04x.", wait_status);
	/* NOTREACHED */
}
Ejemplo n.º 20
0
EXPORT_C
#endif
void
_dbus_babysitter_unref (DBusBabysitter *sitter)
{
  _dbus_assert (sitter != NULL);
  _dbus_assert (sitter->refcount > 0);
  
  sitter->refcount -= 1;
  if (sitter->refcount == 0)
    {      
      if (sitter->socket_to_babysitter >= 0)
        {
          /* If we haven't forked other babysitters
           * since this babysitter and socket were
           * created then this close will cause the
           * babysitter to wake up from poll with
           * a hangup and then the babysitter will
           * quit itself.
           */
          _dbus_close_socket (sitter->socket_to_babysitter, NULL);
          sitter->socket_to_babysitter = -1;
        }

      if (sitter->error_pipe_from_child >= 0)
        {
          _dbus_close_socket (sitter->error_pipe_from_child, NULL);
          sitter->error_pipe_from_child = -1;
        }

      if (sitter->sitter_pid > 0)
        {
          int status;
          int ret;

          /* It's possible the babysitter died on its own above 
           * from the close, or was killed randomly
           * by some other process, so first try to reap it
           */
          ret = waitpid (sitter->sitter_pid, &status, WNOHANG);

          /* If we couldn't reap the child then kill it, and
           * try again
           */
#ifndef __SYMBIAN32__           
          if (ret == 0)          
            kill (sitter->sitter_pid, SIGKILL);
#endif          

        again:
          if (ret == 0)
            ret = waitpid (sitter->sitter_pid, &status, 0);

          if (ret < 0)
            {
              if (errno == EINTR)
                goto again;
              else if (errno == ECHILD)
                _dbus_warn ("Babysitter process not available to be reaped; should not happen\n");
              else
                _dbus_warn ("Unexpected error %d in waitpid() for babysitter: %s\n",
                            errno, _dbus_strerror (errno));
            }
          else
            {
              _dbus_verbose ("Reaped %ld, waiting for babysitter %ld\n",
                             (long) ret, (long) sitter->sitter_pid);
              
              if (WIFEXITED (sitter->status))
                _dbus_verbose ("Babysitter exited with status %d\n",
                               WEXITSTATUS (sitter->status));
              else if (WIFSIGNALED (sitter->status))
                _dbus_verbose ("Babysitter received signal %d\n",
                               WTERMSIG (sitter->status));
              else
                _dbus_verbose ("Babysitter exited abnormally\n");
            }

          sitter->sitter_pid = -1;
        }
      
      if (sitter->error_watch)
        {
          _dbus_watch_invalidate (sitter->error_watch);
          _dbus_watch_unref (sitter->error_watch);
          sitter->error_watch = NULL;
        }

      if (sitter->sitter_watch)
        {
          _dbus_watch_invalidate (sitter->sitter_watch);
          _dbus_watch_unref (sitter->sitter_watch);
          sitter->sitter_watch = NULL;
        }
      
      if (sitter->watches)
        _dbus_watch_list_free (sitter->watches);

      dbus_free (sitter->executable);
      
      dbus_free (sitter);
    }
}
Ejemplo n.º 21
0
static ReadStatus
read_data (DBusBabysitter *sitter,
           int             fd)
{
  int what;
  int got;
  DBusError error;
  ReadStatus r;
  
  dbus_error_init (&error);
  
  r = read_ints (fd, &what, 1, &got, &error);

  switch (r)
    {
    case READ_STATUS_ERROR:
      _dbus_warn ("Failed to read data from fd %d: %s\n", fd, error.message);
      dbus_error_free (&error);
      return r;

    case READ_STATUS_EOF:
      return r;

    case READ_STATUS_OK:
      break;
    }
  
  if (got == 1)
    {
      switch (what)
        {
        case CHILD_EXITED:
        case CHILD_FORK_FAILED:
        case CHILD_EXEC_FAILED:
          {
            int arg;
            
            r = read_ints (fd, &arg, 1, &got, &error);

            switch (r)
              {
              case READ_STATUS_ERROR:
                _dbus_warn ("Failed to read arg from fd %d: %s\n", fd, error.message);
                dbus_error_free (&error);
                return r;
              case READ_STATUS_EOF:
                return r;
              case READ_STATUS_OK:
                break;
              }
            
            if (got == 1)
              {
                if (what == CHILD_EXITED)
                  {
                    sitter->have_child_status = TRUE;
                    sitter->status = arg;
                    _dbus_verbose ("recorded child status exited = %d signaled = %d exitstatus = %d termsig = %d\n",
                                   WIFEXITED (sitter->status), WIFSIGNALED (sitter->status),
                                   WEXITSTATUS (sitter->status), WTERMSIG (sitter->status));
                  }
                else if (what == CHILD_FORK_FAILED)
                  {
                    sitter->have_fork_errnum = TRUE;
                    sitter->errnum = arg;
                    _dbus_verbose ("recorded fork errnum %d\n", sitter->errnum);
                  }
                else if (what == CHILD_EXEC_FAILED)
                  {
                    sitter->have_exec_errnum = TRUE;
                    sitter->errnum = arg;
                    _dbus_verbose ("recorded exec errnum %d\n", sitter->errnum);
                  }
              }
          }
          break;
        case CHILD_PID:
          {
            pid_t pid = -1;

            r = read_pid (fd, &pid, &error);
            
            switch (r)
              {
              case READ_STATUS_ERROR:
                _dbus_warn ("Failed to read PID from fd %d: %s\n", fd, error.message);
                dbus_error_free (&error);
                return r;
              case READ_STATUS_EOF:
                return r;
              case READ_STATUS_OK:
                break;
              }
            
            sitter->grandchild_pid = pid;
            
            _dbus_verbose ("recorded grandchild pid %d\n", sitter->grandchild_pid);
          }
          break;
        default:
          _dbus_warn ("Unknown message received from babysitter process\n");
          break;
        }
    }

  return r;
}
Ejemplo n.º 22
0
int callPosixSpawn(const char *cmdline) {
    char command[1024];
    char progName[1024];
    char progPath[MAXPATHLEN];
    char* argv[100];
    int argc = 0;
    char *p;
    pid_t thePid = 0;
    int result = 0;
    int status = 0;
    extern char **environ;
    
    // Make a copy of cmdline because parse_posic_spawn_command_line modifies it
    strlcpy(command, cmdline, sizeof(command));
    argc = parse_posic_spawn_command_line(const_cast<char*>(command), argv);
    strlcpy(progPath, argv[0], sizeof(progPath));
    strlcpy(progName, argv[0], sizeof(progName));
    p = strrchr(progName, '/');
    if (p) {
        argv[0] = p+1;
    } else {
        argv[0] = progName;
    }
    
#if VERBOSE_SPAWN
    fprintf(stderr, "***********");
    for (int i=0; i<argc; ++i) {
        fprintf(stderr, "argv[%d]=%s", i, argv[i]);
    }
    fprintf(stderr, "***********\n");
#endif

    errno = 0;

    result = posix_spawnp(&thePid, progPath, NULL, NULL, argv, environ);
#if VERBOSE_SPAWN
    fprintf(stderr, "callPosixSpawn command: %s", cmdline);
    fprintf(stderr, "callPosixSpawn: posix_spawnp returned %d: %s", result, strerror(result));
#endif
    if (result) {
        return result;
    }
// CAF    int val =
    waitpid(thePid, &status, WUNTRACED);
// CAF        if (val < 0) printf("first waitpid returned %d\n", val);
    if (status != 0) {
#if VERBOSE_SPAWN
        fprintf(stderr, "waitpid() returned status=%d", status);
#endif
        result = status;
    } else {
        if (WIFEXITED(status)) {
            result = WEXITSTATUS(status);
            if (result == 1) {
#if VERBOSE_SPAWN
                fprintf(stderr, "WEXITSTATUS(status) returned 1, errno=%d: %s", errno, strerror(errno));
#endif
                result = errno;
            }
#if VERBOSE_SPAWN
            else if (result) {
                fprintf(stderr, "WEXITSTATUS(status) returned %d", result);
            }
#endif
        }   // end if (WIFEXITED(status)) else
    }       // end if waitpid returned 0 sstaus else
    
    return result;
}
Ejemplo n.º 23
0
void
_ecore_signal_call(void)
{
#ifdef SIGRTMIN
   int i, num = SIGRTMAX - SIGRTMIN;
#endif
   volatile sig_atomic_t n;
   sigset_t oldset, newset;

   if (sig_count == 0) return;
   sigemptyset(&newset);
   sigaddset(&newset, SIGPIPE);
   sigaddset(&newset, SIGALRM);
   sigaddset(&newset, SIGCHLD);
   sigaddset(&newset, SIGUSR1);
   sigaddset(&newset, SIGUSR2);
   sigaddset(&newset, SIGHUP);
   sigaddset(&newset, SIGQUIT);
   sigaddset(&newset, SIGINT);
   sigaddset(&newset, SIGTERM);
#ifdef SIGPWR
   sigaddset(&newset, SIGPWR);
#endif
#ifdef SIGRTMIN
   for (i = 0; i < num; i++)
     sigaddset(&newset, SIGRTMIN + i);
#endif
   sigprocmask(SIG_BLOCK, &newset, &oldset);
   if (sigchld_count > MAXSIGQ)
     WRN("%i SIGCHLD in queue. max queue size %i. losing "
	  "siginfo for extra signals.", sigchld_count, MAXSIGQ);
   for (n = 0; n < sigchld_count; n++)
     {
	pid_t pid;
	int status;

	while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
	  {
	     Ecore_Exe_Event_Del *e;

	     /* FIXME: If this process is set respawn, respawn with a suitable backoff
	      * period for those that need too much respawning.
	      */
	     e = _ecore_exe_event_del_new();
	     if (e)
	       {
		  if (WIFEXITED(status))
		    {
		       e->exit_code = WEXITSTATUS(status);
		       e->exited = 1;
		    }
		  else if (WIFSIGNALED(status))
		    {
		       e->exit_signal = WTERMSIG(status);
		       e->signalled = 1;
		    }
		  e->pid = pid;
		  e->exe = _ecore_exe_find(pid);

		  if ((n < MAXSIGQ) && (sigchld_info[n].si_signo))
		    e->data = sigchld_info[n]; /* No need to clone this. */

                  if ((e->exe) && (ecore_exe_flags_get(e->exe) & (ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR)))
                     {
		        /* We want to report the Last Words of the exe, so delay this event.
			 * This is twice as relevant for stderr.
			 * There are three possibilities here -
			 *  1 There are no Last Words.
			 *  2 There are Last Words, they are not ready to be read.
			 *  3 There are Last Words, they are ready to be read.
			 *
			 * For 1 we don't want to delay, for 3 we want to delay.
			 * 2 is the problem.  If we check for data now and there
			 * is none, then there is no way to differentiate 1 and 2.
			 * If we don't delay, we may loose data, but if we do delay,
			 * there may not be data and the exit event never gets sent.
			 *
			 * Any way you look at it, there has to be some time passed
			 * before the exit event gets sent.  So the strategy here is
			 * to setup a timer event that will send the exit event after
			 * an arbitrary, but brief, time.
			 *
			 * This is probably paranoid, for the less paraniod, we could
			 * check to see for Last Words, and only delay if there are any.
			 * This has it's own set of problems.
			 */
                        Ecore_Timer *doomsday_clock;

                        doomsday_clock = _ecore_exe_doomsday_clock_get(e->exe);
                        IF_FN_DEL(ecore_timer_del, doomsday_clock);
                        _ecore_exe_doomsday_clock_set(e->exe, ecore_timer_add(0.1, _ecore_signal_exe_exit_delay, e));
                     }
		  else
		    {
		       _ecore_event_add(ECORE_EXE_EVENT_DEL, e,
				   _ecore_exe_event_del_free, NULL);
		    }
	       }
	  }
	sig_count--;
     }
   sigchld_count = 0;

   if (sigusr1_count > MAXSIGQ)
     WRN("%i SIGUSR1 in queue. max queue size %i. losing "
	 "siginfo for extra signals.", sigusr1_count, MAXSIGQ);
   for (n = 0; n < sigusr1_count; n++)
     {
	Ecore_Event_Signal_User *e;

	e = _ecore_event_signal_user_new();
	if (e)
	  {
	     e->number = 1;

	     if ((n < MAXSIGQ) && (sigusr1_info[n].si_signo))
	       e->data = sigusr1_info[n];

	     ecore_event_add(ECORE_EVENT_SIGNAL_USER, e, NULL, NULL);
	  }
	sig_count--;
     }
   sigusr1_count = 0;

   if (sigusr2_count > MAXSIGQ)
     WRN("%i SIGUSR2 in queue. max queue size %i. losing "
	 "siginfo for extra signals.", sigusr2_count, MAXSIGQ);
   for (n = 0; n < sigusr2_count; n++)
     {
	Ecore_Event_Signal_User *e;

	e = _ecore_event_signal_user_new();
	if (e)
	  {
	     e->number = 2;

	     if ((n < MAXSIGQ) && (sigusr2_info[n].si_signo))
	       e->data = sigusr2_info[n];

	     ecore_event_add(ECORE_EVENT_SIGNAL_USER, e, NULL, NULL);
	  }
	sig_count--;
     }
   sigusr2_count = 0;

   if (sighup_count > MAXSIGQ)
     WRN("%i SIGHUP in queue. max queue size %i. losing "
	 "siginfo for extra signals.", sighup_count, MAXSIGQ);
   for (n = 0; n < sighup_count; n++)
     {
	Ecore_Event_Signal_Hup *e;

	e = _ecore_event_signal_hup_new();
	if (e)
	  {
	     if ((n < MAXSIGQ) && (sighup_info[n].si_signo))
	       e->data = sighup_info[n];

	     ecore_event_add(ECORE_EVENT_SIGNAL_HUP, e, NULL, NULL);
	  }
	sig_count--;
     }
   sighup_count = 0;

   if (sigquit_count > MAXSIGQ)
     WRN("%i SIGQUIT in queue. max queue size %i. losing "
	 "siginfo for extra signals.", sigquit_count, MAXSIGQ);
   for (n = 0; n < sigquit_count; n++)
     {
	Ecore_Event_Signal_Exit *e;

	e = _ecore_event_signal_exit_new();
	if (e)
	  {
	     e->quit = 1;

	     if ((n < MAXSIGQ) && (sigquit_info[n].si_signo))
	       e->data = sigquit_info[n];

	     ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL);
	  }
	sig_count--;
     }
   sigquit_count = 0;

   if (sigint_count > MAXSIGQ)
     WRN("%i SIGINT in queue. max queue size %i. losing "
	 "siginfo for extra signals.", sigint_count, MAXSIGQ);
   for (n = 0; n < sigint_count; n++)
     {
	Ecore_Event_Signal_Exit *e;

	e = _ecore_event_signal_exit_new();
	if (e)
	  {
	     e->interrupt = 1;

	     if ((n < MAXSIGQ) && (sigint_info[n].si_signo))
	       e->data = sigint_info[n];

	     ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL);
	  }
	sig_count--;
     }
   sigint_count = 0;

   if (sigterm_count > MAXSIGQ)
     WRN("%i SIGTERM in queue. max queue size %i. losing "
	 "siginfo for extra signals.", sigterm_count, MAXSIGQ);
   for (n = 0; n < sigterm_count; n++)
     {
	Ecore_Event_Signal_Exit *e;

	e = _ecore_event_signal_exit_new();
	if (e)
	  {
	     e->terminate = 1;

	     if ((n < MAXSIGQ) && (sigterm_info[n].si_signo))
	       e->data = sigterm_info[n];

	     ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL);
	  }
	sig_count--;
     }
   sigterm_count = 0;

#ifdef SIGPWR
   if (sigpwr_count > MAXSIGQ)
     WRN("%i SIGPWR in queue. max queue size %i. losing "
	 "siginfo for extra signals.", sigpwr_count, MAXSIGQ);
   for (n = 0; n < sigpwr_count; n++)
     {
	Ecore_Event_Signal_Power *e;

	e = _ecore_event_signal_power_new();
	if (e)
	  {
	     if ((n < MAXSIGQ) && (sigpwr_info[n].si_signo))
	       e->data = sigpwr_info[n];

	     ecore_event_add(ECORE_EVENT_SIGNAL_POWER, e, NULL, NULL);
	  }
	sig_count--;
     }
   sigpwr_count = 0;
#endif

#ifdef SIGRTMIN
   for (i = 0; i < num; i++)
     {
	if (sigrt_count[i] > MAXSIGQ)
	  WRN("%i SIGRT%i in queue. max queue size %i. losing "
	      "siginfo for extra signals.", i + 1, sigrt_count[i], MAXSIGQ);
	for (n = 0; n < sigrt_count[i]; n++)
	  {
	     Ecore_Event_Signal_Realtime *e;

	     if ((e = _ecore_event_signal_realtime_new()))
	       {
		  e->num = i;

		  if ((n < MAXSIGQ) && (sigrt_info[n][i].si_signo))
		    e->data = sigrt_info[n][i];

		  ecore_event_add(ECORE_EVENT_SIGNAL_REALTIME, e, NULL, NULL);
	       }
	     sig_count--;
	  }
	sigrt_count[i] = 0;
     }
#endif
   sigprocmask(SIG_SETMASK, &oldset, NULL);
}
Ejemplo n.º 24
0
extern int slurm_ckpt_signal_tasks(stepd_step_rec_t *job, char *image_dir)
{
	char *argv[4];
	char context_file[MAXPATHLEN];
	char pid[16];
	int status;
	pid_t *children = NULL;
	int *fd = NULL;
	int rc = SLURM_SUCCESS;
	int i;
	char c;

	debug3("checkpoint/blcr: slurm_ckpt_signal_tasks: image_dir=%s",
	       image_dir);
	/*
	 * the tasks must be checkpointed concurrently.
	 */
	children = xmalloc(sizeof(pid_t) * job->node_tasks);
	fd = xmalloc(sizeof(int) * 2 * job->node_tasks);
	if (!children || !fd) {
		error("slurm_ckpt_signal_tasks: memory exhausted");
		rc = SLURM_FAILURE;
		goto out;
	}
	for (i = 0; i < job->node_tasks; i ++) {
		fd[i*2] = -1;
		fd[i*2+1] = -1;
	}

	for (i = 0; i < job->node_tasks; i ++) {
		if (job->batch) {
			sprintf(context_file, "%s/script.ckpt", image_dir);
		} else {
			sprintf(context_file, "%s/task.%d.ckpt",
				image_dir, job->task[i]->gtid);
		}
		sprintf(pid, "%u", (unsigned int)job->task[i]->pid);

		if (pipe(&fd[i*2]) < 0) {
			error("failed to create pipes: %m");
			rc = SLURM_ERROR;
			goto out_wait;
		}

		children[i] = fork();
		if (children[i] < 0) {
			error("error forking cr_checkpoint");
			rc = SLURM_ERROR;
			goto out_wait;
		} else if (children[i] == 0) {
			close(fd[i*2+1]);

			while(read(fd[i*2], &c, 1) < 0 && errno == EINTR);
			if (c)
				exit(-1);

			/* change cred to job owner */
			if (setgid(job->gid) < 0) {
				error ("checkpoint/blcr: "
				       "slurm_ckpt_signal_tasks: "
				       "failed to setgid: %m");
				exit(errno);
			}
			if (setuid(job->uid) < 0) {
				error ("checkpoint/blcr: "
				       "slurm_ckpt_signal_tasks: "
				       "failed to setuid: %m");
				exit(errno);
			}
			if (chdir(job->cwd) < 0) {
				error ("checkpoint/blcr: "
				       "slurm_ckpt_signal_tasks: "
				       "failed to chdir: %m");
				exit(errno);
			}

			argv[0] = (char *)cr_checkpoint_path;
			argv[1] = pid;
			argv[2] = context_file;
			argv[3] = NULL;

			execv(argv[0], argv);
			exit(errno);
		}
		close(fd[i*2]);
	}

 out_wait:
	c = (rc == SLURM_SUCCESS) ? 0 : 1;
	for (i = 0; i < job->node_tasks; i ++) {
		if (fd[i*2+1] >= 0) {
			while(write(fd[i*2+1], &c, 1) < 0 && errno == EINTR);
		}
	}
	/* wait children in sequence is OK */
	for (i = 0; i < job->node_tasks; i ++) {
		if (children[i] == 0)
			continue;
		while(waitpid(children[i], &status, 0) < 0 && errno == EINTR);
		if (! (WIFEXITED(status) && WEXITSTATUS(status))== 0)
			rc = SLURM_ERROR;
	}
 out:
	xfree(children);
	xfree(fd);

	return rc;
}
Ejemplo n.º 25
0
Archivo: 1-1.c Proyecto: AbhiramiP/ltp
int main(void)
{
	int pid;
	int rc;
	int pfd[2];
	int status = PTS_UNRESOLVED;
	int s;
	struct sched_param sp;
	char buf[8];

	/* Set up a pipe, for synching.  */
	rc = pipe(pfd);
	if (rc) {
		ERR_LOG("pipe", rc);
		return status;
	}

	/* get in FIFO */
	sp.sched_priority = sched_get_priority_min(SCHED_FIFO);
	rc = sched_setscheduler(getpid(), SCHED_FIFO, &sp);
	if (rc) {
		ERR_LOG("sched_setscheduler", rc);
		return status;
	}

	/* Must only use a single CPU */
	rc = set_affinity(0);
	if (rc) {
		ERR_LOG("set_affinity", rc);
		return status;
	}

	pid = fork();
	if (pid == 0)
		child_busy(pfd[1]);

	if (pid < 0) {
		ERR_LOG("fork", rc);
		return status;
	}

	/* wait for child */
	rc = read(pfd[0], buf, sizeof(buf));
	if (rc != 2) {
		kill(pid, SIGTERM);
		waitpid(pid, NULL, 0);
		ERR_LOG("read", rc);
		return status;
	}

	/* Can only get here if sched_yield works. */
	kill(pid, SIGTERM);
	waitpid(pid, &s, 0);

	status = PTS_PASS;
	if (WIFSIGNALED(s)) {
		s = WTERMSIG(s);
		if (s != SIGTERM) {
			printf("Failed: kill signal: %d, should be: %d\n",
			       s, SIGTERM);
			status = PTS_FAIL;
		}
	} else if (WIFEXITED(s)) {
		printf("Failed: child prematurely exited with: %d\n",
		       WEXITSTATUS(s));
		status = PTS_FAIL;
	}

	if (status == PTS_PASS)
		printf("Test PASSED\n");

	return status;
}
Ejemplo n.º 26
0
/*
 * Close both pipes and free resources
 *
 *  Returns: 0 on success
 *           berrno on failure
 */
int close_bpipe(BPIPE *bpipe)
{
   int chldstatus = 0;
   int stat = 0;
   int wait_option;
   int remaining_wait;
   pid_t wpid = 0;


   /* Close pipes */
   if (bpipe->rfd) {
      fclose(bpipe->rfd);
      bpipe->rfd = NULL;
   }
   if (bpipe->wfd) {
      fclose(bpipe->wfd);
      bpipe->wfd = NULL;
   }

   if (bpipe->wait == 0) {
      wait_option = 0;                /* wait indefinitely */
   } else {
      wait_option = WNOHANG;          /* don't hang */
   }
   remaining_wait = bpipe->wait;

   /* wait for worker child to exit */
   for ( ;; ) {
      Dmsg2(800, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
      do {
         wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
      } while (wpid == -1 && (errno == EINTR || errno == EAGAIN));
      if (wpid == bpipe->worker_pid || wpid == -1) {
         berrno be;
         stat = errno;
         Dmsg3(800, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
            wpid==-1?be.bstrerror():"none");
         break;
      }
      Dmsg3(800, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
            wpid==-1?strerror(errno):"none");
      if (remaining_wait > 0) {
         bmicrosleep(1, 0);           /* wait one second */
         remaining_wait--;
      } else {
         stat = ETIME;                /* set error status */
         wpid = -1;
         break;                       /* don't wait any longer */
      }
   }
   if (wpid > 0) {
      if (WIFEXITED(chldstatus)) {    /* process exit()ed */
         stat = WEXITSTATUS(chldstatus);
         if (stat != 0) {
            Dmsg1(800, "Non-zero status %d returned from child.\n", stat);
            stat |= b_errno_exit;        /* exit status returned */
         }
         Dmsg1(800, "child status=%d\n", stat & ~b_errno_exit);
      } else if (WIFSIGNALED(chldstatus)) {  /* process died */
#ifndef HAVE_WIN32
         stat = WTERMSIG(chldstatus);
#else
         stat = 1;                    /* fake child status */
#endif
         Dmsg1(800, "Child died from signal %d\n", stat);
         stat |= b_errno_signal;      /* exit signal returned */
      }
   }
   if (bpipe->timer_id) {
      stop_child_timer(bpipe->timer_id);
   }
   free(bpipe);
   Dmsg2(800, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat);
   return stat;
}
Ejemplo n.º 27
0
int exec_str(struct sip_msg *msg, str* cmd, char *param, int param_len) {

	struct action act;
	int cmd_len;
	FILE *pipe;
	char *cmd_line;
	int ret;
	char uri_line[MAX_URI_SIZE+1];
	int uri_cnt;
	int uri_len;
	int exit_status;

	/* pessimist: assume error by default */
	ret=-1;

	cmd_len=cmd->len+param_len+2;
	cmd_line=pkg_malloc(cmd_len);
	if (cmd_line==0) {
		ret=ser_error=E_OUT_OF_MEM;
		LOG(L_ERR, "ERROR: exec_str: no mem for command\n");
		goto error00;
	}

	/* 'command parameter \0' */
	memcpy(cmd_line, cmd->s, cmd->len); cmd_line[cmd->len]=' ';
	memcpy(cmd_line+cmd->len+1, param, param_len);cmd_line[cmd->len+param_len+1]=0;

	pipe=popen( cmd_line, "r" );
	if (pipe==NULL) {
		LOG(L_ERR, "ERROR: exec_str: cannot open pipe: %s\n",
			cmd_line);
		ser_error=E_EXEC;
		goto error01;
	}

	/* read now line by line */
	uri_cnt=0;
	while( fgets(uri_line, MAX_URI_SIZE, pipe)!=NULL){
		uri_len=strlen(uri_line);
		/* trim from right */
		while(uri_len && (uri_line[uri_len-1]=='\r'
				|| uri_line[uri_len-1]=='\n'
				|| uri_line[uri_len-1]=='\t'
				|| uri_line[uri_len-1]==' ' )) {
			DBG("exec_str: rtrim\n");
			uri_len--;
		}
		/* skip empty line */
		if (uri_len==0) continue;
		/* ZT */
		uri_line[uri_len]=0;
		if (uri_cnt==0) {
			memset(&act, 0, sizeof(act));
			act.type = SET_URI_T;
			act.val[0].type = STRING_ST;
			act.val[0].u.string = uri_line;
			if (do_action(&act, msg)<0) {
				LOG(L_ERR,"ERROR:exec_str : SET_URI_T action failed\n");
				ser_error=E_OUT_OF_MEM;
				goto error02;
			}
		} else {
			if (append_branch(msg, uri_line, uri_len, 0, 0, Q_UNSPECIFIED, 0)==-1) {
				LOG(L_ERR, "ERROR: exec_str: append_branch failed;"
					" too many or too long URIs?\n");
				goto error02;
			}
		}
		uri_cnt++;
	}
	if (uri_cnt==0) {
		LOG(L_ERR, "ERROR:exec_str: no uri from %s\n", cmd_line );
		goto error02;
	}
	/* success */
	ret=1;

error02:
	if (ferror(pipe)) {
		LOG(L_ERR, "ERROR: exec_str: error in pipe: %s\n",
			strerror(errno));
		ser_error=E_EXEC;
		ret=-1;
	}
	exit_status=pclose(pipe);
	if (WIFEXITED(exit_status)) { /* exited properly .... */
		/* return false if script exited with non-zero status */
		if (WEXITSTATUS(exit_status)!=0) ret=-1;
	} else { /* exited erroneously */
		LOG(L_ERR, "ERROR: exec_str: cmd %.*s failed. "
			"exit_status=%d, errno=%d: %s\n",
			cmd->len, ZSW(cmd->s), exit_status, errno, strerror(errno) );
		ret=-1;
	}
error01:
	pkg_free(cmd_line);
error00:
	return ret;
}
Ejemplo n.º 28
0
static int recv_fd(int c)
{
    int fd;
    uint8_t msgbuf[CMSG_SPACE(sizeof(fd))];
    struct msghdr msg = {
        .msg_control = msgbuf,
        .msg_controllen = sizeof(msgbuf),
    };
    struct cmsghdr *cmsg;
    struct iovec iov;
    uint8_t req[1];
    ssize_t len;

    cmsg = CMSG_FIRSTHDR(&msg);
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
    msg.msg_controllen = cmsg->cmsg_len;

    iov.iov_base = req;
    iov.iov_len = sizeof(req);

    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;

    len = recvmsg(c, &msg, 0);
    if (len > 0) {
        memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
        return fd;
    }

    return len;
}

static int net_bridge_run_helper(const char *helper, const char *bridge)
{
    sigset_t oldmask, mask;
    int pid, status;
    char *args[5];
    char **parg;
    int sv[2];

    sigemptyset(&mask);
    sigaddset(&mask, SIGCHLD);
    sigprocmask(SIG_BLOCK, &mask, &oldmask);

    if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1) {
        return -1;
    }

    /* try to launch bridge helper */
    pid = fork();
    if (pid == 0) {
        int open_max = sysconf(_SC_OPEN_MAX), i;
        char fd_buf[6+10];
        char br_buf[6+IFNAMSIZ] = {0};
        char helper_cmd[PATH_MAX + sizeof(fd_buf) + sizeof(br_buf) + 15];

        for (i = 0; i < open_max; i++) {
            if (i != STDIN_FILENO &&
                i != STDOUT_FILENO &&
                i != STDERR_FILENO &&
                i != sv[1]) {
                close(i);
            }
        }

        snprintf(fd_buf, sizeof(fd_buf), "%s%d", "--fd=", sv[1]);

        if (strrchr(helper, ' ') || strrchr(helper, '\t')) {
            /* assume helper is a command */

            if (strstr(helper, "--br=") == NULL) {
                snprintf(br_buf, sizeof(br_buf), "%s%s", "--br=", bridge);
            }

            snprintf(helper_cmd, sizeof(helper_cmd), "%s %s %s %s",
                     helper, "--use-vnet", fd_buf, br_buf);

            parg = args;
            *parg++ = (char *)"sh";
            *parg++ = (char *)"-c";
            *parg++ = helper_cmd;
            *parg++ = NULL;

            execv("/bin/sh", args);
        } else {
            /* assume helper is just the executable path name */

            snprintf(br_buf, sizeof(br_buf), "%s%s", "--br=", bridge);

            parg = args;
            *parg++ = (char *)helper;
            *parg++ = (char *)"--use-vnet";
            *parg++ = fd_buf;
            *parg++ = br_buf;
            *parg++ = NULL;

            execv(helper, args);
        }
        _exit(1);

    } else if (pid > 0) {
        int fd;

        close(sv[1]);

        do {
            fd = recv_fd(sv[0]);
        } while (fd == -1 && errno == EINTR);

        close(sv[0]);

        while (waitpid(pid, &status, 0) != pid) {
            /* loop */
        }
        sigprocmask(SIG_SETMASK, &oldmask, NULL);
        if (fd < 0) {
            fprintf(stderr, "failed to recv file descriptor\n");
            return -1;
        }

        if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
            return fd;
        }
    }
    fprintf(stderr, "failed to launch bridge helper\n");
    return -1;
}
Ejemplo n.º 29
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;
}
Ejemplo n.º 30
-1
int
main(int argc, char *argv[])
{
	pid_t pid;
	int ch, status;
	struct timeval before, after;
	struct rusage ru;
	int exitonsig = 0;


	while ((ch = getopt(argc, argv, "lp")) != -1) {
		switch(ch) {
		case 'l':
			lflag = 1;
			break;
		case 'p':
			portableflag = 1;
			break;
		default:
			usage();
			/* NOTREACHED */
		}
	}

	argc -= optind;
	argv += optind;

	if (argc < 1)
		usage();

	gettimeofday(&before, (struct timezone *)NULL);
	switch(pid = vfork()) {
	case -1:			/* error */
		perror("time");
		exit(1);
		/* NOTREACHED */
	case 0:				/* child */
		execvp(*argv, argv);
		perror(*argv);
		_exit((errno == ENOENT) ? 127 : 126);
		/* NOTREACHED */
	}

	/* parent */
	(void)signal(SIGINT, SIG_IGN);
	(void)signal(SIGQUIT, SIG_IGN);
	while (wait3(&status, 0, &ru) != pid)
		;
	gettimeofday(&after, (struct timezone *)NULL);
	if (WIFSIGNALED(status))
		exitonsig = WTERMSIG(status);
	if (!WIFEXITED(status))
		fprintf(stderr, "Command terminated abnormally.\n");
	timersub(&after, &before, &after);

	if (portableflag) {
		fprintf(stderr, "real %9ld.%02ld\n",
			after.tv_sec, after.tv_usec/10000);
		fprintf(stderr, "user %9ld.%02ld\n",
			ru.ru_utime.tv_sec, ru.ru_utime.tv_usec/10000);
		fprintf(stderr, "sys  %9ld.%02ld\n",
			ru.ru_stime.tv_sec, ru.ru_stime.tv_usec/10000);
	} else {

		fprintf(stderr, "%9ld.%02ld real ",
			after.tv_sec, after.tv_usec/10000);
		fprintf(stderr, "%9ld.%02ld user ",
			ru.ru_utime.tv_sec, ru.ru_utime.tv_usec/10000);
		fprintf(stderr, "%9ld.%02ld sys\n",
			ru.ru_stime.tv_sec, ru.ru_stime.tv_usec/10000);
	}

	if (lflag) {
		int hz;
		long ticks;
		int mib[2];
		struct clockinfo clkinfo;
		size_t size;

		mib[0] = CTL_KERN;
		mib[1] = KERN_CLOCKRATE;
		size = sizeof(clkinfo);
		if (sysctl(mib, 2, &clkinfo, &size, NULL, 0) < 0)
			err(1, "sysctl");

		hz = clkinfo.hz;

		ticks = hz * (ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) +
		     hz * (ru.ru_utime.tv_usec + ru.ru_stime.tv_usec) / 1000000;

		fprintf(stderr, "%10ld  %s\n",
			ru.ru_maxrss, "maximum resident set size");
		fprintf(stderr, "%10ld  %s\n", ticks ? ru.ru_ixrss / ticks : 0,
			"average shared memory size");
		fprintf(stderr, "%10ld  %s\n", ticks ? ru.ru_idrss / ticks : 0,
			"average unshared data size");
		fprintf(stderr, "%10ld  %s\n", ticks ? ru.ru_isrss / ticks : 0,
			"average unshared stack size");
		fprintf(stderr, "%10ld  %s\n",
			ru.ru_minflt, "minor page faults");
		fprintf(stderr, "%10ld  %s\n",
			ru.ru_majflt, "major page faults");
		fprintf(stderr, "%10ld  %s\n",
			ru.ru_nswap, "swaps");
		fprintf(stderr, "%10ld  %s\n",
			ru.ru_inblock, "block input operations");
		fprintf(stderr, "%10ld  %s\n",
			ru.ru_oublock, "block output operations");
		fprintf(stderr, "%10ld  %s\n",
			ru.ru_msgsnd, "messages sent");
		fprintf(stderr, "%10ld  %s\n",
			ru.ru_msgrcv, "messages received");
		fprintf(stderr, "%10ld  %s\n",
			ru.ru_nsignals, "signals received");
		fprintf(stderr, "%10ld  %s\n",
			ru.ru_nvcsw, "voluntary context switches");
		fprintf(stderr, "%10ld  %s\n",
			ru.ru_nivcsw, "involuntary context switches");
	}

	if (exitonsig) {
		if (signal(exitonsig, SIG_DFL) == SIG_ERR)
			perror("signal");
		else
			kill(getpid(), exitonsig);
	}
	exit(WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE);
}