How to get the absolute path for a given relative path programmatically in Linux?
Asked Answered
T

7

27

How to get the absolute path for a given relative path programmatically in Linux?

Incase of Windows we have the _fullpath() API. In other words, I mean what is analogous API to _fullpath of Windows in Linux?

Tripersonal answered 26/2, 2010 at 13:17 Comment(1)
Since this was tagged with c, this is probably a duplicate of #229512Stretcher
S
24

As Paul mentioned, use realpath(). Please note though, that since many file systems in Linux support hard links, any given directory can have a number of different absolute paths.

Swear answered 26/2, 2010 at 13:22 Comment(8)
Any given file can, for sure. Hard-links to directories isn't necessarily supported. Symlinks also cause some confusion when it come sto determining the "real" path.Puduns
@unwind, Thanks for the Info. If due to hard links, if a given directory resolves to multiple different absolute paths, what will be the behaviour of realpath API?Tripersonal
Hardlinks to directories are considered evil and forbidden by most filesystems.Outsole
I am a little confused. Is it possible that a given directory resolves to many different absolute paths? If yes, then what will be the behaviour realpath?Tripersonal
@Tripersonal it doesn't affect resolving a relative path to an absolute path.Circumnutate
realpath resolves the name in the way you would expect - by (recursively) flattening out /../ and /./ components and resolving symlinks. The "multiple paths" issue just means that the name you get out at the end isn't necessarily unique for a given file (since a file does not necessarily have a single "true name").Bullough
Of course NTFS (i.e. Windows) also has hard links with all the same complexities: msdn.microsoft.com/en-us/library/windows/desktop/….Hiccup
There seems to be no way to to resolve a path to a given absolute base path other then the current working directory. Oh men, UNIX stinks sometimes, so i have to roll out my own function.Postboy
S
19

Check out the realpath function.

#include <stdlib.h> 
#include <stdio.h> 
#include <linux/limits.h>
int main() 
{ 
        char resolved_path[PATH_MAX]; 
        realpath("../../", resolved_path); 
        printf("\n%s\n",resolved_path); 
        return 0; 
} 
Searles answered 26/2, 2010 at 13:24 Comment(3)
Please use PATH_MAX instead of 100Bade
This code is insecure and buggy, as pointed out above. Do not give such a small buffer to realpath which will most likely write beyond the buffer size (since it requires a length of PATH_MAX). Even if the program doesn't crash, this code could lead to security vulnerabilities depending on the variable layout, if an adversary can control the original path to be resolved. The manual recommends passing NULL as a second parameter and letting realpath allocate memory to ensure no issues with PATH_MAX definitions, starting with POSIX 2008.Berryman
I think it is a good think to always remember that PATH_MAX simply isn't: insanecoding.blogspot.com.br/2007/11/pathmax-simply-isnt.htmlBoardman
K
6

Try realpath:

$ man realpath

This is also available in BSD, OS X, et al.

Komara answered 26/2, 2010 at 13:20 Comment(0)
C
3

There is the realpath from stdlib.h

Circumnutate answered 26/2, 2010 at 13:22 Comment(2)
I immediately thought of realpath, too, but I was stunned -- stunned I say -- when I saw your answer showing that realpath is in stdlib.h. Surely that can't be true, considering that realpath is not part of the C library. Lo and behold, it's true. I'm dumbfounded. What's a well-formed program that defines its own function named realpath to do? Those POSIX guys have run amok! Amok I say!Horrible
Dan: So long as they invoke their compiler in "strictly conforming" mode and don't define any macros that invoke undefined behaviour (like _XOPEN_SOURCE), they should be OK.Bullough
A
2

Running on RedHat 5.3, realpath doesn't exist but readlink is installed. You can use it on relative paths and symlinks, plus it will resolve symlinks recursively for you. It's thus a better option that realpath in my opinion

readlink -f .
Adultery answered 10/10, 2012 at 19:7 Comment(0)
D
0

The is also another useful way, like "readlink -m $filename"

First of all, it works without requirement for target file to exist. Secondly, it will handle symlinks and get really real path.

Durrell answered 11/3, 2010 at 9:54 Comment(0)
D
-3
// For C++ with Gnome Gtkmm3 libraries
#include <glibmm.h>
#include <giomm.h>

  string PathRel2Abs(string relpath) {
  Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(relpath);
  return file->get_path();
}
Dahliadahlstrom answered 4/1, 2017 at 14:8 Comment(2)
Usually it is a good idea to add some explanation to your post on how the code works. This helps newer developers know what the code does.Sordid
And it's not even C.Breannabreanne

© 2022 - 2024 — McMap. All rights reserved.