Пример #1
0
bool Exec::Impl::createchild (const std::string & strCommand)
{
	TRF;

	// If any previous child exist, kill it.
	killchild ();

	int handle [2];
	if (pipe (handle) != 0)
	{
		TRDEB ("Error en pipe");
		return false;
	}

	pid_t child= vfork ();
	switch (child)
	{
	case pid_t (0):
		// Child
		close (handle [0] );
		dup2 (handle [1], STDOUT_FILENO);
		dup2 (handle [1], STDERR_FILENO);
		close (handle [1] );
		{
			const char * strShell;
			strShell= getenv ("SHELL");
			if (! strShell)
				strShell= "/bin/sh";
			execlp (strShell, strShell,
				"-c", strCommand.c_str (),
				static_cast <const char *> (0) );
		}
		TRDEB ("Error en execlp");
		exit (1);
		return false;
	case pid_t (-1):
		// Error
		TRDEB ("Error en fork");
		close (handle [0] );
		close (handle [1] );
		return false;
	default:
		hchild= handle [0];
		close (handle [1] );
		pidchild= child;
		return true;
	}
}
Пример #2
0
static int
kt_dump_contains_proc(mdb_tgt_t *t, void *context)
{
	kt_data_t *kt = t->t_data;
	pid_t (*f_pid)(uintptr_t);
	pid_t reqpid;

	switch (kt->k_dumpcontent) {
	case KT_DUMPCONTENT_KERNEL:
		return (0);
	case KT_DUMPCONTENT_ALL:
		return (1);
	case KT_DUMPCONTENT_INVALID:
		goto procnotfound;
	default:
		f_pid = (pid_t (*)()) dlsym(RTLD_NEXT, "mdb_kproc_pid");
		if (f_pid == NULL)
			goto procnotfound;

		reqpid = f_pid((uintptr_t)context);
		if (reqpid == -1)
			goto procnotfound;

		return (kt->k_dumpcontent == reqpid);
	}

procnotfound:
	warn("unable to determine whether dump contains proc %p\n", context);
	return (1);
}
Пример #3
0
//
// Check the status of this child by explicitly probing it.
// Caller must hold master lock.
//
bool Child::checkStatus(int options)
{
	assert(state() == alive);
	secdebug("unixchild", "checking %p (pid %d)", this, this->pid());
	int status;
  again:
	switch (IFDEBUG(pid_t pid =) ::wait4(this->pid(), &status, options, NULL)) {
	case pid_t(-1):
		switch (errno) {
		case EINTR:
			goto again;		// retry
		case ECHILD:
			secdebug("unixchild", "%p (pid=%d) unknown to kernel", this, this->pid());
			mState = invalid;
			mChildren().erase(this->pid());
			return false;
		default:
			UnixError::throwMe();
		}
		break;	// placebo
	case 0:
		return false;	// child not ready (do nothing)
	default:
		assert(pid == this->pid());
		bury(status);
		return true;
	}
}
Пример #4
0
void process::collect_zombies( void )
{
	while ( true )
	{
		int status = 0;
		int ret = ::wait( &status );
		if ( ret == -1 )
		{
			if ( errno == EINTR )
				continue;
			if ( errno == ECHILD )
			{
				std::unique_lock<std::mutex> lock( the_mutex );
				if ( the_processes.empty() )
					return;
				else
					break;
			}
			throw_errno( "waiting on child processes" );
		}
		else
		{
			std::unique_lock<std::mutex> lock( the_mutex );
			auto i = the_processes.find( pid_t(ret) );
			if ( i != the_processes.end() )
			{
				i->second->update_status( status );
				the_processes.erase( i );
				the_condition.notify_all();
			}
		}
	}
}
Пример #5
0
  inline int system_cmd(const std::string& cmd, const Argv& argv)
  {
    int ret = -1;
    ArgvWrapper argv_wrap(argv);
    const pid_t pid = fork();
    if (pid == pid_t(0)) /* child side */
      {
	execve(cmd.c_str(), argv_wrap.c_argv(), environ);
	exit(127);
      }
    else if (pid < pid_t(0)) /* fork failed */
      ;
    else /* parent side */
      {
	if (waitpid(pid, &ret, 0) != pid)
	  ret = -1;
      }
    return ret;
  }
