Find the answer to your Linux question:
Results 1 to 6 of 6
I am having trouble with a shell that I am writing for fun. When I type the following: I get the error at the end: Code: /home/me/code/ish - ish-0.1> ls ...
  1. #1
    Just Joined!
    Join Date
    Sep 2008
    Posts
    8

    Writing my own shell

    I am having trouble with a shell that I am writing for fun. When I type the following:
    I get the error at the end:
    Code:
    /home/me/code/ish - ish-0.1> ls
    a.out main.c
    /home/me/code/ish - ish-0.1> cd ..
    /home/me/code - ish-0.1> ls
    ls: cannot access : no such file or directory
    Why doesn't it work? Here is my code:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    
    #define N_ARGS 64
    #define L_IS 256
    #define L_OS 1024
    #define L_ARG 32
    
    #define PROMPT "ish-0.1> "
    
    char *pa[N_ARGS]; // Parsed Arguments
    char *is; // Input String
    char *ts; // Temp String
    char *cwd; // current working dir
    
    int main(int argc, char *argv[], char *envp[])
    {
    	cwd = (char *)malloc(L_IS);
    	is = (char *)malloc(L_IS);
    	int err = 1;
    	int i = 1;
    
    	while(1)
    	{
    		// Reset all variables/strings/arrays
    		memset(is, 0, L_IS);
    		for (i = 0; i < N_ARGS && pa[i] != NULL; i++)
    			if (pa[i] != NULL)
    				memset(pa[i], 0, strlen(pa[i]));
    		i = 1;
    
    		// Print the prompt and get user input
    		getcwd(cwd, L_IS);
    		printf("%s - %s", cwd, PROMPT);
    		fgets(is, L_IS, stdin);
    		*(strchr(is, '\n')) = 0;
    
    		// Parse the user input
    		for (pa[0] = strtok(is, " "); ts = strtok(NULL, " "); i++)
    			pa[i] =  ts;
    
    		// Take care of 'special' shell-defined commands
    		if (strstr(pa[0], "exit") != NULL)
    			return 0;
    		else if (strstr(pa[0], "cd") != NULL)
    		{
    			chdir(pa[1]);
    			continue;
    		}
    
    		// Execute the 'real' commands
    		if (fork() == 0)
    		{
    			err = execvp(pa[0], pa);
    			if (err < 0)
    				printf("%s is not a known command\n", pa[0]);
    			exit(1);
    		}
    		else
    			wait(1); // Give the process time to start
    	}
    
    	return 0;
    }

  2. #2
    Linux Enthusiast gerard4143's Avatar
    Join Date
    Dec 2007
    Location
    Canada, Prince Edward Island
    Posts
    714
    I just tried you code and it worked on my machine....That is I ran it and tried ls then cd .. ls and it produced correct results...Gerard4143
    Make mine Arch Linux

  3. #3
    Just Joined!
    Join Date
    Sep 2008
    Posts
    8
    Can I see the output of your 'which cd' please?

  4. #4
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
    Posts
    8,974
    A couple of problems.

    1. When you reset your variables, you need to set the entries of array pa[i] to NULL, not to memset each non-null entry. You do that when you memset(is, 0, L_IS) before. What you are doing is leaving dirty pointers in the array.
    Code:
     for (i = 0; i < N_ARGS; i++) { pa[i] = 0; }
    2. When you parse the user input, you should either change your loop or explicitly NULL terminate the array.
    Code:
    for (i = 0, ts = strtok(is, " "); ts != 0; i++)
    {
        pa[i] = ts;
        ts = strtok(NULL, " ');
    }
    pa[i] = 0;
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  5. #5
    Just Joined!
    Join Date
    Sep 2008
    Posts
    8
    Thank you rubberman. That worked.

  6. #6
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
    Posts
    8,974
    Quote Originally Posted by lexion View Post
    Thank you rubberman. That worked.
    Glad to help. There are a lot of placed in C code where null termination of arrays of pointers is critical, otherwise you end up munging your memory, or try to access invalid memory, resulting in a segfault.
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...