質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

7402閲覧

リダイレクトを実装したい

HO_Pollyanna

総合スコア7

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

2クリップ

投稿2018/05/04 08:16

Cで簡単なシェルを実装したいのですが、リダイレクトが実現できません

lang

1#include<stdio.h> 2#include<stdlib.h> 3#include<unistd.h> 4#include<string.h> 5#include<fcntl.h> 6#include<sys/types.h> 7#include<sys/wait.h> 8 9#define MAX_LINE_IN 1000 10#define MAX_ARGS 30 11#define BUF_SIZE 256 12 13int nol(const char *s){ 14 int i; 15 FILE *f=fopen(s,"r"); 16 char buf[BUF_SIZE]; 17 18 if(!f){ 19 printf("ファイル読み込みエラー\n"); 20 exit(0);} 21 22 i=0; 23 24 while((fgets(buf,BUF_SIZE,f)) != NULL){ 25 i++; 26 } 27 if(fclose(f))exit(0); 28 29 return i; 30} 31void redirect(const char *args[],int a){//a:<のある位置 32 int fd,i; 33 34 args[a]=NULL; 35 fd=open(args[a+1],O_WRONLY | O_CREAT,0664);//rwrwrのこと 36 close(STDOUT_FILENO); 37 dup(fd); 38 execvp(args[0],args); 39 40} 41 42 int main(int argc, char *argv[]){ 43 int pid, status; 44 char line_in[MAX_LINE_IN]; 45 char *args[MAX_ARGS]; 46 int nargs; 47 int i; 48 49 ////tokenize 50 for(;;){ 51 printf("> "); 52 if(fgets(line_in,MAX_LINE_IN,stdin)==NULL)exit(0); 53 line_in[strlen(line_in)-1]='\0'; 54 55 char *token = strtok(line_in," "); 56 nargs=0; 57 args[nargs++]=token; 58 while(token!=NULL){ 59 token = strtok(NULL," "); 60 if(token!=NULL){ 61 args[nargs++]=token; 62 } 63 } 64 args[nargs] = NULL; 65 66 if(args[0]!=NULL){ 67 if(!strcmp(args[0],"exit")) 68 { 69 exit(1); 70 continue; 71 } 72 73 74 75 76 if(fork()==0){ 77 78 if(!strcmp(args[0],"nol")) 79 { 80 printf("%d\n",nol(args[1])); 81 exit(1); 82 } 83 for(i=0;i<nargs;i++) 84 { 85 if(!strcmp(args[i],">")) 86 { 87 redirect(args[0],i); 88 exit(1); 89 } 90 } 91 execvp(args[0],args); 92 printf("command not found\n"); 93 exit(1); 94 } 95 96 else{ 97 wait(&status); 98 } 99 100 } 101 102 } 103 return 0; 104 } 105

コンパイルすると以下の警告がでます
shell.c: In function ‘redirect’:
shell.c:38:18: warning: passing argument 2 of ‘execvp’ from incompatible pointer type [-Wincompatible-pointer-types]
execvp(args[0],args);
^
In file included from shell.c:3:0:
/usr/include/unistd.h:581:12: note: expected ‘char * const*’ but argument is of type ‘const char **’
extern int execvp (const char *__file, char *const __argv[
^
shell.c: In function ‘main’:
shell.c:87:13: warning: passing argument 1 of ‘redirect’ from incompatible pointer type [-Wincompatible-pointer-types]
redirect(args[0],i);
^
shell.c:31:6: note: expected ‘const char **’ but argument is of type ‘char *’
void redirect(const char *args[],int a){//a:<のある位�

実行後、echoコマンドで出力先を任意のファイルにリダイレクトしたいのですが新しいファイルが生成されません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2018/05/04 08:28

そのコードで具体的にどういう動作をさせたいんでしょうか?
HO_Pollyanna

2018/05/04 08:31

echo (任意の文字列) > ___.txt   と入力したときにテキストファイルに任意の文字列を出力させたいと考えています
y_waiwai

2018/05/04 08:36

で、今のコードで、echo (任意の文字列) は実行できるんでしょうか
guest

回答3

0

真っすぐな回答でなくて申し訳ないのですが、system callの帰値を全部調べましょう。ドキュメントを読むという話ではなく、以下のようにコードを書くという意味です。

if((fd=open(...)) == -1 ) { // NULL になってしまった原因の分析 }

投稿2018/05/05 17:01

gm300

総合スコア580

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HO_Pollyanna

2018/05/07 05:29

回答有り難うございます。参考になります。
guest

0

ベストアンサー

void redirect(const char *args[], int a)

こちらの最初の引数は、文字列へのポインタ(ポインタのポインタ)
それに対し、呼び出し側は、
> redirect(args[0], i);

 

char *args[MAX_ARGS];

なので、args[0] は、最初の文字列です。
従って、示すものが違うと思われます。
単に、
redirect(args, i);
で良いかなと、思いますがどうでしょう。

const の有無に関する警告は、それだけでは、無視しても動く事が多い(だから、警告)。その陰にもっと大きな問題がある可能性ですね。

ちょっと、Linuxまで動かして確認できないので、問題点の指摘まで。
(久々に、fork()システムコールを見た。どっかのコピペでやってませんか?)

投稿2018/05/05 11:02

pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HO_Pollyanna

2018/05/07 05:29

本当にありがとうございました。解決できました。
guest

0

extern int execvp (const char *file, char *const argv[
なので*argv[]は書き換え可能で無ければいけません。

c

1void redirect(char *const args[],int a)

にしましょう。

投稿2018/05/04 09:20

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HO_Pollyanna

2018/05/04 13:38

回答有り難う御座います 該当の箇所を修正したのですが echo hello > hello.txt と入力してもhello.txtが現れません... コンパイル時の警告 shell.c: In function ‘main’: shell.c:87:13: warning: passing argument 1 of ‘redirect’ from incompatible pointer type [-Wincompatible-pointer-types] redirect(args[0],i); ^ shell.c:31:6: note: expected ‘char * const*’ but argument is of type ‘char *’ void redirect(char *const args[],int a){//a:<のある位� ^
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問