Add readlink

Signed-off-by: Christoph Lohmann <20h@r-36.net>
This commit is contained in:
stateless 2013-06-15 15:17:57 +01:00 committed by Christoph Lohmann
parent 4d38f60685
commit f66b47bc6f
3 changed files with 81 additions and 0 deletions

View File

@ -51,6 +51,7 @@ SRC = \
paste.c \
printenv.c \
pwd.c \
readlink.c \
renice.c \
rm.c \
rmdir.c \

25
readlink.1 Normal file
View File

@ -0,0 +1,25 @@
.TH READLINK 1 sbase\-VERSION
.SH NAME
readlink \- print value of a symbolic link or canonical file name
.SH SYNOPSIS
.B readlink
.RB [ \-fn ]
.IR file
.SH DESCRIPTION
The readlink utility when invoked with the pathname of a symbolic link as
its argument dereferences the symbolic link and prints the name of target
on standard output. If the -f option is not specified and readlink is
invoked with an argument other than the pathname of a symbolic link, it
exits with a nonzero exit code without printing anything.
.SH OPTIONS
.TP
.B \-f
Canonicalize by following every symlink in every component of the
given path recursively. The argument does not need to be a symbolic
link.
.TP
.B \-n
Do not output the trailing newline.
.SH SEE ALSO
.IR readlink (2),
.IR realpath (3)

55
readlink.c Normal file
View File

@ -0,0 +1,55 @@
/* See LICENSE file for copyright and license details. */
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
static void
usage(void)
{
eprintf("usage: %s [-fn] file\n", argv0);
exit(1);
}
int
main(int argc, char *argv[])
{
char buf[PATH_MAX];
bool nflag = false;
bool fflag = false;
ARGBEGIN {
case 'f':
fflag = true;
break;
case 'n':
nflag = true;
break;
default:
usage();
} ARGEND;
if (argc != 1)
usage();
if (strlen(argv[0]) > PATH_MAX - 1)
exit(1);
if (fflag) {
if (realpath(argv[0], buf) == NULL)
exit(1);
} else {
if (readlink(argv[0], buf, sizeof(buf)) < 0)
exit(1);
}
printf("%s", buf);
if (!nflag)
putchar('\n');
return 0;
}