lstat "No such file or directory"?

Discuss Programming

lstat "No such file or directory"?

Postby ZiaTioN » Tue Feb 24, 2004 4:45 pm

I am getting the topic error when running through the following while loop.

Code: Select all
  while(argc > 1) {
    fname = argv[1];
    if(!lstat(fname, &statbuf)) {
       if(S_ISDIR(statbuf.st_mode)) {
          /*printf("\n%s:\n", fname);*/
          if ((dir = opendir(fname)) == NULL) {
             perror("Failed to open directory");
          }
          printf("\n%s:\n", fname);
          while((file_info = readdir(dir)) != NULL) {
             fname = file_info->d_name;
             if (!lstat(fname, &statbuf)) {                  /* <-- This is the line that errors! */
                if((DASH_A == (opt & DASH_A)) &&
                   (DASH_L != (opt & DASH_L))) {
                   if(fname[0] != '.') {
                      printf("  %s\n", fname);
                   } else {
                      printf("  %s\n", fname);
                   }
                } else if(DASH_L == (opt & DASH_L)) {
                   if (DASH_A == (opt & DASH_A)) {
                      file_list(file_info->d_name, statbuf, opt);
                   } else {
                      if(fname[0] != '.') {
                         file_list(file_info->d_name, statbuf, opt);
                      }
                   }
                } else {
                   if(fname[0] != '.') {
                      printf("  %s\n", fname);
                   }
                }
             } else {
                perror(fname);
             }
          }
          closedir(dir);
       } else {
          printf("%s\n", fname);
       }
    } else {
       perror(fname);
    }
    ++argv;
    --argc;
  }


The commented line is the line in question. When I run this it returns fine for the first two directories in the target dir ("." and "..") but once it hits a real direcrtory or file it returns the error for each file or dir it steps through.

Is there any reason why this would be happening? I cannot see it..

The full program can be found at the following links (in case that might help you help me :) ):
http://www.perlskripts.com/downloads/newls.c <-- main C file
http://www.perlskripts.com/downloads/myls.h <-- .h file
ZiaTioN
administrator
administrator
 
Posts: 460
Joined: Tue Apr 08, 2003 3:28 pm

Postby Void Main » Tue Feb 24, 2004 7:09 pm

If you trace it through you will notice that you are trying to stat a filename in a directory without prepending the directory name to the filename (or chdir into the directory).

Example:
Say I have these files:

/directory/file1.txt
/directory/subdir/file2.txt
/directory/subdir/file3.txt

If I run these commands it works:

$ cd /directory
$ newls file1.txt

If I run these commands it fails:

$ cd /directory
$ newls subdir

It fails with "file2.txt: file not found" and "file3.txt" file not found. The reason it does is you are trying to "lstat" the name "file2.txt" and "file3.txt" from the "/directory" directory. Those files do not exist in that directory so the error message is correct. You have to figure out a way to prepend the directory to the fname, in the above example you would lstat "subdir/file2.txt" and "subdir/file3.txt" *or* chdir into the directory first, but I believe the proper method would be to prepend the path to the file.
User avatar
Void Main
Site Admin
Site Admin
 
Posts: 5705
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA

Postby ZiaTioN » Wed Feb 25, 2004 10:37 am

Well I had to end up doing a chdir because I tried the prepend first and it worked but I havd to prepend inside mt while loop because fname was a changing value through each iteration of the loop. What this did was create a long string prepending each new file or directory name onto the value of the prepended string which was the value it was through the last iteration.

So in a directory called /test that had:

1.txt
2.txt
3.txt

the value of the string would increment as such:

/test/1.txt
/test/1.txt/2.txt
/test/1.txt/2.txt/3.txt

so by the end of the loop I would have a huge file path to files and directories that did not exist.

After that I had to wrestle with a whole other beast. Recursion! LOL...

The product as of now can be found at:

http://www.perlskripts.com/downloads/myls.h
and:
http://www.perlskripts.com/downloads/myls.c

I was able to get the recursion working as depth-first but it only goes down a single depth path and never comes back up to continue. If you want something to do and you want to look at it to see if there is a way to have it work correctly go for it.

What is does is say in /root I have 3 directories called /dir1, /dir2 and /dir3. Now say I have subdirectories in /dir1 that are /subdir1, /subdir2 and /subdir3.

when I do ./myls -R -a /root the printout looks as such:

/root:
.
..
dir1
dir2
dir3

/dir1:
.
..
subdir1
subdir2
subdir3

/subdir1:
.
..
somefile.txt
anotherfile.txt
lastfile.txt

And that is it. It never goes back up to /subdir2 or /subdir3 or /dir2 and /dir3 in root. I hope I explained that well :)
ZiaTioN
administrator
administrator
 
Posts: 460
Joined: Tue Apr 08, 2003 3:28 pm

Postby Void Main » Wed Feb 25, 2004 11:14 am

Maybe you want to cheat and look at the source for ls? :)
User avatar
Void Main
Site Admin
Site Admin
 
Posts: 5705
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA

Postby ZiaTioN » Wed Feb 25, 2004 11:52 am

Yeah I had thought of that too but I think I can figure this out. Cheating kinda ruins the experience. I am doing this mainly for my benefit to learn C better. I like to take binaries that work and try to re-write them to see if I can figure out how they do it without looking at the source. This has proven to me to be the best way to teach yourself a language.
ZiaTioN
administrator
administrator
 
Posts: 460
Joined: Tue Apr 08, 2003 3:28 pm

Postby Void Main » Wed Feb 25, 2004 12:59 pm

So what you are saying is, you enjoy reinventing the wheel. Good for you! :)
User avatar
Void Main
Site Admin
Site Admin
 
Posts: 5705
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA

Postby ZiaTioN » Wed Feb 25, 2004 3:35 pm

Not re-inventing the wheel per say but I like learning how things work and why they work the way they do. I do not plan on replacing myls with the real linux binary "ls" but it is a good way for me to learn some C while having something to compare the output to so I know if I have done it right or not.
ZiaTioN
administrator
administrator
 
Posts: 460
Joined: Tue Apr 08, 2003 3:28 pm


Return to Programming

Who is online

Users browsing this forum: No registered users and 2 guests