首页 > 解决方案 > C 系统调用 popen() 返回指向流的有效指针,但将 errno 设置为“没有这样的文件或目录”

问题描述

我有带有 popen() 调用的虚拟代码。我正在尝试获取 ntpq 输出。它可以工作,但它将 errno 设置为“没有这样的文件 o 目录”

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[]){
    if(access("/usr/bin/ntpq", X_OK) == 0){
        printf("binary found!\n");
    } else if(access("/usr/sbin/ntpq", X_OK) == 0) {
        printf("binary found!\n");
    } else {
        printf("no such binary found!\n");
    }

    char buffer[BUFSIZ+1] = {0};

    fcloseall();
    auto read_fp = popen("/usr/bin/ntpq -pn 2>&1", "r");
    auto fdn = fileno(read_fp);

    printf("fd number:%d, errno: %s\n", fdn, strerror(errno));

    if(read_fp != NULL){
        int chars_read = fread(buffer, sizeof(char), BUFSIZ, read_fp);
        int err_fread = ferror(read_fp);
        printf("errno: %s\n", strerror(errno));
        printf("fread code error: %d\n", err_fread);
        printf("chars_read:%d buffer:\n%s\n",chars_read, buffer);
    }
    auto res = pclose(read_fp);
    printf("pclose result: %d\n", res);
}

输出:

errno: No such file or directory
fread code error: 0
chars_read:1817 buffer:
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 0.debian.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
 1.debian.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
 2.debian.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
 3.debian.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
-194.190.168.1   .GPS.            1 u  429 1024   77   50.695  -11.531   2.685
+193.192.36.3    128.0.142.251    3 u  396 1024   77   28.064  -11.941   3.725
+91.209.94.10    194.190.168.1    2 u  374 1024   77   13.551  -10.077   3.143
+185.209.85.222  194.190.168.1    2 u  361 1024   77    5.546   -8.825   1.980
#89.110.32.178   83.143.51.50     2 u  419 1024   77   17.984  -12.670   8.617
#85.21.78.23     194.58.202.20    2 u  413 1024   77   24.850  -14.270   1.513
#89.169.75.105   88.147.254.228   2 u  368 1024   75   15.885   -9.821   2.040
#195.3.254.2     194.58.202.148   2 u  394 1024   77   21.267   -5.133   3.649
#89.221.207.113  194.58.204.148   2 u  391 1024   77   15.524  -13.023   2.140
+212.13.97.58    89.109.251.22    2 u  407 1024   77   14.036   -9.068   1.887
*195.210.189.106 .GPS.            1 u  456 1024   37   16.241   -9.656   2.837
#83.143.51.50    .PPS.            1 u  381 1024   77   46.082   -9.931   3.363
+195.91.239.8    .PPS.            1 u  533 1024   17   12.478   -9.804   2.495
-94.247.111.10   89.109.251.24    2 u  305 1024   77   57.922  -10.653   1.569
#85.21.78.8      192.36.144.22    2 u  415 1024   77   24.246  -13.495   1.828
+185.22.62.218   194.58.202.20    2 u  367 1024   77   15.070  -10.196   2.563
-188.93.104.2    89.109.251.21    2 u  399 1024   77   13.762   -9.195   2.818

pclose result: 0

我试图用 fcloseall() 关闭所有文件流。我还尝试使用 fflush(NULL) 清除所有流。但什么都没有改变。

我在生产中使用此调用,我需要使用 errno 变量获得成功状态。我能做错什么?我可以检查什么?我可以替换 popen() 调用吗?

Linux debian 4.19.0-17-amd64 #1 SMP Debian 4.19.194-3 (2021-07-18) x86_64 GNU/Linux

标签: c++clinuxbashdebian

解决方案


推荐阅读