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