Skip to content

Instantly share code, notes, and snippets.

@zzztuzzz
Created July 18, 2016 18:21
Show Gist options
  • Save zzztuzzz/ee5d6a52cc128b47769135e12a4ba45f to your computer and use it in GitHub Desktop.
Save zzztuzzz/ee5d6a52cc128b47769135e12a4ba45f to your computer and use it in GitHub Desktop.
System Programming 2016 shell in Clang
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/*
====================定数を定義=====================
***********入力値における文字数の最大値設定***********
*/
#define MAX_ARGS 50
#define MAX_LEN 500
int main(void)
{
int argc, n = 0;
char buf[256];
char input[MAX_LEN];
char *arrayCommand[MAX_ARGS];
char *cp;
int status;
/* 区切り文字の設定 */
const char *delim = " \t\n";
/*無限ループで入力を待機*/
while (1) {
n= n+1;
/* コマンド入力 コマンドプロンプト */
printf("welcome zztuzz shell!![%d] ", n);
/*EOF 終了処理*/
if (fgets(input, sizeof(input), stdin) == NULL) {
printf("ヾ(◎m◎)サラバジャ\n");
exit(0);
}
/* コマンド行を空白/タブで分割し,配列 arrayCommand[] に格納する */
cp = input;
for (argc = 0; argc < MAX_ARGS; argc++) {
if ((arrayCommand[argc] = strtok(cp,delim)) == NULL)
break;
cp = NULL;
}
/*今回はパイプに挑戦. 1パイプ使う場合を実装*/
char *comm1[MAX_ARGS];
char *comm2[MAX_ARGS];
int countCom2 = 0, i = 0, j = 0;
//入力されたコマンドをcomm1,comm2に分割する
while (arrayCommand[i]) {
if (countCom2 == 0) {
if (*arrayCommand[i] == '|') {
countCom2 = 1;
} else {
comm1[i] = arrayCommand[i];
comm1[i + 1] = NULL;
}
} else {
comm2[j] = arrayCommand[i];
comm2[j + 1] = NULL;
j++;
}
i++;
}
//exitが入力された時に終了する
if (strcmp(arrayCommand[0], "exit") == 0) {
exit(0);
}
//"|"が入力された時にパイプを作成
int fd[2];
if (countCom2 == 1) {
pipe(fd);
}
pid_t pid = fork();
if (pid < 0) {
perror("fork");
exit(-1);
} else if (pid == 0 && countCom2 == 0) {
//子1プロセス時に実行
execvp (comm1[0], comm1);
exit(-1);
} else if (pid == 0 && countCom2 == 1) {
//"|"を含んでおり子1プロセス時に実行
dup2(fd[1], 1);
close(fd[1]);
execvp (comm1[0], comm1);
exit(-1);
} else if (countCom2 == 1){
//子1プロセスの終了を待つ
wait(&status);
close(fd[1]);
pid_t pid2 = fork();
if (pid2 == 0) {
//子2プロセス時に実行
dup2(fd[0], 0);
execvp (comm2[0], comm2);
close(fd[0]);
exit(-1);
}
close(fd[0]);
}
//子2プロセスの終了を待つ
wait(&status);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment