- Compiler: Code::Blocks(GNU GCC)
- Platform: Windows(x86)
Update: I have solved the problem by using chdir() to change the current working directory before I call opendir(). So I am assuming that opendir() can only open a directory that is in the current working directory. So my new question is, am I correct?
I am currently writing a basic imitation of window’s dir command. My program works properly when the “.” wildcard is used as an argument for opendir(). But when I don’t use the wildcard and specify a directory instead. My program will not open the directory specified to it. For example if I type c:\windows it will open c:\ instead and each file’s st_mode will be the same. At least I assume that they are all the same because all of the file types(DIR, FILE, OTHER) are the same.
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <dirent.h>
int main(int argc, char* argv[])
{
//'directory' points to the directory | 'directory_contents' is used with readdir() to read the directory's('directory') contents.
DIR *directory;
struct dirent *directory_contents;
struct stat file_info;
//IF no argument is present display the contents of the current directory | IF there is an arugment display the contents of that argument | ELSE Too many arguments
if (argc == 1)
{
directory = opendir(".");
}
else if (argc == 2)
{
//New Code
chdir(argv[1]); directory = opendir(".");
//Old Code
directory = opendir(argv[1]);
}
else
{
printf("ERROR: Extra arguments\n");
}
//Checks to see if the directory opened above was actually opened.
if (directory == NULL)
{
printf("ERROR: Failed to open '%s'.\n", argv[1]);
return 2;
}
else
{
//WHILE there are file names to be read THEN read the file names
while (directory_contents = readdir(directory))
{
stat(directory_contents->d_name, &file_info);
//Test for directory
if(S_ISDIR(file_info.st_mode))
{
//File type
printf("<DIR> ");
//File name
if(strlen(directory_contents->d_name) <= 15)
{
printf("%-15s", directory_contents->d_name);
}
else if(strlen(directory_contents->d_name) > 15)
{
printf("%.12s.. ", directory_contents->d_name);
}
//File premissions
printf("<%c%c%c>\n", ((file_info.st_mode & S_IRUSR)==0) ? '-' : 'r', ((file_info.st_mode & S_IWUSR)==0) ? '-' : 'w', ((file_info.st_mode & S_IXUSR)==0) ? '-' : 'x');
}
//Test for a regular file.
else if(S_ISREG(file_info.st_mode))
{
//File type
printf("<FILE> ");
//File name
if(strlen(directory_contents->d_name) <= 15)
{
printf("%-15s", directory_contents->d_name);
}
else if(strlen(directory_contents->d_name) > 15)
{
printf("%.12s.. ", directory_contents->d_name);
}
//File premissions
printf("<%c%c%c> ", ((file_info.st_mode & S_IRUSR)==0) ? '-' : 'r', ((file_info.st_mode & S_IWUSR)==0) ? '-' : 'w', ((file_info.st_mode & S_IXUSR)==0) ? '-' : 'x');
//File size
if (file_info.st_size < 1000)
{
printf("<%-3i B>\n", file_info.st_size);
}
else if ( (file_info.st_size > 1000) && (file_info.st_size < 1000000) )
{
printf("<%-3i KB>\n", file_info.st_size/1000);
}
else if ( (file_info.st_size > 1000000) && (file_info.st_size < 1000000000) )
{
printf("<%-3i MB>\n", file_info.st_size/1000000);
}
else
{
printf("<%-3i GB>\n", file_info.st_size/1000000000);
}
}
//Symbolic Link etc.
else
{
//File type
printf("<OTHER> ");
//File name
if(strlen(directory_contents->d_name) <= 15)
{
printf("%-15s", directory_contents->d_name);
}
else if(strlen(directory_contents->d_name) > 15)
{
printf("%.12s.. ", directory_contents->d_name);
}
//File premissions
printf("<%c%c%c>\n", ((file_info.st_mode & S_IRUSR)==0) ? '-' : 'r', ((file_info.st_mode & S_IWUSR)==0) ? '-' : 'w', ((file_info.st_mode & S_IXUSR)==0) ? '-' : 'x');
}
}
}
}
And yes I do know that the permissions I am outputting are completely irrelevant because of Window’s use of ACLs. I am only writing this program on windows because I have no choice right now but it is intended for a Linux OS.
stat(directory_contents->d_name,This line is the problem. The
d_namefield is just the name of the file without any directory. So unless the directory happens to be the current directory, the call tostat()will not find the file.