0

私はC言語が初めてで、今日、popen関数を使用して作成された「オープンストリーム」を閉じようとしているときに問題に直面しています。1. この問題は、このプログラムで使用したポーリング機能が原因で発生していますか? 2. それとも fcntl 関数のためですか? 誰かがこの問題の正確な原因を教えてくれたら、とてもうれしいです。以下にコードサンプルを添付しますので、ご覧ください。

コードサンプル:

#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#include <fcntl.h>

char line[1024];
FILE *tfd;

int readData(int *fd)
{
     struct pollfd pfd;
     int pollTime = 10000;
     pfd.events = POLLIN;
     pfd.fd = *fd;
     int ret=1;

     ret = poll(&pfd,1,pollTime);
     printf("\nAfter ret=%d\n.",ret);
     if(ret == -1 || ret ==0)
        {
                printf("Couldn't poll returned : %d\n", ret);
                return 0;
        } else {
                if( fgets(line,sizeof(line),tfd) == NULL )
                {
                        printf("\nReturns nothing.");
                        return 0;
                }
                printf("\nRead Some data.");
        }
        return ret;
}


void main(void)
{
        int ret;
        int fd, flags;
        char filepath[] = "/home/TEST/";
        char filename[] = "log.txt";
        char cmd[100];

        sprintf(cmd,"tail -f %s%s",filepath, filename);
        tfd = popen(cmd, "r");
        fd  = fileno(tfd);

        flags = fcntl(fd, F_GETFL, 0);
        flags |= O_NONBLOCK;
        fcntl(fd, F_SETFL, flags);

        if(tfd==NULL)
        {
                printf("\npopen failed, exiting.\n");
                exit(0);
        }
        while( (ret=readData(&fd)) > 0 )
        {
                printf("\nret2=%d.",ret);
                printf("\nLine : %s",line);
        }
        printf("\n**********DONE****************.\n");
        pclose(tfd);
}

出力:

[root@localhost TEST]# ./polltail

After ret=1
.
Read Some data.
ret2=1.
Line : 64 bytes from maa03s05-in-f4.1e100.net (74.125.236.68): icmp_req=31 ttl=52 time=38.4 ms

After ret=0
.Couldn't poll returned : 0

**********DONE****************.

ここでは、実行の最後にプロンプ​​トが表示されることを期待しています。しかし、それは来ていません。

4

2 に答える 2

1

tail が 10 秒間出力を生成しなかったため、タイムアウトが発生しています。次に pclose() を呼び出しますが、これは pclose() についてドキュメントに記載されていることです。

pclose() 関数は、関連付けられたプロセスが終了するのを待ち、wait4(2) によって返されるコマンドの終了ステータスを返します。

tail コマンドはまだ実行中であり、誰かが終了するまで実行し続けるため、pclose() は無期限にブロックされます。実行中の tail コマンドをプログラムで強制終了する必要がある場合は、popen/pclose を使用する以外の方法が必要になります。

于 2012-07-04T20:26:12.810 に答える
1

-f オプションを指定すると、ファイルの終わりに達しても tail は停止せず、追加のデータが入力に追加されるのを待ちます。-f オプションは、標準入力がパイプの場合は無視されますが、FIFO の場合は無視されます。

pclose() 関数は、関連付けられたプロセスが終了するのを待ちます。これは、wait4(2) によって返されるコマンドの終了ステータスを返します。

pclose() 関数は、ストリームが "popened" コマンドに関連付けられていない場合、ストリームが既に "pclosed" である場合、または wait4(2) がエラーを返した場合に -1 を返します。

pclose()の戻り値を確認してください。

于 2012-07-04T20:31:00.637 に答える