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
Changing File Permissions Linux
Caputre Opengl Window in X11 with Fast Framerate - Possible
Generating a Comprehensive Callgraph Using Gcc & Egypt
How to Play an Audio File from Haskell Code, Cross-Platform
Systemd Enabled Services Not Starting at Boot Anymore
Bash Cut Columns to One File and Save onto The End of Another File
System Calls: Difference Between Sys_Exit(), Sys_Exit and Exit()
Qt - How to Detect Whether The Application Is Running on Gnome or Kde
Docker - Eacces: Permission Denied, Mkdir '/App/Node_Modules/.Cache'
Can Not Route Packets from One Interface to Another
Pci-E Memory Space Access with Mmap
Unix/Linux Ipc: Reading from a Pipe. How to Know Length of Data at Runtime
Where Is G_Multi Configured in Beaglebone Black