Hi, everybody. I need help with this: I'm writing a program that reads something like <path [argument1] [argument2] [...][&]> from the standard input and then tries to execute the program 'path' with arguments 'argument1', 'argument2',... This program will be executed in background if the last character of the line is '&' and in foreground other case. The thing is, when I write something like <p a b> I get the message:
*** glibc detected *** free(): invalid next size (normal): 0x0804a018
*** glibc detected *** free(): invalid next size (fast): 0x0804a018
Aborted
When I just write <p> or <p a> it works just fine, but when I try to pass two or more arguments it cracks. My code is the following (if you have any suggestion to improve it, please tell me - and be gentle: I'm not experienced and I use to make the dumbest mistakes :P):
Thanks a lot!Code:#include<unistd.h> #include<stdio.h> #include<stdlib.h> #define SIZEBUF 1024 typedef enum {FALSE=0, TRUE} bool; int main(int argc, char* argv[]){ char buffer[SIZEBUF]; char **arguments; char *path; int i, currentarg, numargs, bytesread; pid_t pid; bool background; if(setvbuf(stdout, NULL, _IONBF, 0)){ perror("error en setvbuf"); exit(-1); } while(1){ printf("\n-------------------------------\n"); printf("------- esperando input -------\n"); printf("-------------------------------\n\n"); //leemos de la entrada estándar if((bytesread = read(STDOUT_FILENO, buffer, SIZEBUF) - 1) < 0){ perror("error en el read"); exit(-1); } //cortamos el buffer por donde corresponda (el '\n') buffer[bytesread] = '\0'; if(!strcmp(buffer, "exit")) break; background = FALSE; if(buffer[bytesread-1] == '&'){ //comprobamos tiene que ejecutarse en background o no y quitamos el '&' (si lo hay) background = TRUE; bytesread--; buffer[bytesread] = '\0'; //cortamos el buffer por donde corresponda } printf("==========%s===========\n\n", background?"background":"foreground"); numargs = 1; for(i=0; i<bytesread; i++){ if(buffer[i] == ' ') //contamos el número de argumentos para saber cuánta memoria reservar numargs++; } arguments = malloc(numargs+1); currentarg = 1; arguments[0] = &(buffer[0]); for(i=0; i<bytesread; i++){ //creamos el vector de punteros a los argumentos if(buffer[i] == ' '){ arguments[currentarg] = &(buffer[i+1]); currentarg++; buffer[i] = '\0'; //separamos los argumentos por el carácter terminador ('\0') } } path = arguments[0]; arguments[numargs] = NULL; printf("path: %s\n", path);//quitar if((pid = fork()) < 0){ perror("error en el fork"); exit(-1); }else if(pid == 0){ //estamos en el hijo sleep(1); //ponemos un retraso para ver más claramente los efectos de ejecutarlo en background if(execv(path, arguments) < 0){ //ejecutamos el otro programa perror("error en execv"); exit(-1); } }else if(!background){//estamos en el padre y queremos ejecutar el hijo en foreground, así que... wait(NULL); //...esperamos a que termine } //si queríamos ejecutarlo en background (o si ya ha terminado) seguimos free(arguments); } return 0; }



LinkBack URL
About LinkBacks


