logo

utils-std

Collection of commonly available Unix tools
commit: 71488732777247defa6ec1654ab50d56124bb0db
parent 6640362d9df83900ffc23d7d966daaa611ad9fa5
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Wed, 24 Apr 2024 20:20:49 +0200

cmd/readlink: new

Diffstat:

Acmd/readlink.156++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acmd/readlink.c68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest-cmd/readlink.t37+++++++++++++++++++++++++++++++++++++
3 files changed, 161 insertions(+), 0 deletions(-)

diff --git a/cmd/readlink.1 b/cmd/readlink.1 @@ -0,0 +1,56 @@ +.\" utils-std: Collection of commonly available Unix tools +.\" Copyright 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> +.\" SPDX-License-Identifier: MPL-2.0 +.Dd 2024-04-24 +.Dt READLINK 1 +.Os +.Sh NAME +.Nm readlink +.Nd print content of a symbolic link +.Sh SYNOPSIS +.Nm +.Op Fl n +.Ar path +.Sh DESCRIPTION +Note: For canonicalization of a path, see the +.Xr realpath 1 +utility instead. +.Pp +The +.Nm +utility reads the symbolic link of +.Ar path +and prints it. +.Pp +If +.Ar path +is not a symbolic link, +.Nm +errors out. +.Sh OPTIONS +.Bl -tag -width ee +.It Fl n +Do not print a trailing newline. +.El +.Sh EXIT STATUS +.Ex -std +.Sh EXAMPLES +Assign +.Pa //example.org/ +to +.Pa foobar +and read it: +.Bd -literal +$ ln -s //example.org/ foobar +$ readlink foobar +//example.org/ +.Ed +.Sh SEE ALSO +.Xr ln 1 , +.Xr readlink 3 +.Sh STANDARDS +.Nm +should be compliant with +IEEE P1003.1-202x/D4 (“POSIX.1”). +.Sh AUTHORS +.An Haelwenn (lanodan) Monnier Aq Mt contact+utils@hacktivis.me diff --git a/cmd/readlink.c b/cmd/readlink.c @@ -0,0 +1,68 @@ +// utils-std: Collection of commonly available Unix tools +// SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> +// SPDX-License-Identifier: MPL-2.0 + +#define _POSIX_C_SOURCE 200809L + +#include <errno.h> +#include <limits.h> // PATH_MAX +#include <stdbool.h> +#include <stdio.h> // fprintf +#include <string.h> // strerror +#include <unistd.h> // getopt + +static void +usage() +{ + fprintf(stderr, "Usage: readlink [-n] file\n"); +} + +int +main(int argc, char *argv[]) +{ + bool newline = true; + + int c = -1; + while((c = getopt(argc, argv, ":n")) != -1) + { + switch(c) + { + case 'n': + newline = false; + break; + case ':': + fprintf(stderr, "readlink: Error: Missing operand for option: '-%c'\n", optopt); + usage(); + return 1; + case '?': + fprintf(stderr, "readlink: Error: Unrecognised option: '-%c'\n", optopt); + usage(); + return 1; + } + } + + argv += optind; + argc -= optind; + + if(argc != 1) + { + fprintf(stderr, "readlink: Expected one file as argument, got %d\n", argc); + usage(); + return 1; + } + + char buf[PATH_MAX] = ""; + if(readlink(argv[0], buf, sizeof(buf) - 1) < 0) + { + fprintf(stderr, + "readlink: Error: Failed reading symbolic link of '%s': %s\n", + argv[0], + strerror(errno)); + return 1; + } + + printf("%s", buf); + if(newline) printf("\n"); + + return 0; +} diff --git a/test-cmd/readlink.t b/test-cmd/readlink.t @@ -0,0 +1,37 @@ +#!/usr/bin/env cram +# SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> +# SPDX-License-Identifier: MPL-2.0 + + $ export PATH="$TESTDIR/../cmd:$PATH" + + $ test "$(command -v readlink)" = "$TESTDIR/../cmd/readlink" + + $ ln -s //example.org/ foobar + $ readlink foobar + //example.org/ + $ readlink -n foobar + //example.org/ (no-eol) + + $ readlink + readlink: Expected one file as argument, got 0 + Usage: readlink [-n] file + [1] + $ readlink foo bar + readlink: Expected one file as argument, got 2 + Usage: readlink [-n] file + [1] + + $ test ! -f enoent + $ readlink enoent + readlink: Error: Failed reading symbolic link of 'enoent': No such file or directory + [1] + + $ touch regular + $ readlink regular + readlink: Error: Failed reading symbolic link of 'regular': Invalid argument + [1] + + $ mkdir dir + $ readlink dir + readlink: Error: Failed reading symbolic link of 'dir': Invalid argument + [1]