Search code examples
macosqtqt5wifiqprocess

QProcess sometimes returning empty string


I have been recently trying to create a function to scan wireless networks within my program. Basically there is a "Scan" button and this function is triggered when its used.

This function is pretty simple, it just instances a QProcess which opens a shell and the following command native from macOS X is executed:

/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport  -s | awk -F\" \" '{ print $1 }

Which allows me to do a scan of he nearby wireless networks and filter the results to only show a list of their SSID.

The problem arises because when I use my Qt function, it returns me the correct SSIDs, but on most occassions, when I press the button again, the returned list is empty. Trying to debug the application I see that the QProcess command returns an empty string.

Code from my application:

QStringList WifiConnection::scan_macOS()
{
    QProcess* myProcess = new QProcess( this );
    QString airport = "/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport";
    QString command = " -s | awk -F\" \" '{ print $1 }";

    qDebug() << "Opening shell.";
    myProcess->start("sh");
    qDebug() << "Executing command: " << airport << command;
    myProcess->write(airport + command);
    myProcess->closeWriteChannel();
    myProcess->waitForFinished();
    QString info = myProcess->readAllStandardOutput();
}

Any idea what could be the cause of this and if there is any solution to not get this empty string?

EDIT:

  • Qt Version used: 5.4.1

  • Device: Mac Book Air (macOS)


Solution

  • I have found that the issue happens because the airport manager in macOS is already busy with another action (scan for example).

    This can happen for some reasons:

    • Another app is controlling the airport application.
    • The use of QNetworkConfigurationManager which performs a automatic wireless scan every 10 seconds.
    • Location is enabled in your laptop, which in some OS versions causes periodical scans.

    What I did to avoid getting an empty answer was adding myProcess->waitForFinished(); as @markus-nm suggested in a comment, and ensured the result was not empty with if (!info.isEmpty()).