名前付きパイプを介してファイルの内容を渡してから、別のパイプにコピーする方法は?

名前付きパイプを介してファイルの内容を渡してから、別のパイプにコピーする方法は?

私は2つのプログラムを書いた。通常、1.名前付きパイプ(サーバー)を作成し、2.シェルからサーバー部分に文字列を渡します。

端末から名前付きパイプのサーバー部分に文字列を渡す方法を理解します。しかし、ファイルの内容の出力を読み取り、別のファイル(おそらく名前付きパイプのサーバー部分)に渡すことができるように、2つのプログラムにパラメータをファイルとして渡す方法がわかりません。アイデアは、最初のファイルの内容を2番目のファイルにコピーすることです。残念ながら、これを実装する方法がわかりません。

#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>

#define FIFO_NAME "myfifo"
#define BUF_SIZE 512
int main (void)
{
  FILE * fifo;
  char * buf;
  if (mkfifo ("myfifo", 0640) == -1) {
    fprintf (stderr, "Can't create fifo\n");
    return 1;
  }
  fifo = fopen (FIFO_NAME, "r");
  if (fifo == NULL) {
    fprintf (stderr, "Cannot open fifo\n");
    return 1;
  }
  buf = (char *) malloc (BUF_SIZE);
  if (buf == NULL) {
    fprintf (stderr, "malloc () error\n");
    return 1;
  }
  fscanf (fifo, "%s", buf);
  printf ("%s\n", buf);
  fclose (fifo);
  free (buf);
  unlink (FIFO_NAME);
  return 0;
}


#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>

#define FIFO_NAME "myfifo"

int main (int argc, char ** argv)
{
  int fifo;
  
  if (argc < 2) {
    fprintf (stderr, "Too few arguments\n");
    return 1;
  }
  fifo = open (FIFO_NAME, O_WRONLY);
  if (fifo == -1) {
    fprintf (stderr, "Cannot open fifo\n");
    return 1;
  }
  if (write (fifo, argv[1], strlen (argv[1])) == -1) {
    fprintf (stderr, "write() error\n");
    return 1;
  }
  close (fifo);
  return 0;
}

答え1

私はあなたが尋ねるものを完全に理解していません。私の解釈は、コマンドラインからクライアントに提供されたメッセージを送信するのではなく、ファイル名を指定し、そのファイルの内容をサーバーにパイプしたいということです。もしそうなら、次の方法が役に立ちます。

サーバーは次のとおりです。

#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>

#define FIFO_NAME "myfifo"
#define BUF_SIZE 512

int main(void)
{
    if (mkfifo("myfifo", 0640) == -1) {
        fprintf(stderr, "Can't create fifo\n");
        return EXIT_FAILURE;
    }

    FILE *fifo = fopen(FIFO_NAME, "r");
    if (fifo == NULL) {
        fprintf(stderr, "Cannot open fifo\n");
        return EXIT_FAILURE;

    }

    char *line = NULL;
    size_t line_length = 0;

    while (getline(&line, &line_length, fifo) != EOF) {
        printf("%s", line);
    }

    free(line);
    fclose(fifo);
    unlink(FIFO_NAME);

    return EXIT_SUCCESS;
}

クライアントは次のようになります。

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

#define FIFO_NAME "myfifo"

int main(int argc, char **argv)
{
    if (argc < 2) {
        fprintf(stderr, "Too few arguments\n");
        return EXIT_FAILURE;
    }

    const int input_fd = open(argv[1], O_RDONLY);
    if (input_fd < 0) {
        perror("open");
    }

    const int fifo_fd = open(FIFO_NAME, O_WRONLY);
    if (fifo_fd < 0) {
        perror("open");
        return EXIT_FAILURE;
    }

    char buffer[4096];
    int bytes_used;

    while ((bytes_used = read(input_fd, buffer, sizeof(buffer))) > 0) {
        if (write(fifo_fd, buffer, bytes_used) < 0) {
            perror("write");
            return EXIT_FAILURE;
        }
    }

    close(fifo_fd);
    close(input_fd);

    return EXIT_SUCCESS;
}

これはクライアントです

  • コマンドラインオプションをファイル名として使用する
  • ファイルを開く
  • ループからファイルを読み取り、パイプに書き込みます。

同様に、パイプから複数の文字列を読み取れるようにサーバーを変更しました。現在は、標準出力から読み取ったすべての内容を印刷します。実行例を考えてみましょう。

まずサーバーを起動します。

$ gcc -o server server.c
$ ./server

次に、入力ファイルを使用してクライアントを実行します。

$ cat message
this is a file
it has multiple lines
$ ./client message

これにより、サーバーに次の出力が表示されます。

this is a file
it has multiple lines

stdoutの代わりにファイルに書き込む場合は、これは非常に簡単な変更です。

関連情報