Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

posix_spawn, returns 1



  • I want to spawn an application from my application:

    QString strFullPath(strModulesPath + strModule.toString());
    QByteArray baFullPath(strFullPath.toLatin1());
    char* pszFullPath = baFullPath.data();
    //Ensure path is correct before use, this will handle translation of ~ if used!
    wordexp_t exp_result;
    wordexp(pszFullPath, &exp_result, 0);
    pszFullPath = exp_result.we_wordv[0];
    std::ifstream ifile(pszFullPath);
    
    if ( static_cast<bool>(ifile) == true ) {
    //Module path is valid, try and spawn it!
        const int cintModulePort = clsSocketThread::intNextPort();
        std::string strModulePort = std::to_string(cintModulePort);
        std::string strServerPort = std::to_string(clsMainWnd::intGetServerPort());
        char* paryszArgs[] = {pszFullPath, nullptr, nullptr, nullptr};
        const char* cpszModulePort = strModulePort.data();
        const char* cpszSvrPort = strServerPort.data();
        posix_spawn_file_actions_t* pfileActionsp;
        char** ppEnviron = nullptr;
        posix_spawnattr_t* pAttr;
        pid_t pid = 0;
        pfileActionsp = pAttr = nullptr;
        paryszArgs[1] = strdup(cpszSvrPort);
        paryszArgs[2] = strdup(cpszModulePort);
        int intRC = posix_spawn(&pid, pszFullPath, pfileActionsp
                               ,pAttr, paryszArgs, ppEnviron);
        if ( intRC == 0 && pid != 0 ) {
    //Module has been successfully started, save its PID
            objModule.insert(clsScriptHelper::mscszModule, strModule);
            objModule.insert(clsScriptHelper::mscszPID, QJsonValue(pid));
            objModule.insert(clsScriptHelper::mscszPort, QJsonValue(cpszModulePort));
            clsSocketThread* psckCli = new clsSocketThread(SOM_CLIENT
                                                          ,strModuleName.toLatin1().data()
                                                          ,cintModulePort);
            psckCli->setHelper(cliHelper);
                    msmpModules.insert(prModule(strModuleName, objModule));
        }
    }
    

    strModulesPath contains:

    ~/XMLMPAM/config/modules/
    

    strModuleName contains:

    mdFileIO
    

    strModule contains:

    mdFileIO
    

    The above is no mistake strModuleName and strModule do contain the same. objModule is defined as:

    QJsonObject objModule;
    

    When posix_spawn is called the result is 1 and pid contains 1441. From the online help, if successful its supposed to return 0, what does a return of 1 mean with a pid ?

    I should have added, my development system:

    macOS Catalina, Version 10.15.7
    iMac (Retina 5K, 27-inch, Late 2015)
    Processor 4GHz Quad-Core Intel Core i7
    Memory 16 GB 1867 MHz DDR3
    Graphics AMD Radeon R9 M395X 4GB
    

    Qt Creator

    Qt Creator 4.13.1
    Based on Qt 5.15.1 (Clang 11.0 (Apple), 64 bit)
    Built on Sep 16 2020 01:17:08
    From revision 1da2c1f766
    

    Compiler

    C++, Clang (C++, x86 64bit in /usr/bin)
    C, Clang (C, x86 64bit in /usr/bin)
    

    Debugger

    System LLDB at /Applications/Xcode.app/Contents/Developer/usr/bin/lldb
    Version 1200.0.31.1 Apple Swift version 5.3 (swiftlang-1200.0.29.2 clang-1200.0.30.1)
    

  • Lifetime Qt Champion

    @SPlatten Is there a reason why you don't use QProcess? posix_spawn is not part of Qt.


  • Lifetime Qt Champion

    @SPlatten Is there a reason why you don't use QProcess? posix_spawn is not part of Qt.



  • @jsulm , I wasn't aware of it or I forgot...I will certain look for it now and an example.


  • Lifetime Qt Champion

    @SPlatten said in posix_spawn, returns 1:

    what does a return of 1 mean with a pid ?

    "The posix_spawn() and posix_spawnp() functions fail only in the case
    where the underlying fork(2), vfork(2) or clone(2) call fails; in
    these cases, these functions return an error number, which will be
    one of the errors described for fork(2), vfork(2) or clone(2)."
    https://man7.org/linux/man-pages/man3/posix_spawn.3.html



  • @jsulm , I'm not sure if what I'm doing is correct?

    bool clsMainWnd::blnLaunch(QString strApp, QStringList& slstArgs, qint64& int64PID) {
        Q_ASSERT_X(clsMainWnd::mspobjProcess!=nullptr, "blnLaunch", "mspobjProcess is null!");
        int intLastSep = strApp.lastIndexOf(QDir::separator());
        int64PID = 0;
        if ( intLastSep > 0 ) {
            QString strName = strApp.mid(intLastSep + 1)
                   ,strPath = strApp.mid(0, intLastSep + 1);
            if ( mspobjProcess->startDetached(strName, slstArgs, strPath, &int64PID) == true
              && int64PID > 0 ) {
                return true;
            }
        }
        return false;
    }
    

    In the above, strApp:

    ~/XMLMPAM/config/modules/mdFileIO
    

    slstArgs <2 items>:

    "8123"
    "8124"
    

    It doesn't seem to be working as I get no valid PID back.


  • Lifetime Qt Champion



  • @jsulm , I've modified the function:

    bool clsMainWnd::blnLaunch(QString strApp, QStringList& slstArgs, qint64& int64PID) {
        Q_ASSERT_X(clsMainWnd::mspobjProcess!=nullptr, "blnLaunch", "mspobjProcess is null!");
        int intLastSep = strApp.lastIndexOf(QDir::separator());
        int64PID = 0;
        if ( intLastSep > 0 ) {
            QString strName = strApp.mid(intLastSep + 1)
                   ,strPath = strApp.mid(0, intLastSep + 1);
            if ( mspobjProcess->startDetached(strName, slstArgs, strPath, &int64PID) == true
              && int64PID > 0 ) {
                return true;
            }
            qDebug() << mspobjProcess->error();
        }
        return false;
    }
    

    The result is:

    QProcess::UnknownError
    

    Not terribly helpful.


  • Lifetime Qt Champion

    @SPlatten said in posix_spawn, returns 1:

    strName

    What does it contain when you call startDetached? Did you try with absolute path to the executable?



  • @jsulm strName contains:

    mdFileIO
    

    I just tried calling the function with the absolute path:

    bool clsMainWnd::blnLaunch(QString strApp, QStringList& slstArgs, qint64& int64PID) {
        Q_ASSERT_X(clsMainWnd::mspobjProcess!=nullptr, "blnLaunch", "mspobjProcess is null!");
        int intLastSep = strApp.lastIndexOf(QDir::separator());
        int64PID = 0;
        if ( intLastSep > 0 ) {
            QString strName = strApp.mid(intLastSep + 1)
                   ,strPath = strApp.mid(0, intLastSep + 1);
            if ( mspobjProcess->startDetached(strApp, slstArgs, strPath, &int64PID) == true
              && int64PID > 0 ) {
                return true;
            }
            qDebug() << mspobjProcess->error();
        }
        return false;
    }
    

    Where strApp contains:

    ~/XMLMPAM/config/modules/mdFileIO
    

    Same result.


  • Lifetime Qt Champion

    @SPlatten said in posix_spawn, returns 1:

    ~/XMLMPAM/config/modules/mdFileIO

    Try with whole path, without ~ as ~ is resolved by the shell as far as I know.



  • @jsulm , still having problems:

    bool clsMainWnd::blnLaunch(QString strApp, QStringList& slstArgs, qint64& int64PID) {
        Q_ASSERT_X(clsMainWnd::mspobjProcess!=nullptr, "blnLaunch", "mspobjProcess is null!");
        QString strUserProfile("~");
    
        if ( strApp.contains(strUserProfile) == true ) {
        //Application path contains user proflie reference, replace with actual folder
            QString strUserFolder(clsDebugService::strGetUserFolder(strUserProfile));
    
            if ( strUserFolder.endsWith(QDir::separator()) == true ) {
                strUserFolder = strUserFolder.left(strUserFolder.length() - 1);
            }
            strApp = strApp.replace(strUserProfile, strUserFolder);
        }
        int intLastSep = strApp.lastIndexOf(QDir::separator());
        int64PID = 0;
        if ( intLastSep > 0 ) {
            QString strName = strApp.mid(intLastSep + 1)
                   ,strPath = strApp.mid(0, intLastSep + 1);
            if ( mspobjProcess->startDetached(strApp, slstArgs, strPath, &int64PID) == true
              && int64PID > 0 ) {
                return true;
            }
            qDebug() << mspobjProcess->error();
        }
        return false;
    }
    

    After replacing "~" strApp now contains:

    "/Users/simonplatten/XMLMPAM/config/modules/mdFileIO"
    

    Although I get exactly the same results.

    QProcess::UnknownError
    

    [Edit] I just copied the path and app name and pasted into a terminal, I get:

    Last login: Mon Sep 28 09:04:18 on ttys001
    You have new mail.
    simonplatten@Simons-iMac ~ % /Users/simonplatten/XMLMPAM/config/modules/mdFileIO 
    zsh: operation not permitted: /Users/simonplatten/XMLMPAM/config/modules/mdFileIO
    


  • @SPlatten
    What is your question? If you cannot execute /Users/simonplatten/XMLMPAM/config/modules/mdFileIO, e.g. from zsh, then you cannot execute it, and Qt QProcess won't solve that.

    From what very little I know (I'm not Mac), have you tried Googling for zsh: operation not permitted? You get hits telling you why this happens under various MacOS incarnations and what you are supposed to do about it to allow it to run. [Looks like it's some Mac addition for "security" purposes.]



  • @JonB , I will look into it, thank you...its very odd, I am an Amin on the system.



  • @JonB ,@jsulm , got it I think, the application created by Qt Creator is not actually a file, but instead a folder:

    drwxr-xr-x  3 simonplatten  staff     96 28 Sep 07:29 mdFileIO.app
    

    If I then go into this folder the actual executable is located in:

    /Users/simonplatten/build-mdFileIO-Desktop_Qt_5_14_2_clang_64bit-Release/mdFileIO.app/Contents/MacOS/mdFileIO
    

    ls -l:

    -rwxr-xr-x  1 simonplatten  staff  81280 28 Sep 07:29 mdFileIO
    

    I can run this application.



  • @JonB , @jsulm So I simplified my application, commenting out the entire content of main and replacing with just:

    printf("Hello World\n");
    return 0;
    

    This worked without fault, so now I've put back the original and will investigate what exactly is causing the problems.



  • It makes 0 sense to me, I've put it back exactly the way it was, in fact all I did was undo until it was as it was...rebuilt and now it works!


Log in to reply