📄 unixprocess.cpp
字号:
//// This file is part of the "More for C++" library//// Copyright (c) 1999-2003 by Thorsten Goertz (thorsten@morefor.org)//// The "More for C++" library is free software; you can redistribute it and/or// modify it under the terms of the license that comes with this package.//// Read "license.txt" for more details.//// THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES// OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.////////////////////////////////////////////////////////////////////////////////#include <errno.h>#include <more/create.hpp>#include <more/synchronized.hpp>#include <more/os/thread.hpp>#include <signal.h>#include <unistd.h>#include <sys/wait.h>#include "unixprocess.hpp"using namespace more;using namespace more::os;using namespace more::os::unix_;using namespace more::util;////////////////////////////////////////////////////////////////////////////////size_t UnixProcess::getId( ){ return getpid( );}////////////////////////////////////////////////////////////////////////////////void UnixProcess::setSigIntHandler( const p<SignalHandler>& pSignalHandler){ CREATE SigIntHandler( pSignalHandler ); signal( SIGINT, UnixProcess::sigIntHandler );}////////////////////////////////////////////////////////////////////////////////UnixProcess::UnixProcess( const p<File>& pBinary): m_pMutex( Mutex::create( ) ), m_pBinary( pBinary ), m_nProcessId( -1 ){}////////////////////////////////////////////////////////////////////////////////void UnixProcess::execute( const Array<String>& sArgV) throw( more::io::IOException ){ static bool bSigChldHandlerInstalled = false; if( !bSigChldHandlerInstalled ) { bSigChldHandlerInstalled = true; signal( SIGCHLD, UnixProcess::sigChldHandler ); } synchronized( m_pMutex ) { if( !m_pBinary -> exists( ) ) { throw more::io::IOException( -1, "Binary does not exist" ); } if( m_nProcessId > 0 ) { throw more::io::IOException( -1, "Process already executing" ); } m_nProcessId = fork( ); if( m_nProcessId < 0 ) { throw more::io::IOException( -1, "fork( ) failed (errno: " + String::from( errno ) + ")" ); } else if( m_nProcessId == 0 ) { // fork( ) returned 0 so this is executed in a forked copy // of the parent process. The call of "execvp(...)" will // replace the child process with the specified binary. String sBinary = m_pBinary -> getDescriptor( ) -> getFullName( ); const char** pcArgV = new const char*[sArgV.getLength( ) + 2]; pcArgV[0] = sBinary; for( size_t i = 0; i < sArgV.getLength( ); i++ ) { pcArgV[i + 1] = sArgV[i]; } pcArgV[sArgV.getLength( ) + 1] = 0; execvp( sBinary, ( char* const* ) pcArgV ); } } end_synchronized}////////////////////////////////////////////////////////////////////////////////void UnixProcess::terminate( ){ synchronized( m_pMutex ) { if( m_nProcessId > 0 ) { if( kill( m_nProcessId, SIGTERM ) == -1 ) { throw more::io::IOException( errno, "kill( " + String::from( m_nProcessId ) + " ) failed (errno: " + String::from( errno ) + ")" ); } } } end_synchronized}////////////////////////////////////////////////////////////////////////////////void UnixProcess::join( ){ pid_t nProcessId = -1; synchronized( m_pMutex ) { if( m_nProcessId > 0 ) { nProcessId = m_nProcessId; } } end_synchronized // Make a context switch and give the kernel // a chance to get the process properly started Thread::sleep( 100 ); if( nProcessId > 0 ) { int nWaitResult = waitpid( nProcessId, 0, 0 ); synchronized( m_pMutex ) { m_nProcessId = -1; } end_synchronized // if errno is ECHILD, we assume that the sigChldHandler // handled wait properly if( nWaitResult != nProcessId && errno != ECHILD ) { throw more::io::IOException( errno, "waitpid( " + String::from( nProcessId ) + ", 0, 0 ) failed (errno: " + String::from( errno ) + ")" ); } }}////////////////////////////////////////////////////////////////////////////////UnixProcess::SigIntHandler::SigIntHandler( const p<SignalHandler>& pSignalHandler): m_pMutex( Mutex::create( ) ), m_pSignalHandler( pSignalHandler ){ Singleton<SigIntHandler>::setInstance( this );}////////////////////////////////////////////////////////////////////////////////void UnixProcess::SigIntHandler::handleSignal( ){ if( m_pSignalHandler != 0 ) { synchronized( m_pMutex ) { if( m_pSignalHandler != 0 ) { try { m_pSignalHandler -> onSignal( ); } catch( ... ) { } m_pSignalHandler = 0; } } end_synchronized }}////////////////////////////////////////////////////////////////////////////////void UnixProcess::sigChldHandler( int // nMask){ wait( 0 );}////////////////////////////////////////////////////////////////////////////////void UnixProcess::sigIntHandler( int // nMask){ Singleton<SigIntHandler>::getInstance( ) -> handleSignal( );}////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -