I have been beating my head on a wall over this fts_children() question. In the man page, http://www.kernel.org/doc/man-pages/online/pages/man3/fts.3.html, it clearly states As a special case, if fts_read() has not yet been called for a hierarchy,
fts_children() will return a pointer to the files in the logical directory
specified to fts_open(), that is, the arguments specified to fts_open().
Which I take to mean that a linked list of all the files in the current directory are returned. Well, I am finding that not to be the case and I would really appreciate some help in the matter. I expected a linked list to be returned and then I would iterate through it to find the file with the matching file name (the end goal). However, right now, I am just trying to iterate through the linked list (baby steps). Right now, it will return one file and then exit the loop. This does not make sense to me. Any help would very much appreciated!!!
Opening of file system:
char* const path[PATH_MAX] = {directory_name(argv[argc-index]), NULL};
char* name = file_name(argv[argc-index]);
if ((file_system = fts_open(path, FTS_COMFOLLOW, NULL)) == NULL){
fprintf(stderr,"%s:%s\n", strerror(errno), getprogname());
exit(EXIT_FAILURE);
}/*Ends the files system check if statement*/
/*Displays the information about the specified file.*/
file_ls(file_system,name, flags);
For clarification, the directory_name parses the inputted path from the user and returns something like /home/tpar44. That directory is then opened.
Searching within the file system:
void
file_ls(FTS* file_system, char* file_name, int* flags){
FTSENT* parent = NULL;
//dint stop = 0;
parent = fts_children(file_system, 0);
while( parent != NULL ){
printf("parent = %s\n", parent->fts_name);
parent = parent->fts_link;
}
}
Thanks!
I think this is entirely by design.
...that is, the arguments specified to fts_open()...
What it says is that it will list the root elements in the path_argv
parameters for your convenenience. It treats the path_argv
array as a logical directory itself.
In other words this:
int main(int argc, char* const argv[])
{
char* const path[] = { ".", "/home", "more/root/paths", NULL };
FTS* file_system = fts_open(path, FTS_COMFOLLOW | FTS_NOCHDIR, &compare);
if (file_system)
{
file_ls(file_system, "", 0);
fts_close(file_system);
}
return 0;
}
Will output
parent = .
parent = /home
parent = more/root/paths
Which, in fact, it does (see http://liveworkspace.org/code/c2d794117eae2d8af1166ccd620d29eb).
Here is a more complete sample that shows complete directory traversal:
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fts.h>
#include<string.h>
#include<errno.h>
int compare (const FTSENT**, const FTSENT**);
void file_ls(FTS* file_system, const char* file_name, int* flags)
{
FTSENT* node = fts_children(file_system, 0);
if (errno != 0)
perror("fts_children");
while (node != NULL)
{
// TODO use file_name and flags
printf("found: %s%s\n", node->fts_path, node->fts_name);
node = node->fts_link;
}
}
int main(int argc, char* const argv[])
{
FTS* file_system = NULL;
FTSENT* node = NULL;
if (argc<2)
{
printf("Usage: %s <path-spec>\n", argv[0]);
exit(255);
}
char* const path[] = { argv[1], NULL };
const char* name = "some_name";
file_system = fts_open(path, FTS_COMFOLLOW | FTS_NOCHDIR, &compare);
if (file_system)
{
file_ls(file_system, name, 0); // shows roots
while( (node = fts_read(file_system)) != NULL)
file_ls(file_system, name, 0); // shows child elements
fts_close(file_system);
}
return 0;
}
int compare(const FTSENT** one, const FTSENT** two)
{
return (strcmp((*one)->fts_name, (*two)->fts_name));
}