Пример #6
0
bool GetThreadBacktraceContext( uint64_t ThreadID, BacktraceContext *ctx )
{
	/* Can't GetThreadBacktraceContext the current thread. */
	ASSERT( ThreadID != GetCurrentThreadId() );

	/* Attach to the thread.  This may fail with EPERM.  This can happen for at least
	 * two common reasons: the process might be in a debugger already, or *we* might
	 * already have attached to it via SuspendThread.
	 *
	 * If it's in a debugger, we won't be able to ptrace(PTRACE_GETREGS). If
	 * it's us that attached, we will. */
	if( PtraceAttach( int(ThreadID) ) == -1 )
	{
		if( errno != EPERM )
		{
			CHECKPOINT_M( ssprintf( "%s (pid %i tid %i locking tid %i)",
									strerror(errno), getpid(), (int)GetCurrentThreadId(), int(ThreadID) ) );
			return false;
		}
	}

	user_regs_struct regs;
	if( ptrace( PTRACE_GETREGS, pid_t(ThreadID), NULL, &regs ) == -1 )
		return false;

	ctx->pid = pid_t(ThreadID);
#if defined(CPU_X86_64)
	ctx->ip = (void *) regs.rip;
	ctx->bp = (void *) regs.rbp;
	ctx->sp = (void *) regs.rsp;
#elif defined(CPU_X86)
	ctx->ip = (void *) regs.eip;
	ctx->bp = (void *) regs.ebp;
	ctx->sp = (void *) regs.esp;
#else
#error GetThreadBacktraceContext: which arch?
#endif

	return true;
}
Пример #7
0
//
// Perform an idempotent check for dead children, as per the UNIX wait() system calls.
// This can be called at any time, and will reap all children that have died since
// last time. The obvious time to call this is after a SIGCHLD has been received;
// however signal dispatch is so - uh, interesting - in UNIX that we don't even try
// to deal with it at this level. Suffice to say that calling checkChildren directly
// from within a signal handler is NOT generally safe due to locking constraints.
//
// If the shared() flag is on, we explicitly poll each child known to be recently
// alive. That is less efficient than reaping any and all, but leaves any children
// alone that someone else may have created without our knowledge. The default is
// not shared(), which will reap (and discard) any unrelated children without letting
// the caller know about it.
//
void Child::checkChildren()
{
	Bier casualties;
	{
		StLock<Mutex> _(mChildren());
		if (mChildren().shared) {
			for (Children::iterator it = mChildren().begin(); it != mChildren().end(); it++)
				if (it->second->checkStatus(WNOHANG))
					casualties.add(it->second);
		} else if (!mChildren().empty()) {
			int status;
			while (pid_t pid = ::wait4(0, &status, WNOHANG, NULL)) {
				secdebug("unixchild", "universal child check (%ld children known alive)", mChildren().size());
				switch (pid) {
				case pid_t(-1):
					switch (errno) {
					case EINTR:
						secdebug("unixchild", "EINTR on wait4; retrying");
						continue;	// benign, but retry the wait()
					case ECHILD:
						// Should not normally happen (there *is* a child around),
						// but gets returned anyway if the child is stopped in the debugger.
						// Treat like a zero return (no children ready to be buried).
						secdebug("unixchild", "ECHILD with filled nursery (ignored)");
						goto no_more;
					default:
						UnixError::throwMe();
					}
					break;
				default:
					if (Child *child = mChildren()[pid]) {
						child->bury(status);
						casualties.add(child);
					} else
						secdebug("unixchild", "reaping feral child pid=%d", pid);
					if (mChildren().empty())
						goto no_more;	// none left
					break;
				}
			}
		  no_more: ;
		} else {
			secdebug("unixchild", "spurious checkChildren (the nursery is empty)");
		}
	}	// release master lock
	casualties.notify();
}
Пример #8
0
pid_t
ACE_OS::fork (const ACE_TCHAR *program_name)
{
  ACE_OS_TRACE ("ACE_OS::fork");
# if defined (ACE_LACKS_FORK)
  ACE_UNUSED_ARG (program_name);
  ACE_NOTSUP_RETURN (pid_t (-1));
# else
  pid_t const pid =
# if defined (ACE_HAS_STHREADS)
    ::fork1 ();
#else
    ::fork ();
#endif /* ACE_HAS_STHREADS */

#if !defined (ACE_HAS_MINIMAL_ACE_OS) && !defined (ACE_HAS_THREADS)

  // ACE_Base_Thread_Adapter::sync_log_msg() is used to update the
  // program name and process id in ACE's log framework.  However, we
  // can't invoke it from (the child process of) threaded programs
  // because it calls async signal unsafe functions, which will result
  // in undefined behavior (only async signal safe functions can be
  // called after fork() until an exec()).
  //
  // This is no great loss.  Using the ACE log framework in the child
  // process will undoubtedly call async signal unsafe functions too.
  // So it doesn't really matter that the program name and process id
  // will not be updated.

  if (pid == 0)
    ACE_Base_Thread_Adapter::sync_log_msg (program_name);

#else

  ACE_UNUSED_ARG (program_name);

#endif /* ! ACE_HAS_MINIMAL_ACE_OS && !ACE_HAS_THREADS */

  return pid;
# endif /* ACE_WIN32 */
}
Пример #9
0
pid_t pn2pid(string pn_s) {
	string dir = "/proc";
	string cmd;
	string pn;
	vector<string> files;
    DIR *dp;
    struct dirent *dirp;
    if((dp  = opendir(dir.c_str())) == NULL) {
		log2("Error %d opening %s\n", errno, dir.c_str());
		return 0;
    }
    while ((dirp = readdir(dp)) != NULL) {
		pn = dirp->d_name;
		if (!is_number(pn)) continue;
        files.push_back(pn);
		cmd = read_file(dir+"/"+pn+"/cmdline");
		if (cmd.find(pn_s) != string::npos && cmd.find(pn_s) <= 2) return pid_t(atoi(pn.c_str()));
    }
    closedir(dp);
	log("'%s' is not running\n", pn_s.c_str());
	return 0;
}
Пример #10
0
pid_t
ACE_OS::fork (const ACE_TCHAR *program_name)
{
  ACE_OS_TRACE ("ACE_OS::fork");
# if defined (ACE_LACKS_FORK)
  ACE_UNUSED_ARG (program_name);
  ACE_NOTSUP_RETURN (pid_t (-1));
# else
  pid_t pid =
# if defined (ACE_HAS_STHREADS)
    ::fork1 ();
#else
    ::fork ();
#endif /* ACE_HAS_STHREADS */

#if !defined (ACE_HAS_MINIMAL_ACE_OS)
  if (pid == 0)
    ACE_Base_Thread_Adapter::sync_log_msg (program_name);
#endif /* ! ACE_HAS_MINIMAL_ACE_OS */

  return pid;
# endif /* ACE_WIN32 */
}
Пример #11
0
inline OS_systemwide_thread_id_t get_invalid_systemwide_thread_id()
{
   return OS_systemwide_thread_id_t(pid_t(0), get_invalid_thread_id());
}
Пример #12
0
static pid_t gettid() {
  return pid_t(GetCurrentThreadId());
}
Пример #13
0
bool AkVCam::PluginInterface::createDevice(const std::string &deviceId,
                                           const std::wstring &description,
                                           const std::vector<VideoFormat> &formats)
{
    AkLoggerLog("AkVCam::PluginInterface::createDevice");

    StreamPtr stream;

    // Create one device.
    auto pluginRef = reinterpret_cast<CMIOHardwarePlugInRef>(this->d);
    auto device = std::make_shared<Device>(pluginRef);
    device->setDeviceId(deviceId);
    device->connectAddListener(this, &PluginInterface::addListener);
    device->connectRemoveListener(this, &PluginInterface::removeListener);
    this->m_devices.push_back(device);

    // Define device properties.
    device->properties().setProperty(kCMIOObjectPropertyName,
                                     description.c_str());
    device->properties().setProperty(kCMIOObjectPropertyManufacturer,
                                     CMIO_PLUGIN_VENDOR);
    device->properties().setProperty(kCMIODevicePropertyModelUID,
                                     CMIO_PLUGIN_PRODUCT);
    device->properties().setProperty(kCMIODevicePropertyLinkedCoreAudioDeviceUID,
                                     "");
    device->properties().setProperty(kCMIODevicePropertyLinkedAndSyncedCoreAudioDeviceUID,
                                     "");
    device->properties().setProperty(kCMIODevicePropertySuspendedByUser,
                                     UInt32(0));
    device->properties().setProperty(kCMIODevicePropertyHogMode,
                                     pid_t(-1),
                                     false);
    device->properties().setProperty(kCMIODevicePropertyDeviceMaster,
                                     pid_t(-1));
    device->properties().setProperty(kCMIODevicePropertyExcludeNonDALAccess,
                                     UInt32(0));
    device->properties().setProperty(kCMIODevicePropertyDeviceIsAlive,
                                     UInt32(1));
    device->properties().setProperty(kCMIODevicePropertyDeviceUID,
                                     deviceId.c_str());
    device->properties().setProperty(kCMIODevicePropertyTransportType,
                                     UInt32(kIOAudioDeviceTransportTypePCI));
    device->properties().setProperty(kCMIODevicePropertyDeviceIsRunningSomewhere,
                                     UInt32(0));

    if (device->createObject() != kCMIOHardwareNoError)
        goto createDevice_failed;

    stream = device->addStream();

    // Register one stream for this device.
    if (!stream)
        goto createDevice_failed;

    stream->setFormats(formats);
    stream->properties().setProperty(kCMIOStreamPropertyDirection, UInt32(0));

    if (device->registerStreams() != kCMIOHardwareNoError) {
        device->registerStreams(false);

        goto createDevice_failed;
    }

    // Register the device.
    if (device->registerObject() != kCMIOHardwareNoError) {
        device->registerObject(false);
        device->registerStreams(false);

        goto createDevice_failed;
    }

    device->setBroadcasting(this->d->m_ipcBridge.broadcaster(deviceId));
    device->setMirror(this->d->m_ipcBridge.isHorizontalMirrored(deviceId),
                      this->d->m_ipcBridge.isVerticalMirrored(deviceId));
    device->setScaling(this->d->m_ipcBridge.scalingMode(deviceId));
    device->setAspectRatio(this->d->m_ipcBridge.aspectRatioMode(deviceId));
    device->setSwapRgb(this->d->m_ipcBridge.swapRgb(deviceId));

    return true;

createDevice_failed:
    this->m_devices.erase(std::prev(this->m_devices.end()));

    return false;
}
inline OS_process_id_t get_invalid_process_id()
{  return pid_t(0);  }
Пример #15
0
pid_t sched_fork()
{
	pid_t (*call)();
	call = (void *) _SCHED_FORK;
	return call();
}
Пример #16
0
pid_t getpid() { return pid_t(GetCurrentProcessId()); }
Пример #17
0
PreProcessFilter::PreProcessFilter(const string& filterCommand)
    : m_toFilter(NULL),
      m_fromFilter(NULL)
{
    // Child error signal install
    // sigaction is the replacement for the traditional signal() method

#if (!defined(WIN32) && !defined(WIN64))
    struct sigaction action;
    action.sa_handler = exec_failed;
    sigemptyset(&action.sa_mask);
    action.sa_flags = 0;
    if (sigaction(SIGUSR1, &action, NULL) < 0)
    {
        perror("SIGUSR1 install error");
        exit(EXIT_FAILURE);
    }

    int pipe_status;
    int pipefds_input[2];
    int pipefds_output[2];
    // int pipefds_error[2];

    // Create the pipes
    // We do this before the fork so both processes will know about
    // the same pipe and they can communicate.
#ifdef _MSC_VER
    pipe_status = _pipe(pipefds_input);
#else    
    pipe_status = pipe(pipefds_input);
#endif
    if (pipe_status == -1)
    {
        perror("Error creating the pipe");
        exit(EXIT_FAILURE);
    }

    pipe_status = pipe(pipefds_output);
    if (pipe_status == -1)
    {
        perror("Error creating the pipe");
        exit(EXIT_FAILURE);
    }

    /*
    pipe_status = pipe(pipefds_error);
    if (pipe_status == -1)
    {
        perror("Error creating the pipe");
        exit(EXIT_FAILURE);
    }
    */

    pid_t pid;
    // Create child process; both processes continue from here
    pid = fork();

    if (pid == pid_t(0))
    {
        // Child process

        // When the child process finishes sends a SIGCHLD signal
        // to the parent

        // Tie the standard input, output and error streams to the
        // appropiate pipe ends
        // The file descriptor 0 is the standard input
        // We tie it to the read end of the pipe as we will use
        // this end of the pipe to read from it
        dup2 (CHILD_STDIN_READ,0);
        dup2 (CHILD_STDOUT_WRITE,1);
        // dup2 (CHILD_STDERR_WRITE,2);
        // Close in the child the unused ends of the pipes
        close(CHILD_STDIN_WRITE);
        close(CHILD_STDOUT_READ);
        //close(CHILD_STDERR_READ);

        // Execute the program
        execl("/bin/bash", "bash", "-c", filterCommand.c_str() , (char*)NULL);

        // We should never reach this point
        // Tell the parent the exec failed
        kill(getppid(), SIGUSR1);
        exit(EXIT_FAILURE);
    }
    else if (pid > pid_t(0))
    {
        // Parent

        // Close in the parent the unused ends of the pipes
        close(CHILD_STDIN_READ);
        close(CHILD_STDOUT_WRITE);
        // close(CHILD_STDERR_WRITE);

        m_toFilter = new ofdstream(CHILD_STDIN_WRITE);
        m_fromFilter = new ifdstream(CHILD_STDOUT_READ);
    }
    else
    {
        perror("Error: fork failed");
        exit(EXIT_FAILURE);
    }
#else
	std::cerr << "Unsupported on Windows platform (PreProcessFilter)" << std::endl;
#endif
}