[cs631apue] About FTS

Marlon Seaton mseaton at stevens.edu
Tue Oct 8 12:11:07 EDT 2019


Hello,
I am trying to use fts to traverse through the current directory without recursion and i either get a segfault of the following error when I call fts_children()

fts_children: Undefined error: 0.

Here's my code snippet below:

main
{
    if(argc == 1)
      PrintFileNames(".");
}
void PrintFileNames(char* dir )
{

   FTS *filetree = NULL;
   FTSENT *file  = NULL;
   FTSENT *child = NULL;
   char *path[] = {dir, NULL};

   filetree = fts_open(path, FTS_PHYSICAL, &compare);

   if(filetree == NULL)
      ErrorMessage("fts_open failed");

   else
   {

      while((file = fts_read(filetree)) != NULL)
      {

         child = fts_children(filetree, 0);

         if(child == NULL)
            ErrorMessage("fts_children");

         printf("%s\n",child->fts_name);

      }
   }

   if(errno != 0)
      ErrorMessage("fts_read failed");

   if( fts_close(filetree) < 0)
      ErrorMessage("fts_close");
}

Can anyone shed some light on what's going on?
Thanks.
________________________________
From: cs631apue-bounces at lists.stevens.edu <cs631apue-bounces at lists.stevens.edu> on behalf of Jan Schaumann <jschauma at stevens.edu>
Sent: Sunday, October 6, 2019 4:35 PM
To: cs631apue at lists.stevens.edu <cs631apue at lists.stevens.edu>
Subject: Re: [cs631apue] About FTS

Yuxi Wang <ywang286 at stevens.edu> wrote:

> 1.To use these fields to reference any files represented by
> other FTSENT structures will require that the path buffer be modified
> using the information contained in that FTSENT structure's fts_pathlen
> field.  Any such modifications should be undone before further calls to
> fts_read() are attempted.  The fts_name field is always NUL-terminated.

I'm honestly struggling to come up with a useful
example, but the point is that you cannot manipulate
the buffers (e.g., via strcat(3) etc.) in e.g., your
comparison function, nor can you rely on the buffer to
be NULL terminated for a previously returned element.

That means that you can't keep a pointer to the
element returned and subsequently call e.g. strlen(3)
on _that_ element's fts_path field.

Let's say you want to write a program that will print
the path within the parent directory:

$ pwd
/tmp
$ ls
file
$ printParentPath file
tmp/file
$ printParentPath /var/tmp/subdir/file
subdir/file

This might require you to keep track of the parent
struct.  You might try to

- get strlen of current entry accpath, n
- get strlen of parent entry accpath, m
- malloc a buffer of size n + 1 + m
- sprintf parent, '/', current to buffer

But the parent entry's accpath may not be
NULL-terminated, thus strlen(3) giving you a bogus
result.

> 2.What does the fts_accpath represent for? I tracked
> the FTS structure and found it always equal
> fts_name.

fts_accpath will be different depending on whether
you've specified FTS_NOCHDIR or not.  With
FTS_NOCHDIR, fts_accpath will look like fts_path,
without, fts_accpath will look like fts_name.

I haven't verified, but I could imagine that results
will also differ based on whether you're following
symlinks and the hierarchy includes symlinks to
directories whereby directory traversal may encounter
the same subdir via multiple paths.

-Jan
_______________________________________________
cs631apue mailing list
cs631apue at lists.stevens.edu
https://lists.stevens.edu/mailman/listinfo/cs631apue
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.stevens.edu/pipermail/cs631apue/attachments/20191008/d7d73bb2/attachment.html>


More information about the cs631apue mailing list