cd just stays at this state:
sgraham@myshell:/home/class/sgraham>cd ..

sgraham@myshell:/home/class/sgraham>cd ..

typedef struct
{
  int argument;                             // userCom arguments
  char *arg[MAX_ARGS + 1];                  // userCom arguments array 
  char *Listcomm[MAX_COMMAND_SIZE];
  char *input;                          // hold input file
  char *output;                        // hold output file
} Command;

int main()
{
    Command userCom;                         //holds userCom struct
    //const char* cwd;                       //holds current directory
    const char *whitespace = " \n\r\t\v\f";   // userCom delimiting chars
    char* username = getenv("USER");         //Get user name 
    char* curDirect = getenv("HOME");        //get cwd
    char* token[MAX_ARGS];                           
    char* cwd;
    char* buf;
    char buffer[MAX_COMMAND_SIZE + 1];       //hold userCom line
    int tok,i = 0;
    int new;
    long size;

    //struct stat buff;                     //holds file information



    while(1){


    for(i; i < MAX_COMMAND_SIZE; i++)
    userCom.Listcomm[i] = NULL;

    userCom.argument = 0;
    userCom.input = NULL;
    userCom.output = NULL;

    //prints users prompt 
    printf("\n%s@myshell:%s>", username,curDirect); 

    //gets string from userCom line
    fgets(buffer, MAX_COMMAND_SIZE + 1, stdin);


    //parses tokens and looks for delimiters 
    token[tok] = strtok(buffer,whitespace);
    while(token[tok])
    {
        ++tok;
        if(tok == MAX_ARGS)
        printf("Reached max userCom arguments");
        break;

        token[tok] = strtok(NULL, whitespace);
    }

    while(i < tok)
    {
        if(strcmp(token[i], "<") == 0)
            {
             userCom.input = token[++i];
            }
        else if(strcmp(token[i], ">") == 0)
        {
            userCom.output = token[++i];
        }
        else if (token[i][0] == '$')
        {
          char* var = getenv((const char*)&token[i][1]);

          if (!var)
            {
              printf("%s: ERROR: variable.\n", token[i]);
              return 0;
            }
          else
            {
              userCom.arg[userCom.argument] = var;
              ++(userCom.argument);
            }
        }

      else
        {
          userCom.arg[userCom.argument] = token[i];
          ++(userCom.argument);
        }
    }
        userCom.arg[userCom.argument] = 0;
        token[tok] = strtok(NULL,whitespace);
    i++; 

    }//token while loop 

    i = 0; 
    if((strcmp(userCom.Listcomm[i],"cd") == 0))
    {
        if (userCom.argument > 2)
        {
          printf("cd: Too many arguments\n");
          i++;
        }
          // change directories if valid target and update cwd

          else if (userCom.argument == 2)
        {
          i++;
          new = chdir(userCom.Listcomm[i]);
          if (new != 0)
              printf("%s: No such file or directory\n");

          else
            {
              // get the new current working directory

              size = pathconf(".", _PC_PATH_MAX);
              if ((buf = (char *)malloc((size_t)size)) != NULL)
            cwd = getcwd(buf, (size_t)size);
            }
        }

          // if no argument is given, new directory should be $HOME

          else
        {
          new = chdir(getenv("HOME"));

          // get the new current working directory
          size = pathconf(".", _PC_PATH_MAX);
          if ((buf = (char *)malloc((size_t)size)) != NULL)
            cwd = getcwd(buf, (size_t)size);
        }

    }//end while loop 

    return 0; 
}//End Main loop 

If you look at the braces in your program, The while loop declared at line 29 ends at line 94, which is commented as "End token loop".

So you are stuck in an endless loop where you are just getting input from the user. The code in the 2nd half of your program is not getting called because the program is never getting there.

I think you meant for this particular loop to enclose the whole program. So you might want to consider checking the indentation of your program and taking a good look at the braces that start and end the various blocks of the program and ensure they are all where they should be!

From looking at your program, I'd say that you need to remove the closing brace at line 89 and indent the closing brace at line 94
Also add a closing brace at line 139 to end the program, and indent the closing brace at line 138, because that will now close the main while loop, which matches the comment made against that line.

That would appear to be the problem from what I can see!

Edited 2 Years Ago by JasonHippy

the cd command should be doing this once typed

actual result:
sgraham@myshell:/home/class/sgraham/temp>cd ..
sgraham@myshell:/home/class/sgraham>cd ..
sgraham@myshell:/home/class>cd ..
sgraham@myshell:/home>

My result:
sgraham@myshell:/home/class/sgraham>cd ..

sgraham@myshell:/home/class/sgraham>cd ..

sgraham@myshell:/home/class/sgraham>cd ..

A couple of other things I just noticed:
The variable tok is never initialised before it is first used. I recommend intitialising it to zero at initialisation or before its first use.

Also variable i is declared once and used at several places in the code, no problem with that. It is first used at lines 32 and 33, but it is not reset to 0 before it is used at line 58. Which doesn't look right. I think that should be reset at line 57. You are correctly resetting it at line 96, but it should also be reset at line 57!

Another thing that looks fishy is the strcmp at line 97:
From what I can see, userCom.Listcomm never appears to be populated with anything. So you'll end up with either no result, or a crash at runtime with that line (depending on what happens when a null string is passed as a parameter to strcmp! - Not sure offhand!)

So it looks like there might be some fuzzy logic at play in your program too!

I understand what you are trying to do, it is a simple Unix/Linux like terminal clone.

The answer to the first part of your puzzle lies in the comments in my original post. Fix the indentation in your code, double check all of the start and end braces in your code (I'm 99.9% certain that you'll find that the closing brace at line 89 doesn't need to be there and that you require a additional closing brace at the end of your program)

With those changes in place, your program will be able to get out of the tokenisation code and into the part of the code which parses and executes the command entered by the user.

Once you've got to that point, you'll need to make some additional changes to your code. Because as it stands it will not work AFAICT! I haven't gone to any lengths to actually test your code. But it looks like it needs a little more work, as mentioned in my 2nd post!

Edited 2 Years Ago by JasonHippy

This article has been dead for over six months. Start a new discussion instead.