Iḿ writing a function which must return at the end the name of the file the link is pointing to if you enter -link and not return it if you dont write that command. The thing is that I dont know how to get the name of the file with the function "readlink()" because it returns the size of the file but not the name, and searching in "https://pubs.opengroup.org/onlinepubs/000095399/functions/readlink.html" I couldnt understand the way to get the name from the file.
printf("%s %ld (%lu) %s %s ", time, info.st_nlink, info.st_ino, pw->pw_name, gr->gr_name); //prints a bunch of information about the file
printf( (S_ISDIR(info.st_mode)) ? "d" : "-");
printf( (info.st_mode & S_IRUSR) ? "r" : "-");
printf( (info.st_mode & S_IWUSR) ? "w" : "-");
printf( (info.st_mode & S_IXUSR) ? "x" : "-");
printf( (info.st_mode & S_IRGRP) ? "r" : "-");
printf( (info.st_mode & S_IWGRP) ? "w" : "-");
printf( (info.st_mode & S_IXGRP) ? "x" : "-");
printf( (info.st_mode & S_IROTH) ? "r" : "-");
printf( (info.st_mode & S_IWOTH) ? "w" : "-");
printf( (info.st_mode & S_IXOTH) ? "x" : "-");
if(!opts.link){ //If the -link command wasnt written
printf(" %ld %s\n", info.st_size, tokens[2]);
} else{
//Here I need to print the same as in the last line but adding the name of the file the link points to like this:
printf(" %ld %s -> %s\n", info.st_size, tokens[2], name);
}
CodePudding user response:
From the POSIX readlink
reference:
The
readlink()
function shall place the contents of the symbolic link referred to bypath
in the bufferbuf
...
You pass the link name in the first argument (named path
in the reference). The function will then expand the link and copy it into the second argument (named buf
). The size of the array used for buf
is passed as the third argument (bufsize
).
The function returns the length of the byte array it wrote in buf
(it is not a string except by accident). Or -1
on error.
You you could call it something like:
char buffer[1024];
ssize_t link_string_length;
if ((link_string_length = readlink(your_filename_for_stat, buffer, sizeof buffer)) == -1)
{
perror("readlink");
}
else
{
// Make sure that the buffer is terminated as a string
buffer[link_string_length] = '\0';
printf("%s -> %s\n", your_filename_for_stat, buffer);
}
CodePudding user response:
Use readlink()
. The return value is the length of the name, but one of the arguments is a buffer into which the name is copied:
ssize_t readlink(const char *restrict path, char *restrict buf,
size_t bufsize);
Beware that the name is not null-terminated:
The
readlink()
function shall place the contents of the symbolic link referred to by path in the buffer buf which has size bufsize. If the number of bytes in the symbolic link is less than bufsize, the contents of the remainder of buf are unspecified. If the buf argument is not large enough to contain the link content, the first bufsize bytes shall be placed in buf.
You should ensure that there's enough space in the buffer for the return value plus a null byte.
My opinion on the design of readlink()
not adding the null byte to create a string is NSFW.