Reputation: 10203
I am working on a program which uses realpath() to get the absolute path of a file. Unfortunately, this function takes a string buffer that is expected to be so large that it is big enough and that's not safe when this application has to run across multiple platforms. Is there a safe version of this function which avoids the buffer overflow issue, perhaps using dynamic memory allocation?
Upvotes: 17
Views: 23623
Reputation: 8178
There is a way to do the same in Boost using boost::filesystem:
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
try{
path absolutePath = canonical("./../xxx"); //will throw exception if file not exists!
}
catch{...}{
cout << "File not exists";
}
cout << absolutePath.string();
There is QT way to do it (got from here):
QFileInfo target_file_name(argv[1]);
QString absolute_path = target_file_name.absolutePath()
There is a bit complicated implementation of realpath in C++. Cannot tell anything about it's safety, but it should allow path with length more then PATH_MAX
. Going to test it soon.
Upvotes: 2
Reputation: 215261
See here for information on safe and portable use of realpath
:
http://www.opengroup.org/onlinepubs/9699919799/functions/realpath.html
Basically, modern standards allow you to pass a NULL pointer, and realpath
will allocate a buffer of the appropriate length. If you want to be portable to legacy systems which do not support this standard, simply check #ifdef PATH_MAX
and use a fixed-size buffer of length PATH_MAX
. As far as I know, there are no legacy systems that lack a constant PATH_MAX
but which do not support NULL arguments to realpath
.
Upvotes: 20
Reputation: 90422
From the manpage:
If resolved_path is specified as NULL, then realpath() uses malloc(3) to allocate a buffer of up to PATH_MAX bytes to hold the resolved pathname, and returns a pointer to this buffer. The caller should deallocate this buffer using free(3).buffer using free(3).
So it seems like you can just do this:
char *real_path = realpath(path, NULL);
// use real_path
free(real_path);
Upvotes: 14