Question

Here is code that implements the cd system call using C. The problem with this code is that it's not entering the if condition if(strcmp(buffer,"cd") == 0) and I can't understand why.

#include<sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include<dirent.h>
#include<error.h>

#define BUFFERSIZE 20
int main(){

char *args[80]; 
char buffer[BUFFERSIZE];
char *prompt = "OS";
char *a = ">";
printf("%s%s",prompt,a); 
fgets(buffer, BUFFERSIZE, stdin);  

char *tok; 
tok = strtok (buffer," ");


while(buffer != NULL){ 
   buffer[strlen(buffer)-1] = '\0';  
   pid_t pid;
   pid = fork();
   if(pid < 0){
      fprintf(stderr, "Fork failed");
      return 1;
   }
   else if(pid == 0){

       if(strcmp(buffer,"cd") == 0){
         tok = strtok(NULL,"\n");
         cd(tok);
       }
       printf("%s%s",prompt,a); 
       fgets(buffer, BUFFERSIZE, stdin);
   }
   else{
     wait(NULL);
   }
}
return 0;
}


int cd(char *pth){
   char path[1000];
   strcpy(path,pth);

   static char *prompt = "OS";
   static char *a = ">";
   char *token;

   char cwd[256]; 
   getcwd(cwd,sizeof(cwd));

   strcat(cwd,"/"); 
   strcat(cwd,path);
   chdir(cwd);    

   printf("%s-%s%s",prompt,path,a);
   return 0;
  }
Was it helpful?

Solution

Have updated the logic after suggestions from others.

There is no need for a child process here. If you want multitasking then use threads. Child process may be required for process running in background.

The following program is working for me:

#include <stdio.h>

#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
//#include <error.h>

int hasPrefix(char const *, char const *);
int cd(char *pth);

#define BUFFERSIZE 200
int main(){

    char buffer[BUFFERSIZE];
    char *prompt = "OS";
    char *a = ">";

    char *tok;
    tok = strtok (buffer," ");


    while(buffer != NULL){
        bzero(buffer, BUFFERSIZE);
        printf("%s%s",prompt,a);
        fgets(buffer, BUFFERSIZE, stdin);
        if(hasPrefix(buffer,"cd") == 0){
            tok = strchr(buffer,' '); //use something more powerful
            if(tok) {
                char *tempTok = tok + 1;
                tok = tempTok;
                char *locationOfNewLine = strchr(tok, '\n');
                if(locationOfNewLine) {
                    *locationOfNewLine = '\0';
                }
                cd(tok);
            }
        }else{
            system("ls"); //for testing the CWD/PWD
        }
    }
    return 0;
}

int hasPrefix(char const *p, char const *q)
{
    int i = 0;
    for(i = 0;q[i];i++)
    {
        if(p[i] != q[i])
            return -1;
    }
    return 0;
}

int cd(char *pth){
    char path[BUFFERSIZE];
    strcpy(path,pth);

    char cwd[BUFFERSIZE];
    if(pth[0] != '/')
    {// true for the dir in cwd
        getcwd(cwd,sizeof(cwd));
        strcat(cwd,"/");
        strcat(cwd,path);
        chdir(cwd);
    }else{//true for dir w.r.t. /
        chdir(pth);
    }

    return 0;
}

OTHER TIPS

Use

...
if(strncmp(buffer,"cd",2) == 0){
...

instead. It is good for comparing prefixes of arbitrary length. It's also puts a limit on string size. No need to build your own comparison routine.

You have other problems elsewhere in the code, but those can be addressed separately.

I think the problem is because of this line:

buffer[strlen(buffer)-1] = '\0'; 

This replaces the last character of buffer with a null character. So if buffer contained "cd", it now contains just "c" (since the null character is the string terminator in C).

There doesn't seem to be any need for this statement, just remove it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top