* @brief POSIX (mkfifo + poll) implementation of the named-pipe read loop. */
| 640 | * @brief POSIX (mkfifo + poll) implementation of the named-pipe read loop. |
| 641 | */ |
| 642 | void IO::Drivers::Process::pipeReadLoopPosix() |
| 643 | { |
| 644 | #ifndef Q_OS_WIN |
| 645 | const QByteArray pathBytes = m_pipePath.toLocal8Bit(); |
| 646 | struct stat st{}; |
| 647 | const bool exists = (::stat(pathBytes.constData(), &st) == 0); |
| 648 | if (!exists) |
| 649 | ::mkfifo(pathBytes.constData(), 0600); |
| 650 | else if (!S_ISFIFO(st.st_mode)) { |
| 651 | QMetaObject::invokeMethod(this, "onPipeError", Qt::QueuedConnection); |
| 652 | return; |
| 653 | } |
| 654 | |
| 655 | const int fd = ::open(pathBytes.constData(), O_RDONLY | O_NONBLOCK); |
| 656 | if (fd < 0) { |
| 657 | QMetaObject::invokeMethod(this, "onPipeError", Qt::QueuedConnection); |
| 658 | return; |
| 659 | } |
| 660 | |
| 661 | char buf[4096]; |
| 662 | struct pollfd pfd{}; |
| 663 | pfd.fd = fd; |
| 664 | pfd.events = POLLIN; |
| 665 | |
| 666 | while (m_pipeRunning.load()) { |
| 667 | const int rc = ::poll(&pfd, 1, 100); |
| 668 | if (rc <= 0) |
| 669 | continue; |
| 670 | |
| 671 | if (!(pfd.revents & POLLIN)) { |
| 672 | if (pfd.revents & (POLLERR | POLLNVAL)) |
| 673 | break; |
| 674 | |
| 675 | continue; |
| 676 | } |
| 677 | |
| 678 | const ssize_t n = ::read(fd, buf, sizeof(buf)); |
| 679 | if (n < 0) |
| 680 | break; |
| 681 | |
| 682 | if (n == 0) { |
| 683 | if (pfd.revents & POLLHUP) |
| 684 | break; |
| 685 | |
| 686 | continue; |
| 687 | } |
| 688 | |
| 689 | publishReceivedData(QByteArray(buf, static_cast<int>(n))); |
| 690 | } |
| 691 | |
| 692 | ::close(fd); |
| 693 | #endif |
| 694 | } |
| 695 | |
| 696 | //-------------------------------------------------------------------------------------------------- |
| 697 | // Private: executable helper |