| 335 | } |
| 336 | |
| 337 | unsigned int ProcessExecutor::check() |
| 338 | { |
| 339 | unsigned int fileCount = 0; |
| 340 | unsigned int result = 0; |
| 341 | |
| 342 | const std::size_t totalfilesize = std::accumulate(mFiles.cbegin(), mFiles.cend(), std::size_t(0), [](std::size_t v, const FileWithDetails& p) { |
| 343 | return v + p.size(); |
| 344 | }); |
| 345 | |
| 346 | // pass unmodified suppressions to forked process so we only transfer back the actual changes done by the fork |
| 347 | // and do not see the changes which have already been transferred back |
| 348 | Suppressions supprs; |
| 349 | supprs.nomsg.addSuppressions(mSuppressions.nomsg.getSuppressions()); |
| 350 | supprs.nofail.addSuppressions(mSuppressions.nofail.getSuppressions()); |
| 351 | |
| 352 | std::list<int> rpipes; |
| 353 | std::map<pid_t, std::string> childFile; |
| 354 | std::map<int, std::string> pipeFile; |
| 355 | std::size_t processedsize = 0; |
| 356 | auto iFile = mFiles.cbegin(); |
| 357 | auto iFileSettings = mFileSettings.cbegin(); |
| 358 | for (;;) { |
| 359 | // Start a new child |
| 360 | const size_t nchildren = childFile.size(); |
| 361 | if ((iFile != mFiles.cend() || iFileSettings != mFileSettings.cend()) && nchildren < mSettings.jobs && checkLoadAverage(nchildren)) { |
| 362 | int pipes[2]; |
| 363 | if (pipe(pipes) == -1) { |
| 364 | std::cerr << "#### ThreadExecutor::check, pipe() failed: "<< std::strerror(errno) << std::endl; |
| 365 | std::exit(EXIT_FAILURE); |
| 366 | } |
| 367 | |
| 368 | const int flags = fcntl(pipes[0], F_GETFL, 0); |
| 369 | if (flags < 0) { |
| 370 | std::cerr << "#### ThreadExecutor::check, fcntl(F_GETFL) failed: "<< std::strerror(errno) << std::endl; |
| 371 | std::exit(EXIT_FAILURE); |
| 372 | } |
| 373 | |
| 374 | if (fcntl(pipes[0], F_SETFL, flags) < 0) { |
| 375 | std::cerr << "#### ThreadExecutor::check, fcntl(F_SETFL) failed: "<< std::strerror(errno) << std::endl; |
| 376 | std::exit(EXIT_FAILURE); |
| 377 | } |
| 378 | |
| 379 | const pid_t pid = fork(); |
| 380 | if (pid < 0) { |
| 381 | // Error |
| 382 | std::cerr << "#### ThreadExecutor::check, Failed to create child process: "<< std::strerror(errno) << std::endl; |
| 383 | std::exit(EXIT_FAILURE); |
| 384 | } else if (pid == 0) { |
| 385 | #if defined(__linux__) |
| 386 | prctl(PR_SET_PDEATHSIG, SIGHUP); |
| 387 | #endif |
| 388 | close(pipes[0]); |
| 389 | |
| 390 | // create a separate result object so we do not get the results which have already been transferred back |
| 391 | std::unique_ptr<TimerResults> timerResults; |
| 392 | if (mTimerResults) |
| 393 | timerResults.reset(new TimerResults); |
| 394 |
nothing calls this directly
no test coverage detected