1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
#define _XOPEN_SOURCE 700
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int
main(int argc, char **argv) {
int c, flag_L = 1;
long size;
while ((c = getopt(argc, argv, "LP")) != -1) {
switch (c) {
case 'L':
flag_L = 1;
break;
case 'P':
flag_L = 0;
break;
case '?':
fprintf(stderr, "usage: %s [-L|-P]\n", argv[0]);
return 1;
}
}
if (flag_L) {
char *cwd = getenv("PWD");
if (cwd == NULL)
goto flag_P;
else if (*cwd != '/')
goto flag_P;
else if (strstr(cwd, "/./") != NULL)
goto flag_P;
else if (strstr(cwd, "/../") != NULL)
goto flag_P;
/* POSIX.1-2017 does not specify what to do if $PWD is longer than PATH_MAX bytes;
* this implementation chooses to print the pathname found from PWD in this case.
*/
puts(cwd);
return 0;
}
flag_P:
size = pathconf(".", _PC_PATH_MAX);
if (size == -1)
size = PATH_MAX;
char *buf = NULL;
for (char *tmp = NULL; tmp == NULL; size += 32) {
char *b = realloc(buf, size);
if (b == NULL) {
free(buf);
perror("pwd");
return 1;
}
buf = b;
errno = 0;
tmp = getcwd(buf, size);
if (tmp == NULL && errno != ERANGE) {
perror("pwd");
free(buf);
return 1;
}
}
puts(buf);
free(buf);
return 0;
}
|