master xplshn/aruu / cmd / posix / readlink.c
 1/* See LICENSE file for copyright and license details. */
 2
 3
 4#include <limits.h>
 5#include <stdio.h>
 6#include <stdlib.h>
 7#include <string.h>
 8#include <unistd.h>
 9
10#include "util.h"
11
12static void
13usage(void)
14{
15#if FEATURE_READLINK_REALPATH
16	eprintf("usage: %s [-fn] path\n", argv0);
17#else
18	eprintf("usage: %s [-n] path\n", argv0);
19#endif
20}
21
22// ?man readlink: print value of symlink
23// ?man arguments: path
24// ?man display the target of a symbolic link
25int
26main(int argc, char *argv[])
27{
28	char buf[PATH_MAX];
29	ssize_t n;
30	int nflag = 0;
31#if FEATURE_READLINK_REALPATH
32	int fflag = 0;
33#endif
34
35	ARGBEGIN
36	{
37#if FEATURE_READLINK_REALPATH
38	// ?man -f: force the operation
39	case 'f':
40		fflag = 1;
41		break;
42#endif
43	// ?man -n: print line numbers or counts
44	case 'n':
45		nflag = 1;
46		break;
47	default:
48		usage();
49	}
50	ARGEND
51
52	if (argc != 1)
53		usage();
54
55	if (strlen(argv[0]) >= PATH_MAX)
56		eprintf("path too long\n");
57
58#if FEATURE_READLINK_REALPATH
59	if (fflag) {
60		if (!realpath(argv[0], buf))
61			eprintf("realpath %s:", argv[0]);
62	} else
63#endif
64	{
65		if ((n = readlink(argv[0], buf, PATH_MAX - 1)) < 0)
66			eprintf("readlink %s:", argv[0]);
67		buf[n] = '\0';
68	}
69
70	fputs(buf, stdout);
71	if (!nflag)
72		putchar('\n');
73
74	return fshut(stdout, "<stdout>");
75}