Startpunkten
This commit is contained in:
249
Lab2/lab2.c
Normal file
249
Lab2/lab2.c
Normal file
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Laboration 2 i C och UNIX
|
||||
*
|
||||
* Komplett shell
|
||||
* =========================================
|
||||
*
|
||||
* Christian Ohlsson, di7chro@cse.kau.se
|
||||
* Stefan Sonesson, di7stes@cse.kau.se
|
||||
*
|
||||
* Karlstads Universitet, 991209
|
||||
*
|
||||
*
|
||||
*===========================================
|
||||
*/
|
||||
#include "lab2.h"
|
||||
|
||||
extern treePtr tree;
|
||||
|
||||
/*Array med alla inmatningar som gjorts*/
|
||||
char *symTable[SYMTBLSIZE];
|
||||
|
||||
/*Global räknare för symTable*/
|
||||
int place=0;
|
||||
|
||||
/*Kopierar alla WORD & NULL till symTable*/
|
||||
int insert(char *str){
|
||||
if(str) symTable[place]=(char*)strdup(str);
|
||||
else symTable[place]=str;
|
||||
return place++;
|
||||
}
|
||||
|
||||
/*Rensar symTable*/
|
||||
void delTable() {
|
||||
int i=0;
|
||||
for(i=0 ; i<SYMTBLSIZE ; i++) symTable[i] = NULL;
|
||||
place=0;
|
||||
}
|
||||
|
||||
/*Exekverar varje kommando som en egen process*/
|
||||
void cmd(treePtr tPtr) {
|
||||
int pid, status;
|
||||
switch(pid=fork()){
|
||||
case -1: printf("Could not fork. (cmd)\n"); break;
|
||||
case 0: if((execvp(symTable[tPtr->index], &symTable[tPtr->index])) == -1) {
|
||||
fprintf(stderr, "Could not execute that.\n");
|
||||
exit(1); /* Child */
|
||||
}
|
||||
exit(1); break;
|
||||
default: if((waitpid(pid, &status,0)) == -1) { /* Parent */
|
||||
fprintf(stderr, "Could not wait. (cmd)\n");
|
||||
return;
|
||||
/*exit(1);*/
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*Hanterar pipes och ställer om fildescriptorer*/
|
||||
void pipa(treePtr tPtr) {
|
||||
int status, pfd[2];
|
||||
if((pipe(pfd)) == -1) {
|
||||
fprintf(stderr, "Pipe failed. (pipa) \n");
|
||||
return;
|
||||
}
|
||||
switch(fork()) {
|
||||
case -1: fprintf(stderr, "Fork failed. (pipa)\n");break;
|
||||
case 0 : if((dup2(pfd[1], 1)) == -1) { /* Child 1 */
|
||||
fprintf(stderr, "Could not dup.(pipa)\n");
|
||||
exit(1);
|
||||
}
|
||||
if((close(pfd[0])) == -1) {
|
||||
fprintf(stderr, "Could not close filedescriptor.(pipa)\n");
|
||||
exit(1);
|
||||
}
|
||||
doTree(tPtr->left);
|
||||
exit(1); break;
|
||||
default: /* Parent 1 */
|
||||
switch(fork()) {
|
||||
case -1: fprintf(stderr, "Fork failed(pipa)\n");break;
|
||||
case 0 : if((dup2(pfd[0], 0)) == -1) { /* Child 2 */
|
||||
fprintf(stderr, "Could not dup(pipa).\n");
|
||||
exit(1);
|
||||
}
|
||||
if((close(pfd[1])) == -1) {
|
||||
fprintf(stderr, "Could not close filedescriptor.(pipa)\n");
|
||||
exit(1);
|
||||
}
|
||||
doTree(tPtr->right);
|
||||
exit(1); break;
|
||||
default: if((close(pfd[0])) == -1) { /* Parent 2 */
|
||||
fprintf(stderr, "Could not close filedescriptor 0.(pipa)\n");
|
||||
exit(1);
|
||||
}
|
||||
if((close(pfd[1])) == -1) {
|
||||
fprintf(stderr, "Could not close filedescriptor 1.(pipa)\n");
|
||||
exit(1);
|
||||
}
|
||||
if((wait(&status)) == -1) {
|
||||
fprintf(stderr, "Could not wait.(pipa)\n");
|
||||
exit(1);
|
||||
}
|
||||
if((wait(&status)) == -1) {
|
||||
fprintf(stderr, "Could not wait.(pipa)\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*Hanterar semikolon, Kör vänster-delen om
|
||||
semikolonet, och när det är klart körs högerdelen*/
|
||||
void semi(treePtr tPtr) {
|
||||
int status;
|
||||
switch(fork()) {
|
||||
case -1: fprintf(stderr, "Fork failed. (semi)\n");break;
|
||||
case 0 : doTree(tPtr->left); /* Child */
|
||||
exit(1);
|
||||
break;
|
||||
default: if((wait(&status)) == -1) { /* Parent */
|
||||
fprintf(stderr, "Could not wait.(semi)\n");
|
||||
exit(-1);
|
||||
}
|
||||
if(tPtr->right)
|
||||
doTree(tPtr->right);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*Ställer om utmatningsfil från STDOUT till utfil
|
||||
Om filen finns, trunkeras den*/
|
||||
void great(treePtr tPtr) {
|
||||
int fd, status;
|
||||
if((fd=open(symTable[tPtr->right->index],O_CREAT|O_TRUNC|O_WRONLY, PERMS))==-1) {
|
||||
fprintf(stderr, "Could not open file. (great)\n");
|
||||
exit(1);
|
||||
}
|
||||
switch(fork()) {
|
||||
case -1: fprintf(stderr, "Fork failed\n"); break;
|
||||
case 0 : if((dup2(fd, 1)) == -1) { /* Child */
|
||||
fprintf(stderr, "Could not dup. (great)\n");
|
||||
exit(1);
|
||||
}
|
||||
doTree(tPtr->left);
|
||||
exit(1); break;
|
||||
default: if((wait(&status)) == -1) { /* Parent */
|
||||
fprintf(stderr, "Could not wait. (great)\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if((close(fd)) == -1) {
|
||||
fprintf(stderr, "Could not close file. (great)\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
/*Ställer om indirigering från STDIN till fil*/
|
||||
void less(treePtr tPtr) {
|
||||
int fd, status;
|
||||
if((fd=open(symTable[tPtr->right->index], O_RDONLY, PERMS))==-1){
|
||||
fprintf(stderr, "Could not open file (less)\n");
|
||||
return;
|
||||
}
|
||||
switch(fork()) {
|
||||
case -1: fprintf(stderr, "Fork failed\n"); break;
|
||||
case 0 : if((dup2(fd, 0)) == -1) { /* Child */
|
||||
fprintf(stderr, "Could not dup.(less)\n");
|
||||
exit(1);
|
||||
}
|
||||
doTree(tPtr->left);
|
||||
exit(1); break;
|
||||
default: if((wait(&status)) == -1) { /* Parent */
|
||||
fprintf(stderr, "Could not wait.(less)\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if((close(fd)) == -1) {
|
||||
fprintf(stderr, "Could not close file.(less)\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
/*Kör processer utan att de behöver invänta den andre*/
|
||||
void and(treePtr tPtr) {
|
||||
int status;
|
||||
switch(fork()) {
|
||||
case -1: fprintf(stderr, "Fork failed. (and)\n");break;
|
||||
case 0: if(tPtr->left) doTree(tPtr->left); /* Child */
|
||||
exit(0);
|
||||
break;
|
||||
default: if(tPtr->right) doTree(tPtr->right); /* Parent */
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*Ställer om utmatningsfil från STDOUT till utfil
|
||||
Om filen finns, appendas den*/
|
||||
void dblarr(treePtr tPtr) {
|
||||
int fd, status;
|
||||
if((fd=open(symTable[tPtr->right->index],O_CREAT|O_APPEND|O_WRONLY, PERMS))==-1) {
|
||||
fprintf(stderr, "Could not open file. (dblarr)\n");
|
||||
exit(1);
|
||||
}
|
||||
switch(fork()) {
|
||||
case -1: fprintf(stderr, "Fork failed\n"); break;
|
||||
case 0: if((dup2(fd, 1)) == -1) {
|
||||
fprintf(stderr, "Could not dup. (dblarr)\n");
|
||||
exit(1);
|
||||
}
|
||||
doTree(tPtr->left);
|
||||
exit(1); break;
|
||||
default: if((wait(&status)) == -1) {
|
||||
fprintf(stderr, "Could not wait. (dblarr)\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if((close(fd)) == -1) {
|
||||
fprintf(stderr, "Could not close file. (dblarr)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
/*Anropar rätt funktion beroende på metatecken*/
|
||||
void doTree(treePtr tPtr) {
|
||||
if(tPtr->nodeType == 0) cmd(tPtr);
|
||||
if(tPtr->nodeType == PIPE) pipa(tPtr);
|
||||
if(tPtr->nodeType == SEMI) semi(tPtr);
|
||||
if(tPtr->nodeType == GREAT) great(tPtr);
|
||||
if(tPtr->nodeType == LESS) less(tPtr);
|
||||
if(tPtr->nodeType == AND) and(tPtr);
|
||||
if(tPtr->nodeType == DBLARR) dblarr(tPtr);
|
||||
delTable();
|
||||
}
|
||||
/*Anropar Lex och Yacc med yyparse och sedan exeveras trädet*/
|
||||
int main() {
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
signal(SIGKILL, SIG_IGN);
|
||||
signal(SIGCHLD,SIG_IGN);
|
||||
signal(SIGINT,SIG_IGN);
|
||||
system("clear");
|
||||
write(1, "Welcome to WARPshell 1.0\n",26);
|
||||
while(1) {
|
||||
fflush(stdout);
|
||||
write(1,"C:\\> ",5);
|
||||
yyparse();
|
||||
if(tree) doTree(tree);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
34
Lab2/lab2.h
Normal file
34
Lab2/lab2.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Laboration 2 i C och UNIX
|
||||
*
|
||||
* Komplett shell
|
||||
* =========================================
|
||||
*
|
||||
* Christian Ohlsson, di7chro@cse.kau.se
|
||||
* Stefan Sonesson, di7stes@cse.kau.se
|
||||
*
|
||||
* Karlstads Universitet, 991209
|
||||
*
|
||||
*
|
||||
*===========================================
|
||||
*/
|
||||
#define SYMTBLSIZE 100
|
||||
#define PERMS 0644
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include "tree.h"
|
||||
#include "y.tab.h"
|
||||
|
||||
void doTree(treePtr tPtr);
|
||||
void pipa(treePtr tPtr);
|
||||
void semi(treePtr tPtr);
|
||||
void great(treePtr tPtr);
|
||||
void less(treePtr tPtr);
|
||||
void and(treePtr tPtr);
|
||||
void dblarr(treePtr tPtr);
|
||||
|
||||
35
Lab2/lexer.l
Normal file
35
Lab2/lexer.l
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Laboration 2 i C och UNIX
|
||||
*
|
||||
* Komplett shell
|
||||
* =========================================
|
||||
*
|
||||
* Christian Ohlsson, di7chro@cse.kau.se
|
||||
* Stefan Sonesson, di7stes@cse.kau.se
|
||||
*
|
||||
* Karlstads Universitet, 991209
|
||||
*
|
||||
*
|
||||
*===========================================
|
||||
*/
|
||||
%{
|
||||
#include "tree.h"
|
||||
#include "y.tab.h"
|
||||
%}
|
||||
|
||||
WORD [a-zA-Z0-9_\-\./\*]+
|
||||
|
||||
%%
|
||||
[ \t]+ {/*Käkar upp white-space*/}
|
||||
"\n" { insert(NULL); return NL;}
|
||||
"&" { insert(NULL); return AND;}
|
||||
"|" { insert(NULL); return PIPE;}
|
||||
";" { insert(NULL); return SEMI;}
|
||||
">" { insert(NULL); return GREAT;}
|
||||
"<" { insert(NULL); return LESS;}
|
||||
">>" { insert(NULL); return DBLARR;}
|
||||
"exit" { printf("OK, use the other stinky shell then...\n");exit(0);}
|
||||
{WORD} { yylval.txt=insert(yytext);return WORD;}
|
||||
. { fprintf(stderr,"What?\n",6);}
|
||||
%%
|
||||
|
||||
57
Lab2/parser.y
Normal file
57
Lab2/parser.y
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Laboration 2 i C och UNIX
|
||||
*
|
||||
* Komplett shell
|
||||
* =========================================
|
||||
*
|
||||
* Christian Ohlsson, di7chro@cse.kau.se
|
||||
* Stefan Sonesson, di7stes@cse.kau.se
|
||||
*
|
||||
* Karlstads Universitet, 991209
|
||||
*
|
||||
*
|
||||
*===========================================
|
||||
*/
|
||||
%{
|
||||
#include <stdio.h>
|
||||
#include "tree.h"
|
||||
extern treePtr tree;
|
||||
%}
|
||||
|
||||
%union {
|
||||
int txt;
|
||||
treePtr tPtr;
|
||||
};
|
||||
|
||||
%token NL PIPE SEMI GREAT LESS AND DBLARR EXIT
|
||||
%token<txt> WORD OPT
|
||||
%type<tPtr> rad ccmd scmd cmd
|
||||
|
||||
%start rad
|
||||
|
||||
%%
|
||||
rad : ccmd NL { tree=$1; return 0;}
|
||||
| NL { return 1;}
|
||||
;
|
||||
ccmd : ccmd PIPE scmd { $$=(treePtr)makeNode(PIPE, $1, $3); }
|
||||
| ccmd AND { $$=(treePtr)makeNode(AND, $1, NULL); }
|
||||
| ccmd SEMI scmd { $$=(treePtr)makeNode(SEMI, $1, $3); }
|
||||
| ccmd SEMI { $$=(treePtr)makeNode(SEMI, $1, NULL);}
|
||||
| scmd { $$=$1;}
|
||||
;
|
||||
scmd : scmd GREAT WORD { $$=(treePtr)makeNode(GREAT, $1, makeLeaf($3));}
|
||||
| scmd DBLARR WORD { $$=(treePtr)makeNode(DBLARR, $1, makeLeaf($3));}
|
||||
| scmd LESS WORD { $$=(treePtr)makeNode(LESS, $1, makeLeaf($3));}
|
||||
| cmd { $$=$1;}
|
||||
| error { $$=NULL;}
|
||||
;
|
||||
cmd : cmd WORD { $$=$1;}
|
||||
| WORD { $$=(treePtr)makeLeaf($1);}
|
||||
;
|
||||
%%
|
||||
|
||||
int yyerror() {
|
||||
fprintf(stderr, "\nSyntax error\n");
|
||||
tree=NULL;
|
||||
return 0;
|
||||
}
|
||||
6
Lab2/read_me
Normal file
6
Lab2/read_me
Normal file
@@ -0,0 +1,6 @@
|
||||
Laboration 2 i C och UNIX
|
||||
Komplett Shell
|
||||
Christian Ohlsson, di7chro@cse.kau.se
|
||||
Karlstads Universitet 991209
|
||||
|
||||
Labben är provkörd och klar!
|
||||
50
Lab2/tree.c
Normal file
50
Lab2/tree.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Laboration 2 i C och UNIX
|
||||
*
|
||||
* Komplett shell
|
||||
* =========================================
|
||||
*
|
||||
* Christian Ohlsson, di7chro@cse.kau.se
|
||||
* Stefan Sonesson, di7stes@cse.kau.se
|
||||
*
|
||||
* Karlstads Universitet, 991209
|
||||
*
|
||||
*
|
||||
*===========================================
|
||||
*/
|
||||
#include "tree.h"
|
||||
|
||||
treePtr tree=NULL;
|
||||
extern char *symTable[];
|
||||
|
||||
/*Skapar en nod med ett visst metatecken*/
|
||||
treePtr makeNode(int op,treePtr left,treePtr right) {
|
||||
treePtr tmp = malloc(sizeof(treeNode));
|
||||
tmp->nodeType = op;
|
||||
tmp->index = -1;
|
||||
tmp->right = right;
|
||||
tmp->left = left;
|
||||
return tmp;
|
||||
}
|
||||
/*Skapar ett löv som innehåller ett kommando*/
|
||||
treePtr makeLeaf(int index) {
|
||||
treePtr tmp = malloc(sizeof(treeNode));
|
||||
tmp->nodeType = 0;
|
||||
tmp->index = index;
|
||||
tmp->right = tmp->left = NULL;
|
||||
return tmp;
|
||||
}
|
||||
/*Skriver ut trädet på skärmen*/
|
||||
void printTree(treePtr tPtr){
|
||||
char str[10];
|
||||
if(tPtr == NULL) ;
|
||||
else{
|
||||
if(!tPtr->nodeType) /*Om det är ett löv...(kommando eller arg)*/
|
||||
sprintf(str,"%s---%d",symTable[tPtr->index],tPtr->nodeType);
|
||||
else /*Vi har ett metatecken!*/
|
||||
sprintf(str,"%d",tPtr->nodeType);
|
||||
puts(str);
|
||||
printTree(tPtr->left);
|
||||
printTree(tPtr->right);
|
||||
}
|
||||
}
|
||||
31
Lab2/tree.h
Normal file
31
Lab2/tree.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Laboration 2 i C och UNIX
|
||||
*
|
||||
* Komplett shell
|
||||
* =========================================
|
||||
*
|
||||
* Christian Ohlsson, di7chro@cse.kau.se
|
||||
* Stefan Sonesson, di7stes@cse.kau.se
|
||||
*
|
||||
* Karlstads Universitet, 991209
|
||||
*
|
||||
*
|
||||
*===========================================
|
||||
*/
|
||||
#ifndef _TREE_H
|
||||
#define _TREE_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
extern char *symTable[];
|
||||
/*Nod som finns i trädet*/
|
||||
typedef struct node{
|
||||
int nodeType;
|
||||
int index;
|
||||
struct node* left;
|
||||
struct node* right;
|
||||
}treeNode;
|
||||
|
||||
typedef treeNode *treePtr;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user