As a part of an assignment from one of my classes, I have to write a program in C to duplicate the results of the ls -al command. I have read up on the necessary materials but I
myfile->d_name
is the file name not the path, so you need to append the file name to the directory "Downloads/file.txt"
first, if it's is not the working directory:
char buf[512];
while((myfile = readdir(mydir)) != NULL)
{
sprintf(buf, "%s/%s", argv[1], myfile->d_name);
stat(buf, &mystat);
....
As to why it prints 4096
that is the size of the links .
and ..
from the last call to stat()
.
Note: you should allocate a buffer large enough to hold the directory name, the file name the NULL
byte and the separator, something like this
strlen(argv[1]) + NAME_MAX + 2;
This is the final code I got to work for anyone interested. It prints the correct file sizes. Credit goes to asker and mux for answering, just putting the code together. Input I got this to work for is "./main ." .
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
int main(int argc, char* argv[])
{
DIR *mydir;
struct dirent *myfile;
struct stat mystat;
char buf[512];
mydir = opendir(argv[1]);
while((myfile = readdir(mydir)) != NULL)
{
sprintf(buf, "%s/%s", argv[1], myfile->d_name);
stat(buf, &mystat);
printf("%zu",mystat.st_size);
printf(" %s\n", myfile->d_name);
}
closedir(mydir);
}
I believe you'll observe that if you ./a.out .
you will get the behaviour you expect.
You have a slightly subtle bug, observable if you examine the return code of your call to stat(2)
.
The fundamental mistake: the dirent
s returned by readdir(2)
(the myfile
in your code) will have a d_name
relative to mydir
. Your code will stat
..
first, succeed, and so mystat
will contain valid data for ..
, then all subsequent calls to stat(2)
will fail, returning -1
, which you do not check for, so mystat
will not be modified, and you will print the st_size
for the old value, i.e. that of ..
.
or maybe just system("ls -al") will also work!
The trouble is that when you stat("ankur.txt", &mystat)
, you are not working on the file "Downloads/ankur.txt"
. Most likely, the stat()
is failing; alternatively, it is reporting on a different file.
Consequently, you need to look at whether your system supports fstatat() — new in POSIX 2008 — or arrange to prefix the name of the file with name of the directory.