#1
  1. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2002
    Location
    london
    Posts
    0
    Rep Power
    0

    Trying to compile/run a program i wrote on a UNIX machine, on a Linux machine.


    Hi,
    I'm writing a program to emulate the ls command, and have written a lot of it on a UNIX machine at college. I'm now trying to compile and run the program on my home machine (Debian Linux) using gcc, but am getting a non-terminating loop, and no useful results.
    I get the result:
    $У@?
    over and over again, instead of listing the files in the directory.
    Is this a problem that's not easily fixed because of the different Operating Systems? Or is there something I can do to make it work on both?
    Any info appreciated.

    Source code:

    /* emulator of the ls function */
    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>

    void printstats(char name[])
    {

    }

    void listdir(char dirname[])
    {
    int fp,i=0,j,readfile;
    char buffer[16];
    if ((fp = (open(dirname,O_RDONLY))) != -1 )
    {
    printf("sucess\n");
    while((readfile=read(fp,buffer,sizeof(buffer)))!=0)
    {
    for (j=2;j<15;j++)
    {
    printf("%c",buffer[j]);
    }
    printf("\n");
    i++;
    }
    close(dirname);
    }
    else
    {
    printf("fail");
    }

    }

    void main(int argc, char *argv[])
    {
    listdir(*++argv);
    }
  2. #2
  3. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,607
    Rep Power
    4247
    I think you should be using opendir(), readdir() and closedir() instead of open(), read() and close()?? These functions are part of the standard C library and are designed to specifically read directories.

    When you try to read the directory with the open() and read() commands, you're probably getting the directory contents along with the file attributes and everything else (which may or may not be stored in binary format), which is why you're seeing all the funny characters. You'd see the same behaviour, if you type:

    cat /directoryname

    Under FreeBSD, you'll see a lot of junk characters along with the file names. These are the additional information (such as permissions, inodes etc.) that are associated with the file names. The command will not work under Linux (at least RedHat 7.1 up) because cat will complain that it is a directory.

    Anyway, opendir(), readdir() and closedir() are the way to go.
  4. #3
  5. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2002
    Location
    london
    Posts
    0
    Rep Power
    0
    Ok I tried that and at least it got rid of the non-terminating loop ;)
    Now I have a different problem though:

    ryo@debian:~/c dev$ ./list .
    sucess
    4?@??
    4?@??
    4?@??
    4?@??
    Segmentation fault

    I've kinda been dumped in the deep end with system calls in c, is there anywhere I can read up on it?
    By the way the program will go on to read permissions, inode numbers, and more info, would using opendir(), readdir(), and closedir() hinder that?
  6. #4
  7. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,607
    Rep Power
    4247
    Here's some code demonstrating the usage of opendir(), closedir() and readdir(). I've tested this on both FreeBSD and Linux.

    Code:
    #include <dirent.h>
    #include <stdio.h>
    
    int dirlist(char *);
    
    int main(int argc, char *argv[]) {
      if (argc > 1)
        dirlist(*++argv);
    
      return 0;
    }
    
    int dirlist(char *dirname) {
      DIR *dirp;
      struct dirent *direntry;
    
      fprintf(stderr, "Dir list for %s\n", dirname);
    
      /* Open a pointer to the directory structure */
      if ((dirp = opendir(dirname)) == NULL) {
        fprintf(stderr, "Could not open dir %s\n", dirname);
        return 1;
      }
    
      /* Read each file in sequence from the directory structure */
      while ((direntry = readdir(dirp)) != NULL) {
        fprintf(stdout, "%s\n", direntry->d_name);
      }
    
      /* Close the resource */
      closedir(dirp);
    
      return 0;
    }
    As for finding the rest of the information, the dirent structure contains a field called d_ino which is the inode number. For the rest of the information, check out the stat() family of functions. You can get the help for these functions under Linux by typing:

    man -S2 stat

    Incidentally, the opendir(), readdir(), stat() etc functions conform to POSIX standards, so they should be available on practically all modern *NIXES.
  8. #5
  9. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2002
    Location
    london
    Posts
    0
    Rep Power
    0
    Thanks, I'll have a look through it and see what I can pick up :)

IMN logo majestic logo threadwatch logo seochat tools logo