Featured Post

Trie implementation in C

'ls' command implementation for Linux/Unix in C

This program simulates the simple list directory 'ls' command in Unix. It uses the inbuilt system calls to create this functionality.

#include <sys/types.h>
#include <sys/dir.h>
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>

#define FALSE 0
#define TRUE !FALSE

extern  int alphasort(); //Inbuilt sorting function

char pathname[MAXPATHLEN];

void die(char *msg)
{
  perror(msg);
  exit(0);
}

int file_select(struct direct *entry)
{
    if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0))
        return (FALSE);
    else
        return (TRUE);
}

int main()
{
    int count,i;
    struct direct **files;

    if(!getcwd(pathname, sizeof(pathname)))
        die("Error getting pathname\n");

    printf("Current Working Directory = %s\n",pathname);
    count = scandir(pathname, &files, file_select, alphasort);

    /* If no files found, make a non-selectable menu item */
    if(count <= 0)
      die("No files in this directory\n");
    
    printf("Number of files = %d\n",count);
    for (i=1; i<count+1; ++i)
        printf("%s  ",files[i-1]->d_name);
    printf("\n"); /* flush buffer */
}

Comments

  1. Dear Varun, this code looks amazing. very practical. however i was wondering how you would implement it if a path was given instead of current directory. or how you would implement -l
    do you know how you would change this approach. i imagined if (argc == 1)
    printContent(".", NULL);
    if (argc == 2) {
    dashl = argv[1];
    printContent(dashl, NULL);
    }

    if (argc == 3) {
    dashl = argv[1];
    path = argv[2];
    if (strcmp(dashl, "-l")) {
    printf("Invalid argument\n");
    return 0;
    } else {
    printContent(dashl, path);
    }

    }
    else {
    printf("Invalid number of arguments.\n");
    return 0;
    }
    and then calling print content for differnt argument numbers. could u help with that part?

    ReplyDelete
    Replies
    1. It's quite simple. If there are a limited number of arguments, it can be done like this:

      if(argc < 2)
      {
      if(!getcwd(pathname, sizeof(pathname)))
      die("Error getting pathname\n");
      }
      else
      strcpy(pathname, argv[1]);

      If there are variable arguments you can use va_list and va_arg

      Delete
    2. I am new to systems programming. Can you suggest text books or materials or websites? Support from class is much limited.

      Delete
  2. Hey I'm new at coding and I was wondering how to run this code, I copy pasted it in vim and tried compiling but it gave me these errors:

    ls6.cpp: In function ‘int main()’:
    ls6.cpp:38: warning: deprecated conversion from string constant to ‘char*’
    ls6.cpp:41: error: invalid conversion from ‘int (*)(dirent*)’ to ‘int (*)(const dirent*)’
    ls6.cpp:41: error: initializing argument 3 of ‘int scandir(const char*, dirent***, int (*)(const dirent*), int (*)(const dirent**, const dirent**))’
    ls6.cpp:45: warning: deprecated conversion from string constant to ‘char*’

    ReplyDelete
    Replies
    1. Hi , it seems to be a typo . There is no 'dirent' structure being used. It is 'direct'. I tried this code again , it works fine.

      Delete
  3. #include
    #include
    #include
    #include
    int main(){
    DIR *dir;
    struct dirent *c;
    char *path="/root/Documents";
    dir=opendir(path);
    while((c=readdir(dir))!=NULL){
    printf("%s\n",c->d_name);
    }
    //closedir(dir);
    return 0;

    }

    ReplyDelete
  4. #include
    #include
    #include
    #include
    int main(){
    DIR *dir;
    struct dirent *c;
    char *path="/root/Documents";
    dir=opendir(path);
    while((c=readdir(dir))!=NULL){
    printf("%s\n",c->d_name);
    }
    closedir(dir);
    return 0;

    }

    ReplyDelete
  5. hey buddy I am new to system programming and I have a assignment due today can you help me resolve an issue

    ReplyDelete
  6. main.c: In function ‘main’:
    main.c:41:39: warning: passing argument 3 of ‘scandir’ from incompatible pointer type [-Wincompatible-pointer-types]
    41 | count = scandir(pathname, &files, file_select, alphasort);
    | ^~~~~~~~~~~
    | |
    | int (*)(struct dirent *)
    In file included from /usr/include/x86_64-linux-gnu/sys/dir.h:23,
    from main.c:2:
    /usr/include/dirent.h:257:13: note: expected ‘int (*)(const struct dirent *)’ but argument is of type ‘int (*)(struct dirent *)’
    257 | int (*__selector) (const struct dirent *),
    | ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    ReplyDelete

Post a Comment

Please post your valuable suggestions