I'm not all that experienced in C, but have an assignment in one of my classes, and I'm having a few issues opening a directory.
The purpose of the program is to (paraphrased):
- If no flag or directory is provided, list names of files in current directory.
- If a flag (-l) is provided, list more information about each file.
- If a flag and a directory are provided, go to that directory and list information about each file (or directory) in that directory. It's not necessary to recurse through subdirectories.
It doesn't need to handle getting only a directory but no flag, or an invalid directory. It's more proof-of-concept.
I've managed to satisfy parts 1 and 2, but part 3 keeps breaking, giving a segmentation fault.
My code is as follows:
void recursedirect(char* flag, char* directory)
{
DIR* dir;
struct dirent *entry;
printf("Flag: %s\nDirectory: %s\n\n", flag, directory);
if (flag == NULL)
// No flag provided, therefore only do file names.
{
dir = opendir(".");
entry = readdir(dir);
while (entry != NULL)
{
printf ("%s\n", entry->d_name);
entry = readdir(dir);
}
}
else if (strcmp(flag, "-l") == 0 && directory == NULL)
// No directory provided, but flag provided
{
dir = opendir(".");
entry = readdir(dir);
while (entry != NULL)
{
fileinfo(directory);
entry = readdir(dir);
}
}
else if (strcmp(flag, "-l") != 0)
{
printf("Invalid flag.\n");
}
else
// A directory is provided
{
dir = opendir(directory);
if (dir != NULL)
{
entry = readdir(dir);
while (entry != NULL)
{
fileinfo(directory);
entry = readdir(dir);
}
}
else
printf("Something went wrong. It might be an invalid filename.\n");
}
}
Specifically, the else statement at the end is giving me trouble. I've tried giving it any filepaths I can think of, hardcoded and otherwise, and it's still giving me issues. I'm guessing it's something simple, but I don't have enough experience to know what it is.
fileinfo
is a function that prints out the file information given a DIR
and dirent
as arguments. However, the error definitely isn't in that code best I can tell.
EDIT: I made the mistake of not sharing everything. My main method is pretty simple.
int main (int argc, char** argv)
{
char* flag = argv[1];
char* directory = argv[2];
recursedirect(flag, directory);
}//main
It includes the following:
#include <dirent.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
And the fileinfo
function is as follows (edited slightly, as I realised I no longer needed to give it an argument of DIR *dir
):
void fileinfo(struct dirent *entry)
{
struct stat fileStats;
stat(entry->d_name, &fileStats);
printf("File Name: %s\n", entry->d_name);
printf("File Size: %d bytes\n", (int) fileStats.st_size);
printf("Number of Blocks: %d\n", (int) fileStats.st_blocks);
printf("Number of Links/References: %d\n", (int) fileStats.st_nlink);
printf("I-Node: %d\n", (int) fileStats.st_ino);
printf("Device ID: %d\n", (int) fileStats.st_dev);
printf("User ID: %d\n", (int) fileStats.st_uid);
printf("Group ID: %d\n", (int) fileStats.st_gid);
stat("alphabet",&fileStats);
printf("Time of Last Access: %s", ctime(&fileStats.st_atime));
printf("Time of Last Modification: %s", ctime(&fileStats.st_mtime));
printf("Time of Last Status Change: %s", ctime(&fileStats.st_ctime));
stat(entry->d_name, &fileStats);
printf("File Permissions: ");
printf((int) (S_ISDIR(fileStats.st_mode)) ? "d" : "-");
printf((int) (fileStats.st_mode & S_IRUSR) ? "r" : "-");
printf((int) (fileStats.st_mode & S_IWUSR) ? "w" : "-");
printf((int) (fileStats.st_mode & S_IXUSR) ? "x" : "-");
printf((int) (fileStats.st_mode & S_IRGRP) ? "r" : "-");
printf((int) (fileStats.st_mode & S_IWGRP) ? "w" : "-");
printf((int) (fileStats.st_mode & S_IXGRP) ? "x" : "-");
printf((int) (fileStats.st_mode & S_IROTH) ? "r" : "-");
printf((int) (fileStats.st_mode & S_IWOTH) ? "w" : "-");
printf((int) (fileStats.st_mode & S_IXOTH) ? "x\n\n" : "-\n\n");
}
As for more clarification on failed inputs, ./files
and ./files -l
both work. ./files
with any invalid flag is caught as intended. However, ./files -l *any valid filepath*
consistently fails.
Everything is compiled using gcc
in Ubuntu 14.04.5 in the c9.io IDE.
Thank you!
EDIT 2: I've tried deleting and putting back the file, and now strangely I'm not getting the error. However, now it won't print full file info for anything. I'll troubleshoot some more.
EDIT 3: I've fixed it with one exception. The issue was an incorrect if statement checking the flag. Apparently something was going wrong in the IDE. I'm now getting this error: Couldn't open MANPATH=/home/ubuntu/.nvm/versions/node/v6.11.2/share/man:/usr/local/rvm/rubies/ruby-2.4.0/share/man:/usr/local/man:/usr/local/share/man:/usr/share/man:/usr/local/rvm/man
It looks like this isn't the code and is a problem with the c9 server in some way. I've tried giving both the source code and compiled code files full permissions, restarting the workspace, and restarting Apache2. Thank you all for everything!