Shell in C: Segmentation error and execve function, what's wrong? [closed]

0
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>

void type_prompt(){
    printf("\n$~");
}


void read_command(char command[], char *parameters[]){
    char linha[100] = "";
    fgets(linha, 100, stdin);

    int i;
    int flag = 0;
    for (i = 0; i <= strlen(linha); i++){
        if (linha[i] == ' '){
            flag = 1;
            break;
        }
    }

    char *word = strtok(linha, " ");
    strcat(command, "/bin/");
    strcat(command, word);
    parameters[0] = word;

    if (flag == 1) command[strlen(command)] = '
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>

void type_prompt(){
    printf("\n$~");
}


void read_command(char command[], char *parameters[]){
    char linha[100] = "";
    fgets(linha, 100, stdin);

    int i;
    int flag = 0;
    for (i = 0; i <= strlen(linha); i++){
        if (linha[i] == ' '){
            flag = 1;
            break;
        }
    }

    char *word = strtok(linha, " ");
    strcat(command, "/bin/");
    strcat(command, word);
    parameters[0] = word;

    if (flag == 1) command[strlen(command)] = '%pre%';
    else command[strlen(command) - 1] = '%pre%';

    if (flag == 1){
        while (word != NULL){
            word = strtok(NULL, " ");
            strcat(*parameters, word);
        }
    }
}

int main (){
    char command[] = {""};
    char *parameters[100] = {NULL}; //argv
    char *env[]={"PATH=/usr/local/sbin/:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games",NULL};
    int status;

    while (1){
        type_prompt();
        read_command(command, parameters);

        if (fork() != 0){
            command[0] = '%pre%';
            parameters[0] = '%pre%';
            waitpid(-1, &status, 0);
        }

        else {  
            execve(command, parameters, env);
            command[0] = '%pre%';
            parameters[0] = '%pre%';
            printf("Erro execve %d: %s\n", errno, strerror(errno));
        }
    }
}
'; else command[strlen(command) - 1] = '%pre%'; if (flag == 1){ while (word != NULL){ word = strtok(NULL, " "); strcat(*parameters, word); } } } int main (){ char command[] = {""}; char *parameters[100] = {NULL}; //argv char *env[]={"PATH=/usr/local/sbin/:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games",NULL}; int status; while (1){ type_prompt(); read_command(command, parameters); if (fork() != 0){ command[0] = '%pre%'; parameters[0] = '%pre%'; waitpid(-1, &status, 0); } else { execve(command, parameters, env); command[0] = '%pre%'; parameters[0] = '%pre%'; printf("Erro execve %d: %s\n", errno, strerror(errno)); } } }
    
asked by anonymous 13.04.2018 / 17:52

1 answer

0

There are several errors, the basic problem is that you are manipulating the vector parameters in the wrong way, and also throwing in the "string" strings, which is a variable that disappears as soon as the read_command () function returns. / p>

Below is a "diff" of lines that I changed to make it work. The program is still not perfect because strdup () allocates memory in the heap and repeated execution will leak memory because new parameters are thrown into "parameters" without destroying the old ones, but at least the program does not break anymore, and works as expected .

-void read_command(char command[], char *parameters[]){
-    char linha[100] = "";
+void read_command(char command[], char **parameters){
+    char linha[100];
+    linha[0] = '
-void read_command(char command[], char *parameters[]){
-    char linha[100] = "";
+void read_command(char command[], char **parameters){
+    char linha[100];
+    linha[0] = '%pre%';
     fgets(linha, 100, stdin);

+    // remove o "enter"
+    linha[strlen(linha) - 1] = '%pre%';
+
+    printf("compr linha %d\n", strlen(linha));
+    if (strlen(linha) < 1) {
+        printf("saindo\n");
+        exit(0);
+    }
+
     int i;
     int flag = 0;
     for (i = 0; i <= strlen(linha); i++){
@@ -27,22 +37,24 @@
     char *word = strtok(linha, " ");
     strcat(command, "/bin/");
     strcat(command, word);
-    parameters[0] = word;
-
-    if (flag == 1) command[strlen(command)] = '%pre%';
-    else command[strlen(command) - 1] = '%pre%';
+    *parameters = strdup(command);
+    printf("comando: '%s'\n", command);

     if (flag == 1){
         while (word != NULL){
             word = strtok(NULL, " ");
-            strcat(*parameters, word);
+            if (word) {
+           printf("parametro: '%s'\n", word);
+                *(++parameters) = strdup(word);
+            }
         }
     }
+    *(++parameters) = NULL;
 }

 int main (){
     char command[] = {""};
-    char *parameters[100] = {NULL}; //argv
+    char *parameters[100];
     char *env[]={"PATH=/usr/local/sbin/:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games",NULL};
     int status;

@@ -52,14 +64,12 @@

         if (fork() != 0){
             command[0] = '%pre%';
-            parameters[0] = '%pre%';
             waitpid(-1, &status, 0);
         }

         else {  
             execve(command, parameters, env);
             command[0] = '%pre%';
-            parameters[0] = '%pre%';
             printf("Erro execve %d: %s\n", errno, strerror(errno));
         }
     } 
'; fgets(linha, 100, stdin); + // remove o "enter" + linha[strlen(linha) - 1] = '%pre%'; + + printf("compr linha %d\n", strlen(linha)); + if (strlen(linha) < 1) { + printf("saindo\n"); + exit(0); + } + int i; int flag = 0; for (i = 0; i <= strlen(linha); i++){ @@ -27,22 +37,24 @@ char *word = strtok(linha, " "); strcat(command, "/bin/"); strcat(command, word); - parameters[0] = word; - - if (flag == 1) command[strlen(command)] = '%pre%'; - else command[strlen(command) - 1] = '%pre%'; + *parameters = strdup(command); + printf("comando: '%s'\n", command); if (flag == 1){ while (word != NULL){ word = strtok(NULL, " "); - strcat(*parameters, word); + if (word) { + printf("parametro: '%s'\n", word); + *(++parameters) = strdup(word); + } } } + *(++parameters) = NULL; } int main (){ char command[] = {""}; - char *parameters[100] = {NULL}; //argv + char *parameters[100]; char *env[]={"PATH=/usr/local/sbin/:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games",NULL}; int status; @@ -52,14 +64,12 @@ if (fork() != 0){ command[0] = '%pre%'; - parameters[0] = '%pre%'; waitpid(-1, &status, 0); } else { execve(command, parameters, env); command[0] = '%pre%'; - parameters[0] = '%pre%'; printf("Erro execve %d: %s\n", errno, strerror(errno)); } }
    
13.04.2018 / 19:22