解决实现LS命令的代码,例如C中的功能

时间:2015-08-14 14:31:02

标签: c linux shell ls

我已经起草了一个代码片段,用于在名为 My $ HELL 的自定义shell中模拟 ls -all 的操作 主shell进程调用此代码(通过 execlp 调用其可执行文件)。

以下是可执行文件 myls 的代码: -

myls.c

#include <stdio.h>     
#include <stdlib.h>    
#include <sys/types.h>  
#include <dirent.h>    
#include <sys/stat.h> 
#include <time.h>


void search_dir(const char * arg); 

void main(int argc, char *argv[])
{
    int i;  
    if (argc==1)
        search_dir(".");
    for(i=1;i<argc;i++)
        search_dir(argv[i]);
}

 void search_dir(const char *arg)//Function to read directories and file attributes//
{
    DIR *dirp;
    struct dirent *dp;//Dirent structure used to read and store directory attributes//
    char file_name[256];
    char time[50]={"\0"};
    struct tm *timeinfo;
    struct stat prop_file;//stat function for accessing file attributes//
    char type;

    if((dirp=opendir(arg))==NULL)
    {
        perror("opendir");
        return;
    }

    printf("\n\nDirectory \tTime last Modified\tSize\t\t  Name\n");
    while((dp=readdir(dirp))!=NULL) // Navigates the directory structure
    {

        if ( stat(dp->d_name,&prop_file)!=0) //Reading file attributes//
        {
            printf("\n%s:Error in reading the file attributes", dp->d_name );   
            continue;
        }
        if ( dp->d_type==8 )
        {
            type = '-';
        }
        else
        {
            type = 'd';
        }
        timeinfo=localtime(&(prop_file.st_mtime));
        strftime(time,20,"%b %d %H:%M", timeinfo);
        printf("\n %c\t\t %s\t\t%d\t\t %s",type,time,(int)prop_file.st_size,dp->d_name); //Printing ile attributes//
    }
    printf("\n");
}

无论目录中的内容如何,​​该过程都会显示某些字段,之后调用过程将以分段错误终止。

GDB运行也有一点帮助(因为模糊)并且对错误的搜索几乎没有结果。以下是调试输出: -

[~pbox/working/trial]<My$HELL>myls
Executing myls


Directory   Time last Modified  Size          Name

 d       Aug 14 19:22       4096         ..
 d       Aug 14 18:42       4096         .
[~pbox/working/trial]<My$HELL>

Program received signal SIGSEGV, Segmentation fault.
strlen () at ../sysdeps/x86_64/strlen.S:106
106 ../sysdeps/x86_64/strlen.S: No such file or directory.
(gdb) Quit

据我所知,这种错误是非法变量/指针分配的结果。任何帮助指出该错误的人都非常感激。

我还附加了主要流程的代码段,其中 myls 被调用

的main.c

.
.
    else if(strcmp(command[0],"myls")==0)   //command of type char ** stores the user input command check if the first field is 'myls'//        
                {
                    printf("Executing myls\n");
                    strcat(path,"/myls"); //path stores the directory path
                    result=execvp(path,command); //result of type int
                    exit(0);
                }   
.
.

在期待中欢呼和感谢!!

1 个答案:

答案 0 :(得分:-1)

以下代码:

1) cleanly compiles
2) handles errors in an appropriate manner
3) does the job correctly
4) does not follow symbolic links
5) does not display the proper file type for every file
6) when accessing directories that are (in any way) protected
   from casual reading, will output an error message
7) properly builds the path+filename before calling stat()
8) properly declares main() function and proper return
9) does not handle any options that are passed in.
10)does not seg fault



#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <time.h>
#include <string.h>


void search_dir(const char * arg);

int main(int argc, char *argv[])
{
    int    i;
    char   dirBuf[128] = {'\0'};
    char * newline = NULL;

    if (argc==1)
        search_dir(".");
    else
    {
        for(i=1;i<argc;i++)
        {
            newline = strcpy( dirBuf, argv[i] );
            if( strstr( dirBuf, "\n") )
            {
                 *newline = '\0';
            }
            search_dir(dirBuf);
        }
    }
    return 0;
}

 void search_dir(const char *arg)//Function to read directories and file attributes//
{
    DIR *dirp;
    struct dirent *dp;//Dirent structure used to read and store directory attributes//
    char fileName[256];
    char fileTime[50]={"\0"};
    struct tm *timeinfo;
    struct stat prop_file;//stat function for accessing file attributes//
    char type;

    printf( "%s\n", arg);

    if( NULL == (dirp=opendir(arg)) )
    {
        perror("opendir failed");
        return;
    }

    // implied else, opendir successful

    printf("\n\nDirectory \tTime last Modified\tSize\t\t  Name\n");

    while( NULL != (dp=readdir(dirp)) ) // gets next entry in current directory,
    {
        strcpy(fileName, arg);
        strcat(fileName, "/");
        strcat(fileName, dp->d_name);
        printf( "\nfileName: %s", fileName);

        if ( stat(fileName,&prop_file) ) //Reading file attributes//
        {
            perror( "stat failed" );
            printf("\n%s:Error in reading the file attributes", dp->d_name );
            continue;
        }

#ifdef _DIRENT_HAVE_D_OFF
        // following if/else needs expansion
        if ( dp->d_type==8 )
        {
            type = '-';
        }

        else
        {
            type = 'd';
        }
#else
        type = '?';
#endif

        timeinfo=localtime(&(prop_file.st_mtime));
        strftime(fileTime, 49, "%b %d %H:%M", timeinfo);
        printf("\n %c\t\t %s\t\t%d\t\t %s",
            type,
            fileTime,
            (int)prop_file.st_size,
            dp->d_name); //Printing file attributes//
    }
    printf("\n");
    closedir( dirp );
}