【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※返信付き投稿の削除は禁止!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら


本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.21519

cat、egrep、wcをパイプで繋ぐ
投稿者---ひか(2005/06/20 23:52:19)


お久しぶりです。
また行き詰ってしまいましたのでよろしくお願いします。
UNIXシステムコールで、パイプを使い、catでファイルを繋ぎ、egrepで空行の除去、最後にwcを使い行数、単語数、バイト数を数えるということをしたいのですが…。
作ってみたのですがコンパイルは通るのですが以下のような結果になってしまいます。

egrep: NULL: そのようなファイルやディレクトリはありません
egrep: wc: そのようなファイルやディレクトリはありません
0 0 0

ご指導お願いいたします。
以下実行したソースです。

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

int
main(int argc, char *argv[])
{
  int fds[2], fds2[2];
  pid_t pid1, pid2, pid3;
  int status1, status2, status3;
  char *cat_args[argc + 2];
  char *wc_args[2];
  char *egrep_args[4];


  cat_args[0] = "cat";
  cat_args[1] = "--";
  memcpy(&cat_args[2], &argv[1], (argc - 1) * sizeof(char *));
  cat_args[argc + 1] = NULL;
  wc_args[0] = "wc";
  wc_args[1] = NULL;

  egrep_args[0] = "egrep";
  egrep_args[1] = "-v";
  egrep_args[2] = "^$";
  egrep_args[3] = "NULL";

  if (pipe(fds) == -1) {
    perror(NULL);
    exit(1);
  }
  if (pipe(fds2) == -1) {
    perror(NULL);
    exit(1);
  }

  if ((pid3 = fork()) == 0){
    if (fds2[0] != STDIN_FILENO){
      dup2(fds2[0], STDIN_FILENO);
      close(fds2[0]);
    }
    close(fds2[1]);

    execv("/bin/wc", wc_args);
    execv("/usr/bin/wc", wc_args);
    _exit(1);
  }
  if (pid3 == -1){
    perror(NULL);
    exit(1);
  }
  close(fds2[0]);

  if ((pid1 = fork()) == 0) {
    if (fds2[1] != STDIN_FILENO) {
      dup2(fds2[1], STDIN_FILENO);
      close(fds2[1]);
    }
    execv("/bin/egrep", egrep_args);
    execv("/usr/bin/egrep", egrep_args);
    _exit(1);
  }
  if (pid1 == -1) {
    perror(NULL);
    exit(1);
  }
  close(fds2[1]);
  close(fds[0]);

  if ((pid2 = fork()) == 0) {
    if (fds[1] != STDOUT_FILENO) {
      dup2(fds[1], STDOUT_FILENO);
      close(fds[1]);
    }
    execv("/bin/cat", cat_args);
    execv("/usr/bin/cat", cat_args);
    _exit(1);
  }
  if (pid2 == -1) {
    perror(NULL);
    exit(1);
  }
  close(fds[1]);
  waitpid(pid2, &status2, 0);
  waitpid(pid1, &status1, 0);
  waitpid(pid3, &status3, 0);
  return 0;
}




この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:cat、egrep、wcをパイプで繋ぐ 21520 ぽこ 2005/06/21 00:30:09
<子記事> Re:cat、egrep、wcをパイプで繋ぐ 21521 かずま 2005/06/21 02:28:35


No.21520

Re:cat、egrep、wcをパイプで繋ぐ
投稿者---ぽこ(2005/06/21 00:30:09)


> egrep_args[3] = "NULL";

ぱっと見、ここでは?


この投稿にコメントする

削除パスワード

No.21521

Re:cat、egrep、wcをパイプで繋ぐ
投稿者---かずま(2005/06/21 02:28:35)


#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int fds[2], fds2[2];
    pid_t pid1, pid2, pid3;
    int status1, status2, status3;

    if (pipe(fds) == -1) { perror(NULL); exit(1); }
    if (pipe(fds2) == -1) { perror(NULL); exit(1); }

    if ((pid3 = fork()) == -1) { perror(NULL); exit(1); }
    if (pid3 == 0) {
        char *wc_args[] = { "wc", NULL };
        dup2(fds2[0], STDIN_FILENO);
        close(fds[0]); close(fds[1]); close(fds2[0]); close(fds2[1]);
        execv("/bin/wc", wc_args);
        execv("/usr/bin/wc", wc_args);
        _exit(1);
    }
    close(fds2[0]);

    if ((pid1 = fork()) == -1) { perror(NULL); exit(1); }
    if (pid1 == 0) {
        char *egrep_args[] = { "egrep", "-v", "^$", NULL };
        dup2(fds[0], STDIN_FILENO);
        dup2(fds2[1], STDOUT_FILENO);
        close(fds[0]); close(fds[1]); close(fds2[1]);
        execv("/bin/egrep", egrep_args);
        execv("/usr/bin/egrep", egrep_args);
        _exit(1);
    }
    close(fds[0]); close(fds2[1]);

    if ((pid2 = fork()) == -1) { perror(NULL); exit(1); }
    if (pid2 == 0) {
        char *cat_args[argc + 2];  // XXX
        cat_args[0] = "cat"; cat_args[1] = "--";
        memcpy(&cat_args[2], &argv[1], argc * sizeof(char *));
        dup2(fds[1], STDOUT_FILENO);
        close(fds[1]);
        execv("/bin/cat", cat_args);
        execv("/usr/bin/cat", cat_args);
        _exit(1);
    }
    close(fds[1]);

    waitpid(pid2, &status2, 0);
    waitpid(pid1, &status1, 0);
    waitpid(pid3, &status3, 0);
    return 0;
}



この投稿にコメントする

削除パスワード

No.21523

Re:cat、egrep、wcをパイプで繋ぐ
投稿者---ひか(2005/06/21 12:51:16)


ぽこさん、かずまさん、ありがとうございます!
無事解決しました!

"NULL"になっていたことに気づきませんでした。
パイプを使うときはcloseをしっかりしていないとおかしくなるんですね。

本当にありがとうございました。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