Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-1787

Wait() issue, SIGCHLD signal handler registered in QCoreApplication object creation without SA_RESTART

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P3: Somewhat important
    • Some future release
    • 4.4.0, 5.3.0
    • Core: Threads
    • None

    Description

      With Qt on Mac,

      With the following code:

      #include <QCoreApplication>
      #include <sys/types.h>
      #include <sys/wait.h>
      #include <errno.h>
      
      int main(int argc, char *argv[])
      {
        QCoreApplication a(argc, argv);
      
        pid_t nChildPid = fork();
        if (!nChildPid)
          sleep(5);
        else
        {
          int status = 0;
          pid_t nWaitedPid = wait(&status);
          if (nWaitedPid == -1)
            printf("An error %d occured on wait() system call\n", errno);
          else
            printf("System call wait() exited successfully\n");
        }
      
        return 0;
      }
      

      If we compile this code under Mac OS X (for example under 10.4.11 version; under 10.5.x issue is also reproducing)
      and execute it, then the following result will be received:

      $ ./test.app/Contents/MacOS/test
      An error 4 occured on wait() system call

      In other words execution of wait() system call fails with EINTR system error code. If commenting line with QCoreApplication
      object then all be fine. It is likely that some SIGCHLD signal handler registering on QCoreApplication object creation without SA_RESTART flag.
      Because follow workaround eliminating issue:

      #include <QCoreApplication>
      #include <sys/types.h>
      #include <sys/wait.h>
      #include <errno.h>
      #include <signal.h>
      
      int main(int argc, char *argv[])
      {
        QCoreApplication a(argc, argv);
      
      //Workaround
      //***********************************************
          struct sigaction _def_handler;
          struct sigaction _prev_handler;
          _def_handler.sa_handler = SIG_DFL;
          _def_handler.sa_flags = 0;
      
          int ret = sigaction(SIGCHLD, &_def_handler, &_prev_handler);
          if (ret == -1)
          {
              printf("An error %d occured on sigaction() system call\n", errno);
              return (-1);
          }
          _prev_handler.sa_flags |= SA_RESTART;
          ret = sigaction(SIGCHLD, &_prev_handler, NULL);
          if (ret == -1)
          {
              printf("An error %d occured on sigaction() system call\n", errno);
              return (-1);
          }
      //***********************************************
      
        pid_t nChildPid = fork();
        if (!nChildPid)
          sleep(5);
        else
        {
          int status = 0;
          pid_t nWaitedPid = wait(&status);
          if (nWaitedPid == -1)
            printf("An error %d occured on wait() system call\n", errno);
              else
                  printf("wait() system call performed successfully\n");
        }
      
        return 0;
      }
      

      Just registering here the same currently bound to SIGCHLD signal handler with SA_RESTART system flag and all working perfectly.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            w00t Robin Burchell
            admin Administrator
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes