在C中实现的Cd命令

时间:2014-03-09 19:05:18

标签: c

I have edited my code now and cd is working to a certain point. 

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


#define MAX_COMMAND_SIZE 80
#define MAX_ARGS 9
#define HIS_SIZE 100


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

int main()
{
    Command userCom = {0};                       //holds userCom struct
    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 = 0;
    int new;
    long size;
    int in = 0;
    int i;
    struct stat buff;                       //holds file information



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

    while(1){


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

    //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);
    }

    i =0;
    for (;i<tok;++i)

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

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

      else
        {
          userCom.arg[userCom.argument] = token[i];
          ++(userCom.argument);

        }
    }
        tok = 0;
        userCom.arg[userCom.argument] = 0;  


        if((strcmp(userCom.arg[0],"cd") == 0))
        {   
            if (userCom.argument > 2)
          printf("cd: Too many arguments\n");

          // change directories if valid target and update cwd

          else if (userCom.argument == 1)
        {
          new = chdir(cwd);
          if (new != 0)
              printf("%s: No such file or directory\n");

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

              else
            {
              new = chdir(curDirect);

              // 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 "cd" function

cd的第一个条目是正确的,但是当我第二次输入cd时,它应该停留在sgraham,而它应该在课堂上。 “结果”

sgraham @ myshell:/ home / class / sgraham / proj1&gt; cd ..

sgraham @ myshell:/ home / class / sgraham&gt; cd ..

sgraham @ myshell:/ home / class / sgraham&gt; cd .. cd:参数太多

3 个答案:

答案 0 :(得分:0)

使用-g编译程序,最终得到一个带有帧指针的可执行文件。

gcc -g -o test test.c
gdb ./test
[ ... ]
(gdb) run
Starting program: /home/vagrant/test

vagrant@myshell:/home/vagrant>cd /

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400afb in main () at test.c:114
114         if(strcmp(userCom.Listcomm[i],"cd") == 0)
(gdb) quit
A debugging session is active.

    Inferior 1 [process 8666] will be killed.

Quit anyway? (y or n) y

答案 1 :(得分:0)

所有userCom.Listcomm[i]都被初始化为NULL,并且在strcmp中使用之前从未再次更改,这会给您带来分段错误。

答案 2 :(得分:0)

您已将所有userCom.Listcomm[i]初始化为NULL。然后你试图对它进行strcmp。在比较字符串之前,你需要指出它。

为了有效地使用GDB,您需要使用-g编译代码。这意味着GCC将调试信息添加到您的代码中。您还可以使用其他更高级的选项(请参阅list of debugging options),但在这种情况下,-g会告诉您所需的一切。

在GDB中运行程序,您可以使用bt命令获取回溯。然后,您可以通过查看堆栈帧确切地查看程序崩溃的位置:

Program received signal SIGSEGV, Segmentation fault.
0xb7ea0b69 in strcmp () from /lib/libc.so.6
(gdb) bt
#0  0xb7ea0b69 in strcmp () from /lib/libc.so.6
#1  0x08048912 in main () at sigseg.c:114
(gdb) frame 1
#1  0x08048912 in main () at sigseg.c:114
114             if(strcmp(userCom.Listcomm[i],"cd") == 0)