Whats wrong with this basic shell program? it will run fine for the first few commands but results always ends in a seg fault

StackOverflow https://stackoverflow.com/questions/21391425

  •  03-10-2022
  •  | 
  •  

Pergunta

I have to build a simple shell program using lex and c code. The lex portion is for breaking down the input. It has been provided for me and I'm not expected to change it. I'm in the process of getting my code to run basic commands like "ls". It seems to work the first few times I run the command but eventually always seg faults. Here is the lex code provided:

%{
int _numargs = 10;
char *_args[10];
int _argcount = 0;
%}

WORD [a-zA-Z0-9\/\.-]+
SPECIAL [()><|&;*]

%%
_argcount=0; 
_args[0]=NULL; 

{WORD}|{SPECIAL} { 
if(_argcount < _numargs-1) {
_args[_argcount++]= (char *)strdup(yytext);
_args[_argcount]= NULL;
}
}

\n return (int)_args;

[ \t]+

.

%%

char **getln() {
return (char **)yylex();
}

This is the C code:

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

extern char **getln();

int main() {
    int i;
    char **args; 
    int child1;
    int status1;
    int counter=0;
    int argCount = 1;

    char **array = (char **)malloc(1500 * sizeof(char *));
    for (i = 0; i < 1500; ++i) {
        array[i] = (char *)malloc(500);
    }
    strcpy(array[0],"ls\0");
    array[1] = NULL;

    while(1) {
        args = getln();
        printf("is error here?");
        strcpy(array[0], args[counter]);

        for(i = (counter+1); args[i] != NULL; i++) {
            printf("\nRight before copying to subarray");
            strcpy(array[argCount], args[i]);
            argCount++;
        }

        array[argCount] = NULL;

        if (strcmp(args[counter],"exit")==0) exit(0);

        child1 = fork();
        if(child1==0){

            execvp(array[0], array);
            printf("Unknown command, please try again.");
            exit(1);
        }
        else{
            while (wait(&status1) != child1);
        }

        for(i = 0; args[i] != NULL; i++) {
            printf("Argument %d: %s\n argCount: %d", i, args[i], argCount);
        }
        argCount = 1;
        counter++;
    }
} 

Thanks in advance for any advice. If there is some simple way to adjust the getln() function to overwrite the args array each time it is called that might be easier than what I am attempting but I have no idea how to go about that.

Foi útil?

Solução

It seems like you have put

_argcount=0;
_args[0]=NULL;

at the top of the rules section in hopes that these statements would be executed at the beginning of yylex(). And you've noticed that they aren't executed (it keeps appending to the previous values because _argcount never goes back to 0).

The obvious thing to do is move those statements into getln() just before the yylex().

What you have now is a lexer that will ignore the string _argcount=0; in the input because it will match that pattern and there's no action to go with it. The second line is even cooler since the [0] is a character class. It makes the lexer ignore the string _args0=NULL;

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top