简体   繁体   中英

Troubleshoot code implementing LS command like functionalities in C

I have drafted a code snippet that is to emulate the operation of ls -all in a custom shell named My$HELL The main shell process invokes this code(by calling its executable through execlp ).

Following is the code of the executable myls which is to do the work:-

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

Irrespective of the contents in the directory, the process displays certain fields after which the calling process terminates with a segmentation fault.

A GDB run is also of a little help (for being vague) and search on the error yields little result. Following is the debugged output:-

[~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

From what I could understand such error are results of illegal variable/pointer assignments. Any help in pointing out the bug is highly appreciated.

Am also appending code segment of the main process from where myls is being called

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

Cheers and thanks in anticipation!!

the following code :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM