Mam za zadanie napisać uproszczonego shella - to w skrócie. Mam jednak problem z pobieraniem komend wraz z argumentami.
Próbuję sił z funkcją strtok(), jednak nieco mnie ona zawodzi i nie wiem, czy sprawdzi się przy mniejszej/większej liczbie argumentów, niż z góry zakładam w kodzie (miejsce na 3).
Już trochę kombinuję - bez zadowalającego rezultatu.
Edit. Częściowo problem został rozwiązany. Jednak przy liczbie argumentów mniejszej niż max, ostatni z nich dostaje znak nowej linii na końcu. Psuje mi to szyki, gdyż podstawowe komendy takie jak np. 'history', nie działają teraz dopóki nie dodam nowego argumentu. +Zaktualizowałem kod niżej.
Kod:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
//#include <sys/wait.h> //linux
#include <fcntl.h>
#include <time.h>
#include <string.h>
#define HST ".history"
int cmd2int(char * cmd) {
if(strcmp(cmd,"cd")==0) return 1;
else if(strcmp(cmd,"run")==0) return 2;
else if(strcmp(cmd,"history")==0) return 3;
else if(strcmp(cmd,"quit")==0) return 0;
else return 999;
}
void history(char command[]) { //funkcja odpowiadająca za zapisanie polecenia do historii
//chdir("C:\\"); //zamienić na kropkę
FILE * hfile;
hfile=fopen(HST, "a");
if(!hfile) {
printf ("Nie mogę otworzyć pliku .historia do zapisu!\n");
exit(1);
}
fprintf (hfile,"%s\n", command);
fclose (hfile);
}
/* void run(char arg1, char arg2, char arg3) { //exclusvie linuxa
int nr_proc;
nr_proc=fork();
if(nr_proc>0)
{
printf("\nwykonano");
}
else execlp(command,0);
} */
void showhistory() {
//chdir("C:\\"); //zamienić na kropkę
FILE * hfile;
char bufor[256];
char z;
hfile=fopen(HST, "r");
if(!hfile) {
printf("Nie mogę otworzyć pliku .historia do odczytu lub plik jeszcze nie istnieje!\n");
exit(-1);
}
while(fgets(bufor,256,hfile)) {
printf("%s", bufor);
}
fclose(hfile);
scanf("%c",&z);
}
int main() {
const int MAX_SIZE=1024;
char command[MAX_SIZE];
int icmd=1;
char * cmd;
char * arg1;
char * arg2;
char * arg3;
while (icmd != 0) { //główna pęta do wczytywania komendy;
printf("./Przykladowa Sciezka/\$:");
//printf("%s",getcwd(path,MAX_SIZE));
fgets(command, MAX_SIZE, stdin);; //pobieranie polecenia
history(command);
cmd=strtok(command," ,.-");
printf("Komenda: %s\n",cmd);
arg1=strtok(NULL," ,.-");
printf("Argument 1: %s\n",arg1);
arg2=strtok(NULL," ,.-");
printf("Argument 2: %s\n",arg2);
arg3=strtok(NULL," ,.-");
printf("Argument 3: %s\n",arg3);
int i=0;
for(i=0;i<strlen(cmd);i++)
{
if(*(cmd+i)='\n') *(cmd+i)='\0';
}
icmd=cmd2int(cmd); //icmd = wersja int polecenia
switch(icmd) { //obsługa polecenia
case 1: //cd
chdir(arg1);
break;
case 2: //run
//run(arg1,arg2...);
break;
case 3: //history
showhistory();
break;
case 4: //
break;
case 0:
icmd=0;
break;
default:
printf("Take polecenie nie istnieje\n");
break;
}
printf("\n");
}
return 0;
}
Lub wersja aktualizowana na bieżąco: https://www.dropbox.com/s/0jpob5fay5ojj4j/shell.h
Pomysły?
Po rozwiązaniu tego problemu pewnie zaczniemy wałkować następny.
Edit. Częściowo problem został rozwiązany. Jednak przy liczbie argumentów mniejszej niż max, ostatni z nich dostaje znak nowej linii na końcu. Psuje mi to szyki, gdyż podstawowe komendy takie jak np. 'history', nie działają teraz dopóki nie dodam nowego argumentu.