3

FDステータスフラグfcntlを_ stdout と stderr の状態フラグも に変更されました。stdinstdinO_NONBLOCKO_NONBLOCK

fcntl関数、SYSCALL_DEFINE3およびのソース コードを調べましたdo_fcntlが、何も役に立ちませんでした。また、スタックオーバーフローまたはグーグル。カーネルまたはglibcの実装に関連している可能性があると思います。

私のコンピューターは、x86_64 上の Ubuntu 12.04 で、gcc 4.6.3 がインストールされています。

  int flag = 0;
  int value = O_NONBLOCK;
  int fd = open("./tmp", O_RDONLY);

  if(-1 == (flag = fcntl(fd, F_GETFL)))
      fprintf(stdout, "%d:%s\n", errno, strerror(errno));

  flag = fcntl(stdin->_fileno, F_GETFL);
  flag = fcntl(stderr->_fileno, F_GETFL);
  if(-1 == (flag = fcntl(stdout->_fileno, F_GETFL)))
      fprintf(stdout, "%d:%s\n", errno, strerror(errno));

  flag = fcntl(stdout->_fileno, F_SETFL, flag | O_NONBLOCK);

  flag = fcntl(fd, F_GETFL);
  flag = fcntl(stdin->_fileno, F_GETFL);
  flag = fcntl(stdout->_fileno, F_GETFL);
  flag = fcntl(stderr->_fileno, F_GETFL);

  flag = fcntl(stdin->_fileno, F_SETFL, flag | O_APPEND);

  flag = fcntl(fd, F_GETFL);
  flag = fcntl(stdin->_fileno, F_GETFL);
  flag = fcntl(stdout->_fileno, F_GETFL);
  flag = fcntl(stderr->_fileno, F_GETFL);

  close(fd);

これは、この問題に対する私のコードです。

4

2 に答える 2

1

ジョナサンの答えに続いて、ここにいくつかの健全なコードがあります:

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

void show_nonblock_status(void) {
    char streams[3][7] = {"stdin", "stdout", "stderr"};

    for ( int i = 0; i < 3; ++i ) {
        int flag = fcntl(i, F_GETFL);
        if ( flag == -1 ) {
            perror("error getting flags");
            exit(EXIT_FAILURE);
        }

        if ( flag & O_NONBLOCK ) {
            printf("O_NONBLOCK is set for %s\n", streams[i]);
        } else {
            printf("O_NONBLOCK is not set for %s\n", streams[i]);
        }
    }
}

int main(void) {
    show_nonblock_status();

    int flag = fcntl(1, F_GETFL);
    if ( flag == -1 ) {
        perror("error getting flags");
        exit(EXIT_FAILURE);
    }

    flag = fcntl(1, F_SETFL, flag | O_NONBLOCK);
    if ( flag == -1 ) {
        perror("error getting flags");
        exit(EXIT_FAILURE);
    }

    show_nonblock_status();

    return 0;
}

さまざまな用途で次の出力が得られます。

paul@local:~/src/c/scratch$ ./fct
O_NONBLOCK is not set for stdin
O_NONBLOCK is not set for stdout
O_NONBLOCK is not set for stderr
O_NONBLOCK is set for stdin
O_NONBLOCK is set for stdout
O_NONBLOCK is set for stderr
paul@local:~/src/c/scratch$ cat testfile | ./fct
O_NONBLOCK is not set for stdin
O_NONBLOCK is not set for stdout
O_NONBLOCK is not set for stderr
O_NONBLOCK is not set for stdin
O_NONBLOCK is set for stdout
O_NONBLOCK is set for stderr
paul@local:~/src/c/scratch$ cat testfile | ./fct 2>/dev/null
O_NONBLOCK is not set for stdin
O_NONBLOCK is not set for stdout
O_NONBLOCK is not set for stderr
O_NONBLOCK is not set for stdin
O_NONBLOCK is set for stdout
O_NONBLOCK is not set for stderr
paul@local:~/src/c/scratch$

最初のケースでは、ファイルの説明は同じであるため、O_NONBLOCK3 つすべてに対して が設定されます。

2 番目のケースでは、ファイルが にパイプされるstdinため、 は と に異なるファイル記述をstdout持ちstderr、両方ともO_NONBLOCK設定されています。

3 番目のケースでは、ファイルが にパイプされstdin、 にstderrリダイレクトされる/dev/nullため、3 つのファイルの説明はすべて異なり、O_NONBLOCKのみに設定されstdoutます。

于 2013-10-21T03:57:35.573 に答える