| 169 | } |
| 170 | |
| 171 | std::unique_ptr<Process> |
| 172 | Process::createWithPseudoTerminal( const std::string& program, const std::vector<std::string>& args, |
| 173 | const std::string& workingDirectory, |
| 174 | Terminal::PseudoTerminal& pseudoTerminal, |
| 175 | const std::unordered_map<std::string, std::string>& env ) { |
| 176 | int pid = fork(); |
| 177 | if ( pid == -1 ) { |
| 178 | fprintf( stderr, "Failed to fork process\n" ); |
| 179 | return nullptr; |
| 180 | } else if ( pid == 0 ) { |
| 181 | setsid(); |
| 182 | dup2( (int)pseudoTerminal.mSlave, 0 ); |
| 183 | dup2( (int)pseudoTerminal.mSlave, 1 ); |
| 184 | dup2( (int)pseudoTerminal.mSlave, 2 ); |
| 185 | |
| 186 | if ( ioctl( (int)pseudoTerminal.mSlave, TIOCSCTTY, NULL ) < 0 ) { |
| 187 | fprintf( stderr, "ioctl TIOCSCTTY failed: %s", strerror( errno ) ); |
| 188 | exit( 1 ); |
| 189 | } |
| 190 | |
| 191 | if ( (int)pseudoTerminal.mSlave > 2 ) |
| 192 | close( (int)pseudoTerminal.mSlave ); |
| 193 | |
| 194 | #ifdef __OpenBSD__ |
| 195 | if ( pledge( "stdio getpw proc exec", NULL ) == -1 ) { |
| 196 | fprintf( stderr, "pledge\n" ); |
| 197 | exit( 1 ); |
| 198 | } |
| 199 | #endif |
| 200 | std::vector<const char*> argsV; |
| 201 | argsV.push_back( program.c_str() ); |
| 202 | for ( auto& a : args ) { |
| 203 | argsV.push_back( a.c_str() ); |
| 204 | } |
| 205 | argsV.push_back( nullptr ); |
| 206 | execshell( program.c_str(), argsV.data(), workingDirectory, env ); |
| 207 | } else { |
| 208 | pseudoTerminal.mSlave.release(); |
| 209 | return std::unique_ptr<Process>( new Process( pid ) ); |
| 210 | } |
| 211 | return nullptr; |
| 212 | } |
| 213 | |
| 214 | }} // namespace eterm::System |
| 215 |
no test coverage detected