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; } }
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); }
// // 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; } }
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(); } } } }
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; }
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, ®s ) == -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; }
// // 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(); }
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 */ }
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; }
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 */ }
inline OS_systemwide_thread_id_t get_invalid_systemwide_thread_id() { return OS_systemwide_thread_id_t(pid_t(0), get_invalid_thread_id()); }
static pid_t gettid() { return pid_t(GetCurrentThreadId()); }
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); }
pid_t sched_fork() { pid_t (*call)(); call = (void *) _SCHED_FORK; return call(); }
pid_t getpid() { return pid_t(GetCurrentProcessId()); }
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 }