commit f66b47bc6f7ce63409855668d0d1550b83638609
parent 4d38f6068500104693796059da3950a2de296af3
Author: stateless <stateless@archlinux.us>
Date: Sat, 15 Jun 2013 15:17:57 +0100
Add readlink
Signed-off-by: Christoph Lohmann <20h@r-36.net>
Diffstat:
3 files changed, 81 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -51,6 +51,7 @@ SRC = \
paste.c \
printenv.c \
pwd.c \
+ readlink.c \
renice.c \
rm.c \
rmdir.c \
diff --git a/readlink.1 b/readlink.1
@@ -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)
diff --git a/readlink.c b/readlink.c
@@ -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;
+}