How to Convert Absolute Path to Relative in C Linux

How to convert absolute path to relative in c linux

I'd be seriously tempted to make the decision, if I were writing this tool, that absolute symbolic links should have the same value when moved somewhere else in the filesystem -- the user wanted a very specific file. And, relative symbolic links should have the same value when moved somewhere else in the filesystem -- the user wanted the links to work regardless of where the directory tree was rooted.

But if the two types of links were intermixed, then you'd have some more work to do -- which is where I assume you are now. (Unix programs are often not that forgiving about guessing a user's intent; if you just readlink(2) and symlink(2) exactly what the filesystem says, your program will never be surprising.)

rsync(1) might have some source code you can use -- or at least learn from. The --safe-links command line option causes rsync to ignore absolute symbolic links and relative symbolic links that point outside the trees it was instructed to copy. This isn't canonicalizing paths to relative as you wish but it may provide sufficient code for discovering which links point outside the directory tree in question.

Slightly related; the Linux-specific symlinkat(2) system call may make it easier for you to create your symbolic links. (The family of ...at() system calls are something like providing a process with multiple "current working directories" without forcing you to make all the fchdir(2) calls yourself.)

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

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.

How to retrieve absolute path given relative

use:

find "$(pwd)"/ -type f

to get all files or

echo "$(pwd)/$line"

to display full path (if relative path matters to)

Change relative path to absolute path in C++ using realpath in Linux

Shell or environment variables (see environ(7)) are not expanded by realpath(3). You need to call getenv(3). You could try

std::string homedir(getenv("HOME"));
realpath((homedir+"/Desktop/SumoSVN/bin").c_str(), resolved_path);

See also wordexp(3) (and perhaps glob(3)). Read path_resolution(7) & glob(7). Notice that it is your shell which expands arguments of commands.

BTW, the current directory is obtained by getcwd(3).

PS. On some installations with different languages Desktop does not exist: it becomes e.g. Bureau on French Debian or Ubuntu or Mint systems.

How to go from absolute path to relative path?

QString QDir::relativeFilePath(const QString & fileName);

should return the relative file path.

How to use relative paths in general C program?

Under Linux, the file /proc/self/exe is a symbolic link to the actual executable running. Hence you could use that to ascertain the directory where the executable is, and work from there.

For example, this program (executable file /home/pax/testprog):

#include <stdio.h>
#include <unistd.h>

int main(void) {
// Buffer should be more robust in real program but read anyway.

char buff[1000];
ssize_t sz = readlink("/proc/self/exe", buff, sizeof(buff));

// Find final directory separator (from '/home/pax/testprog').

while (sz > 0 && buff[sz-1] != '/')
--sz;

// Truncate string to directory name only, and print.

buff[sz] = '\0';
printf("[%s]\n", buff);
}

generates the following output:

[/home/pax/]

For MacOs, it's the same theory, but you may not necessarily have procfs available to you. On that system however, there's another way to get the path:

int proc_pidpath(
int pid, // pid of the process to know more about
void * buffer, // buffer to fill with the abs path
uint32_t buffersize // size of the buffer
);

So, in order to use this, replace:

ssize_t sz = readlink("/proc/self/exe", buff, sizeof(buff));

with:

ssize_t sz = proc_pidpath(getpid(), buff, sizeof(buff));

though you'll probably also need the libproc.h header (getpid is already included as part of unistd.h).



Related Topics



Leave a reply



Submit