Я делаю программу оболочки, которая использует execvp с вкладкой для выполнения моей команды.
Если я вставлю в оболочку "ls -l; ls", она должна выполнить exec "ls -l" (это работает) тогда "ls", но это делает "ls"
Моя вкладка будет иметь [ls \ 0] [- l \ 0], будет прекрасно работать
, тогда, если я попробую ls,моя вкладка: [ls \ 0] [\ 0], и она дает мне:
ls: невозможно получить доступ: нет такого файла или каталога
Как удалить этот последний [\ 0] дляесть только [ls \ 0] на моей вкладке?
Спасибо
РЕДАКТИРОВАТЬ: вот полный код, не могу сделать
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#define syserror(x) perror(errormsg[x])
#define fatalsyserror(x) syserror(x), exit(x)
#define ROUGE(m) "\033[01;31m"m"\033[0m"
#define VERT(m) "\033[01;32m"m"\033[0m"
#define FAILEDEXEC 127
#define DONTEXEC 128
#define ERR -1
#define SIZECMDLINE 4096
#define SIZE 1024
#define MAXCMD 10
#define PIPEFAILED 1
typedef struct statusProc {
int proc;
int value;
int failed;
} StatusProc;
StatusProc statusproc;
char * errormsg[] = {
"No error",
ROUGE("Impossible to fork process"),
ROUGE("Exec failed")
};
void traiterCmdInFork(char *cmd[SIZE]){
char *tab[SIZE],**ps;
int i=0;
tab[i]=cmd[i];
i++;
cmd++;
for(;*cmd && *cmd!='\0';i++,cmd++){
tab[i]=*cmd;
cmd++;
}
for (ps = tab; *ps; ps++) printf("r:%s ", *ps);
execvp(*tab, tab);
syserror(2);
exit(FAILEDEXEC);
}
int traiterInFather(char *cmd[SIZE]){
char currentdir[SIZE];
if(!strncmp(*cmd,"cd",2)){
chdir(*(cmd+1));
getcwd(currentdir, SIZE);
return 1;
} else if(!strncmp(*cmd,"status",6)){
if (!statusproc.proc){
printf("Aucune commande execute avant\n");
} else if(!statusproc.failed){
printf("%d termine avec comme code retour %d\n",statusproc.proc,statusproc.value);
} else {
printf("%d termine anormalement\n",statusproc.proc);
}
return 1;
}
return 0;
}
int main(void) {
char lgcmd[SIZECMDLINE], command[SIZE], *tabcmd[SIZE], currentdir[SIZE], *newcmd, *s, *tmp ,**ps;
pid_t p;
int i, j, nbcar, nbcmdprev, status, waitstatus, waitprev;
nbcmdprev=0;
//utiliser macro
for(;;) {
getcwd(currentdir, SIZE);
printf("%s>",currentdir);
memset(lgcmd,0,SIZECMDLINE);
fgets(lgcmd, SIZECMDLINE-1, stdin);
for(s=lgcmd; isspace(*s); s++);
s[strlen(s)-1]='\0'; //retire \n a la fin de la ligne de commande
printf("Command line:%s\n",s);
nbcar=0;
status=0;
waitprev=0;
waitstatus=0;
i=0;
newcmd=s;
printf("test");
for(;*s;s++,nbcar++){
//on avance jusqua fin dune commande
printf("R3");
if(*s==';' || *(s+1)=='\0' || *s=='|' || *s=='&'){ //traiter cas || et && et finligne
if(*s=='|' && *(s+1)=='|'){
*s++='\0';
waitprev=2;
} else if(*s=='&' && *(s+1)=='&'){
*s++='\0';
waitprev=1;
} else if(*(s+1)=='\0'){
s++;
nbcar++;
}
memset(command,0,strlen(command));
for (j = 0; j < nbcmdprev; j++) {
memset(tabcmd[j],0,strlen(tabcmd[j]));
printf("clear %d\n",j);
}
memcpy(command,newcmd,nbcar);
*s='\0';
for(tmp=command; isspace(*tmp); tmp++);
for(i=0; *tmp && tmp !=s; i++) {
tabcmd[i]=tmp;
//stopper le while quand on rencontre un ; ou & ou |
while (!isspace(*tmp) && *tmp!='\0' && *tmp!=';' && *tmp!='|' && *tmp!='&') {
printf("tmp:%c\n",*tmp);
tmp++;
}
//traiter &
if(*tmp=='|'){
waitprev=2;
*tmp++='\0';
break;
} else if(*tmp==';'){
waitprev=0;
*tmp++='\0';
break;
} else if(*tmp=='&'){
waitprev=1;
*tmp++='\0';
break;
} else if(*tmp!='\0'){
printf("tmp:%c\n",*tmp);
*tmp++='\0';
} else if(*tmp=='\0'){
printf("fin");
}
while (isspace(*tmp)) {
printf("tmp:%c\n",*tmp);
tmp++;
}
printf("tmp:%c\n",*tmp);
}
s++;
newcmd=s;
nbcar=0;
nbcmdprev=i;
if(!traiterInFather(tabcmd)){
printf("Dans if\n");
for (j = 0; j < i; j++) {
printf("len cmd%d:%d\n",j,strlen(*tabcmd));
}
p=fork();
if (p == ERR) fatalsyserror(1);
if(p) {
statusproc.proc=p;
wait(&status);
if(WIFEXITED(status)) {
if ((status=WEXITSTATUS(status)) != FAILEDEXEC) {
if(waitprev==1){
waitstatus = -1;
} else if(waitprev==2) {
waitstatus = -2;
} else {
waitstatus = 0;
}
printf(VERT("exit status of ["));
for (ps = tabcmd; *ps; ps++) printf("%s ", *ps);
printf(VERT("\b]=%d\n"), status);
//printf("\n");
statusproc.value=status;
statusproc.failed=0;
}
}
else {
statusproc.failed=1;
puts(ROUGE("Abnormal exit"));
}
} else {
printf("Command fork:");
for (ps = tabcmd; *ps; ps++) printf("-1-%s", *ps);
printf("\n" );
if((waitstatus==-1 && status==0) || (waitstatus==-2 && status!=0) ||(waitstatus==0 && status==0)){
traiterCmdInFork(tabcmd);
} else {
//stop le fils quand on ne doit pas executer commande
exit(DONTEXEC);
}
}
}
}
}
}
exit(0);
}
РЕДАКТИРОВАТЬ2: я добавилint arg to traiterCmdInFork
, например, число аргументов cmd (ls -a = 2), поэтому я копирую только туда, где есть текст, это решило мою проблему.
Спасибо за вашу помощь