Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/bin/pwd/pwd.c
105563 views
1
/*-
2
* SPDX-License-Identifier: BSD-3-Clause
3
*
4
* Copyright (c) 1991, 1993, 1994
5
* The Regents of the University of California. All rights reserved.
6
* Copyright (c) 2026 Dag-Erling Smørgrav
7
*
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
10
* are met:
11
* 1. Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
* 3. Neither the name of the University nor the names of its contributors
17
* may be used to endorse or promote products derived from this software
18
* without specific prior written permission.
19
*
20
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
* SUCH DAMAGE.
31
*/
32
33
#include <sys/param.h>
34
#include <sys/stat.h>
35
36
#include <err.h>
37
#include <stdbool.h>
38
#include <stdio.h>
39
#include <stdlib.h>
40
#include <unistd.h>
41
42
static char *
43
getcwd_logical(void)
44
{
45
struct stat log, phy;
46
char *pwd, *p, *q;
47
48
/* $PWD is set and absolute */
49
if ((pwd = getenv("PWD")) == NULL || *pwd != '/')
50
return (NULL);
51
/* $PWD does not contain /./ or /../ */
52
for (p = pwd; *p; p = q) {
53
for (q = ++p; *q && *q != '/'; q++)
54
/* nothing */;
55
if ((*p == '.' && q == ++p) ||
56
(*p == '.' && q == ++p))
57
return (NULL);
58
}
59
/* $PWD refers to the current directory */
60
if (stat(pwd, &log) != 0 || stat(".", &phy) != 0 ||
61
log.st_dev != phy.st_dev || log.st_ino != phy.st_ino)
62
return (NULL);
63
return (pwd);
64
}
65
66
static char *
67
getcwd_physical(void)
68
{
69
static char pwd[MAXPATHLEN];
70
71
return (getcwd(pwd, sizeof(pwd)));
72
}
73
74
static void
75
usage(void)
76
{
77
(void)fprintf(stderr, "usage: pwd [-L | -P]\n");
78
exit(1);
79
}
80
81
int
82
main(int argc, char *argv[])
83
{
84
char *pwd;
85
int opt;
86
bool logical;
87
88
logical = true;
89
while ((opt = getopt(argc, argv, "LP")) != -1) {
90
switch (opt) {
91
case 'L':
92
logical = true;
93
break;
94
case 'P':
95
logical = false;
96
break;
97
default:
98
usage();
99
}
100
}
101
argc -= optind;
102
argv += optind;
103
if (argc != 0)
104
usage();
105
106
/*
107
* If we're trying to find the logical current directory and that
108
* fails, behave as if -P was specified.
109
*/
110
if ((logical && (pwd = getcwd_logical()) != NULL) ||
111
(pwd = getcwd_physical()) != NULL)
112
printf("%s\n", pwd);
113
else
114
err(1, ".");
115
if (fflush(stdout) != 0)
116
err(1, "stdout");
117
exit(0);
118
}
119
120