Matt
Matt

Reputation: 53

Character arrays, and pointers how to use strtok and strcmp

I'm writing a linux shell for my operating systems class. I've knocked out the majority of it but I'm stuck on simple string comparisons. I've everything I can think of. strcmp should take in \0 terminated strings and return 0 for equal but that doesn't seem to be working and even stepping through the array and checking each char isn't working either. I currently have cmd[0] in the strcmp I know thats not right it needs to be null terminated but I've tried using strcpy and strcat \0 to another string. If someone could point out my mistake it would be much appreciated.

//Matthew Spiers
//CSC306

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

using namespace std;

void ckCmd(char dir[]);
int main(){

    pid_t pid;
    char cdstr[4] = "cd";
    char str[50];
    char *cmd[3];
    char *pstr;
    char temp[50];
    char dir[50] = "/bin/";
    while(1){
        pid = fork();
        if(pid < 0){
            fprintf(stdout, "Fork Failed");
        }
        else if(pid == 0){
            fprintf(stdout, "\e[36m306.SH>\e[0m");
            fgets(str, 50, stdin);  
            for(int i =0; i<50; i++){
                if(str[i] == '\n'){
                    str[i] = '\0';
                }
            }
            strcpy(temp, str); // Make a copy of original string
            cmd[0] = strtok(str, " ");
            for(int i =1; i<3; i++){
                cmd[i] = strtok(NULL, " ");
            }
            strcat(dir, cmd[0]);

            cout << cmd[0];

                    pstr = strtok(temp, " ");  //pull out only first token
            //Change Directory
            if(!strcmp(pstr, "cd")){ //if first token is cd
                //either branch to a routine just change directory
                //ie branch and change directory
            }
            //ckCmd(temp);

            execlp(dir, cmd[0], cmd[1], cmd[2], NULL);
            _exit(0);
        }
        else{
            wait(NULL);
        }
    }
}

void ckCmd(char str[]){
    char *p;
    p = strtok(str, " ");
    if(p[0] == 'c'){
        chdir("new");
    }
}

    enter code here

Upvotes: 0

Views: 1640

Answers (2)

Eli Bendersky
Eli Bendersky

Reputation: 273806

What exactly isn't working? Can you show a smaller code sample?

The line:

strcat(dir, cmd[0]);

Are you aware that dir is the target here and not cmd[0]?

The line: !strcmp(cmd[0], "cd") by itself is correct, but it's unclear what exactly you're trying to do. Could you comment each group of line with your intentions?


Update: I suggest that you're trying too many things at once. To home in on your problem I recommend the following steps:

  1. Understand how strtok works. It isn't very hard - read its manual and then try it in a separate file with some strings. This should give you a good idea.
  2. Break parts of your code out and provide them with pre-set input (not from the user and without the forking). See where the behavior is as expected and where it drifts off.

Upvotes: 0

user411313
user411313

Reputation: 3990

strtok is not reentrant/thread-safe! You should use the RETURN-value from strtok:

p = strtok(str, " ");
    if(p[0] == 'c'){

cmd[0] = strtok(str, " ");
...
if(!strcmp(cmd[0], "cd")){

If p/cmd[0] is NULL, it will crash.

Upvotes: 1

Related Questions