1

Here's my function to get the size of a file using stat():

off_t fsize(const char *filename) {                                                                                                                   
  struct stat st;                                                                                                                                        

  if (stat(filename, &st) == 0)                                                                                                                          
     return st.st_size;                                                                                                                                 

  fprintf(stderr, "Cannot determine size of %s: %s\n",                                                                                                   
         filename, strerror(errno));                                                                                                                    

  return -1;                                                                                                                                             
}

I can get the file size just fine by doing:

size = fsize ("byte.bin");

but when I need to get the file from a lower directory from the local directory, let's say "deps/src" directory, it stops prematurely on me with no error message that i expected:

size = fsize ("deps/src/byte.bin");

I wrote a small program that uses the function, copied the byte.bin file to a "deps/byte.bin" and called my fsize function with "deps/byte.bin" and get the error "Cannot determine size of byte.bin: No such file or directory"

If I use an absolute path like "/something/deps/byte.bin" it works.

What am I doing wrong and how show I do this for the relative path?

EhevuTov
  • 20,205
  • 16
  • 66
  • 71
  • 4
    _Why_ does it bomb? You've presumably got the `strerror` right there, what does it say? – sarnold Jun 22 '12 at 22:52
  • It doesn't print that error message like I'd think. That error msg is printed if I explicitly give it a file that doesn't exist. When I use "deps/src/byte.bin", which does exist, it gives me a malloc error in my malloc_error_break. Yet, if I copy that same file to my local dir and use "byte.bin" it runs just fine – EhevuTov Jun 22 '12 at 22:59
  • 1
    If you get a malloc error, I'd dare to say you have a problem elsewhere which manifestates exactly here. – glglgl Jun 22 '12 at 23:09
  • @glglgl but why would that occur by just changing the string value? I would think stat would throw an error message that my fsize() would return, just like when I explicitly put in a false string. – EhevuTov Jun 22 '12 at 23:10
  • @EhevuTov: did you try this in a small program that does nothing but call `fsize()` and display results? – Michael Burr Jun 22 '12 at 23:12
  • @EhevuTov Why not ? If your code does something it should not, and invokes undefined behavior, there's no telling what will follow, and anything could trigger bad things to happen anywhere. – nos Jun 22 '12 at 23:13
  • @MichaelBurr I'm doing that now, actually. This is part of a larger SNMP agent program I'm creating. I'll let you know my results. – EhevuTov Jun 22 '12 at 23:13
  • @MichaelBurr I wrote a small test program and I'm getting a "no such file or directory" error even though I made a copy into "deps/" dir and changed the string in the code to "deps/byte.bin" – EhevuTov Jun 22 '12 at 23:23
  • 2
    Now that you've got a small test program, you'll stand a chance of figuring out what the problem is; run `strace -o /tmp/out -f ./test deps/byte.bin` (or however you need to call it) and look at the system calls and their return values in `/tmp/out` -- once you find the failing `stat` call, I expect the error will be clear as day. – sarnold Jun 22 '12 at 23:34
  • @glglgl it's a malloc error because the file size function returns a -1 and when I malloc for -1 later, which is why I need the file size, it errors the malloc. That is not the root-cause problem however. It's this problem with not being able to use the fsize() in a different dir. – EhevuTov Jun 22 '12 at 23:36
  • @sarnold thanks, I'm getting closer and appreciate your example tremendously, but I need to find a MacOSX equivalent. It looks like I might be able to use "trace" but not sure... – EhevuTov Jun 22 '12 at 23:38
  • Oh, bother, sorry about that. I _think_ OS X uses the combination `ktruss` followed by `ktrace` -- or `truss` followed by `trace`. I hope that helps. – sarnold Jun 22 '12 at 23:41
  • @sarnold I don't have a ktruss or ktrace and they're not in my port/software system. MacOS X is fBSD and netBSD based. Is this something I could use dtrace with? These tools are new to me but I'm excited to get to work on tracing. Thank you for your help. – EhevuTov Jun 22 '12 at 23:44
  • 1
    Aha, looks like the modern equivalent is [`dtruss`](http://dtrace.org/blogs/brendan/2011/10/10/top-10-dtrace-scripts-for-mac-os-x/). :) – sarnold Jun 23 '12 at 00:03
  • Assuming you deleted `byte.bin` after having copied it to `deps`: if you get "*Cannot determine size of byte.bin: No such file or directory"*" you did pass `byte.bin` to `fsize()` so it's perfectly ok you get an error indicating `byte.bin` can not be found, isn't it? ;-) – alk Jun 23 '12 at 14:35
  • I'm narrowing down the issue. It seems absolute paths work, but relative paths don't (except if the file is in the current working dir). So "/src/deps/api" works but not "deps/api" when I compile and run from "/src" – EhevuTov Jun 25 '12 at 20:01

1 Answers1

1

I'm guessing that what's happening is that you are incorrectly assuming about the working directory. A simple way to test where the working directory is would be to just write a program that simply outputs a file like test.txt. In many (but not all) cases, the working directory is wherever the executable file is stored. This means that if you are trying to access a file on a relative path, you will likely need to include at least one .. in your relative path to get out of the bin directory.

Daniel
  • 6,595
  • 9
  • 38
  • 70
  • Thank you for your response. I agree. I wish I could find out which dir stat() uses. I find the behavior odd if it uses the current working directory for just the filename, but a different cwd for a path/filename. I also ran GetCurrentDir() from unistd.h and it returned my cwd correctly. It's strange. – EhevuTov Jun 25 '12 at 21:07
  • @EhevuTov, let me reiterate Jonathan Wood's question, then. Is `deps` a subfolder of the current working directory? If it is not, then what you have will not work because it is an incorrect relative path. – Daniel Jun 25 '12 at 21:18
  • I'm pretty sure I said previously it was a sub directory, and it is. – EhevuTov Jun 25 '12 at 21:26