Using sys/stat.h

Aug 6, 2008 at 5:14am
I am getting an error saying size is unknown when declaring struct stat. Looking at sys/stat.h is very confusing and hard to understand how to use it. This is the code I have.

// Find all files in the base directory
DIR * base = NULL;
base = opendir(base_dir);
if (base == NULL)
{
printf("ERROR: Unable to open directory %s\n", base_dir);
exit(110);
}

DIR * modified = NULL;
modified = opendir(modified_dir);
if (modified == NULL)
{
printf("ERROR: Unable to open directory %s\n", modified_dir);
exit(110);
}

struct dirent * de_base = readdir(base);
while (de_base != NULL)
{

// Name of the current file
char * base_name = (*de_base).d_name;
struct stat stat_base, stat_modified;

// ignore "." and ".."
if ((strcmp(base_name, ".") != 0) && (strcmp(base_name, "..") = 0))
{
stat(base_name, &state_base);
struct dirent * de_modified = readdir(modified);
while (de_modified != NULL)
{
char * modified_name = (*de_modified).d_name;
stat(modified_name, &stat_modified);
if (strcmp(base_name,modified_name) == 0)
{
if (stat_base.st_mtime < stat_modified.st_mtime)
{
printf("%s Modified\n", base_name);
}
break;
}

de_base = readdir(modified);
}
}

// go to next entry in directory
de_base = readdir(base);
}

// close the directories
closedir(base);
closedir(modified);

I am just checking one directory with another and if I find a file that has the same name I just if the modified date is newer vs the other file. I am getting an erro stating the storage size isn't known on the line:

struct stat stat_base, stat_modified;

I don't know what I am doing wrong here. The examples I have seen that use this header declear them just had I did.
Aug 6, 2008 at 2:23pm
Did you #include sys/types.h before #including sys/stat.h?
Aug 6, 2008 at 4:46pm
Thanks!

I had one more question about comparing times. Can I compare two files modified date by just doing this:

if (stat_base.st_mtime < stat_modified.st_mtime)
{
printf("%s Modified\n", base_name);
}
break;
}

It doesnt seem to be working. Is there another way to compare dates for the modified times?
Aug 6, 2008 at 7:58pm
although char * base_name = (*de_base).d_name; is perfectly OK, a better, more legible way of writing it is...
char * base_name = de_base->d_name;

You shouldn't need to include any header files as a dependency for other system header files. They all include everything they need internally. However you sometimes need multiple header files to be able to use an API function. Just look up the relevant man page to see what you need to include.

Back to your immediate problem. I'm not convinced you can do a comma separated list if you are using two words for the type you are declaring. to check it, put the two declarations on separate lines...
1
2
struct stat stat_base;
struct stat stat_modified;


The st_mtime check should work because its a time_t which is usual a signed int.
Do a printf() with %d of these values to see what is happening.

Aug 6, 2008 at 11:53pm
Thanks bnbertha. I just did a printf() and got something weird. These are the results I get:

base directory file time: 1075095728
modified directory file time: 1215378334
base directory file time: 1215378334
modified directory file time: 1215378334
base directory file time: 1215378334
modified directory file time: 1215378334
base directory file time: 1215378334
modified directory file time: 1215378334

The first file time I get is different but then all the other files have the same time. I even tryed deleting files and creating them again and I still get that 1215378334 number. This is weird.
Aug 7, 2008 at 6:54pm
These numbers are, I think seconds elapsed since the epoch which always used to be 1 Jan 1970. try this to format it
1
2
3
4
5
6
7
struct tm  *ts;
char           buf[100];

ts = localtime(&stat_base.st_mtime);

strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
printf("%s\n", buf);

This will tell you if those numbers are right.
Aug 8, 2008 at 7:04am
Thanks Bnbertha! Even after creating new directories with files and modifing them I still get that date. The date time is even correct when I checked the system time. I am using a VM that I just copied from another computer so not sure if something when wrong moving it. I am going to try it on a different computer and see if I can get it working.

Anyways I had one last question ;). Is there a way to check if the current item read from a directory is a sub-directory or just another file? Thanks again!
Aug 8, 2008 at 7:43pm
Yes you can
The struct dirent has a field called d_type.

If this is DT_DIR then it is a directory

These are the types on my solaris box....
1
2
3
4
5
6
7
8
9
     #define DT_UNKNOWN       0
     #define DT_FIFO          1
     #define DT_CHR           2
     #define DT_DIR           4
     #define DT_BLK           6
     #define DT_REG           8
     #define DT_LNK          10
     #define DT_SOCK         12
     #define DT_WHT          14 
Topic archived. No new replies allowed.