#c #linux #network-programming #popen
#c #linux #сетевое программирование #popen
Вопрос:
У меня есть приложение, написанное на Qt C , которое должно собирать информацию о сетевом подключении. Код для этого показан ниже:
class NetworkHelper {
public:
static void networkInfo(const QString amp;device, QString amp;hwaddr, QString amp;hwdesc, QString amp;ip, QString amp;ipmask, QString amp;gateway, QString amp;dhcp)
{
FILE *fp;
char buf[512];
QRegularExpression re_vendor("GENERAL.VENDOR:\s (?<vendor>. )");
QRegularExpression re_product("GENERAL.PRODUCT:\s (?<product>. )");
QRegularExpression re_hwaddr("GENERAL.HWADDR:\s (?<hwaddr>. )");
QRegularExpression re_ip_gateway("ip = (?<ip>\d .\d .\d .\d )/\d , gw = (?<gateway>\d .\d .\d .\d )");
QRegularExpression re_ipmask("subnet_mask = (?<ipmask>\d .\d .\d .\d )");
QRegularExpression re_dhcp("dhcp_server_identifier = (?<dhcp>\d .\d .\d .\d )");
QRegularExpressionMatch match;
hwaddr = QString();
hwdesc = QString();
ip = QString();
ipmask = QString();
gateway = QString();
dhcp = QString();
#ifdef Q_OS_LINUX
const char *cmd = QString("nmcli dev list iface %1").arg(device).toUtf8().constData();
if (!(fp = popen(cmd,"r")))
return;
while (fgets(buf, sizeof(buf), fp) != NULL)
{
match = re_ip_gateway.match(buf);
if (match.hasMatch())
{
ip = match.captured("ip");
gateway = match.captured("gateway");
}
match = re_ipmask.match(buf);
if (match.hasMatch())
ipmask = match.captured("ipmask");
match = re_dhcp.match(buf);
if (match.hasMatch())
dhcp = match.captured("dhcp");
match = re_vendor.match(buf);
if (match.hasMatch())
hwdesc = match.captured("vendor");
match = re_product.match(buf);
if (match.hasMatch())
hwdesc = hwdesc.isEmpty() ? match.captured("product") : " / " match.captured("product");
match = re_hwaddr.match(buf);
if (match.hasMatch())
hwaddr = match.captured("hwaddr");
}
ret = pclose(fp);
#endif
}
};
Приложение запускается как автозапуск сразу после загрузки компьютера. Проблема в том, что popen() возвращает код 139, что, насколько я понимаю, означает segfault, а цикл while не выполняется, поэтому я не могу получить информацию о сети.
Если я вхожу в систему и вручную запускаю приложение, приведенный выше код выполняется нормально, и я получаю всю необходимую сетевую информацию.
Кроме того, другая часть приложения запускает HTTP-сервер, к которому я могу подключиться и при автозапуске приложения, поэтому, похоже, проблем с сетью нет.
Кто-нибудь знает, как я смогу запустить popen () при автозапуске приложения?
Комментарии:
1. NetworkManager не всегда запускается непосредственно во время загрузки. Есть ли у вас обязательное условие для подключения к сети в вашем сценарии автозапуска?
2. Нет, я этого не делаю. Так в этом может быть проблема? Я использую Ubuntu. Есть ли у вас дополнительная информация о том, что мне понадобится в моем сценарии?
3. Я попытался добавить ‘sudo service network-manager start’ в свой сценарий автозапуска, но в этом случае мой http-сервер не запускается, и, следовательно, я вообще не могу подключиться к приложению. Есть идеи, как мне поступить?
4. Может кто-нибудь, пожалуйста, дать подсказку, что мне нужно добавить в мой сценарий austostart, чтобы гарантировать, что NetworkManager запущен?
5. просто для ясности. Если мое приложение работает в фоновом режиме, и я вхожу в компьютер или выполняю ssh, то popen («nmcli dev list iface eth0», «r») работает нормально и выдает код возврата 0. Если я выхожу из системы или завершаю сеанс ssh, то команда popen() не работает и выдает код возврата 139.
Ответ №1:
Обнаружил, что мое приложение запустилось раньше сетевого менеджера (или что-то в этом роде — не совсем уверен, почему я увидел вышеупомянутое поведение, поскольку я смог подключиться к http-серверу, запущенному приложением, но не смог запустить команду nmcli).
В моем сценарии автозапуска я добавил условие не запускать приложение до установления подключения к Интернету, что решило мою проблему