]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/getcwd.c
Remove "Contributed by" lines
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / getcwd.c
CommitLineData
fe0ec73e 1/* Determine current working directory. Linux version.
2b778ceb 2 Copyright (C) 1997-2021 Free Software Foundation, Inc.
fe0ec73e 3 This file is part of the GNU C Library.
fe0ec73e
UD
4
5 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
fe0ec73e
UD
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 13 Lesser General Public License for more details.
fe0ec73e 14
41bdb6e2 15 You should have received a copy of the GNU Lesser General Public
59ba27a6 16 License along with the GNU C Library; if not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
fe0ec73e 18
958f238f 19#include <assert.h>
fe0ec73e
UD
20#include <errno.h>
21#include <limits.h>
22#include <stdlib.h>
23#include <unistd.h>
df6a4a4a 24#include <sys/param.h>
0dee6738
UD
25
26#include <sysdep.h>
63bda0c1 27#include <sys/syscall.h>
fe0ec73e 28
958f238f 29
8d04a97c
UD
30/* If we compile the file for use in ld.so we don't need the feature
31 that getcwd() allocates the buffers itself. */
a3848485 32#if IS_IN (rtld)
8d04a97c
UD
33# define NO_ALLOCATION 1
34#endif
35
36
7fb90fb8
UD
37/* The "proc" filesystem provides an easy method to retrieve the value.
38 For each process, the corresponding directory contains a symbolic link
39 named `cwd'. Reading the content of this link immediate gives us the
40 information. But we have to take care for systems which do not have
41 the proc filesystem mounted. Use the POSIX implementation in this case. */
fcdbd910
AZ
42
43/* Get the code for the generic version. */
44#define GETCWD_RETURN_TYPE static char *
45#include <sysdeps/posix/getcwd.c>
7fb90fb8 46
fe0ec73e
UD
47char *
48__getcwd (char *buf, size_t size)
49{
fe0ec73e 50 char *path;
fe0ec73e 51 char *result;
6973fc01 52
8d04a97c
UD
53#ifndef NO_ALLOCATION
54 size_t alloc_size = size;
a2b3aa73 55 if (size == 0)
fe0ec73e
UD
56 {
57 if (buf != NULL)
58 {
59 __set_errno (EINVAL);
60 return NULL;
61 }
62
6c7a5753 63 alloc_size = MAX (PATH_MAX, __getpagesize ());
fe0ec73e
UD
64 }
65
8d04a97c 66 if (buf == NULL)
fe0ec73e 67 {
6973fc01 68 path = malloc (alloc_size);
fe0ec73e
UD
69 if (path == NULL)
70 return NULL;
71 }
8d04a97c
UD
72 else
73#else
74# define alloc_size size
75#endif
76 path = buf;
fe0ec73e 77
ffb7875d 78 int retval;
7fb90fb8 79
6277fdab 80 retval = INLINE_SYSCALL (getcwd, 2, path, alloc_size);
52a713fd 81 if (retval > 0 && path[0] == '/')
ffb7875d
JM
82 {
83#ifndef NO_ALLOCATION
84 if (buf == NULL && size == 0)
85 /* Ensure that the buffer is only as large as necessary. */
86 buf = realloc (path, (size_t) retval);
958f238f
UD
87
88 if (buf == NULL)
ffb7875d
JM
89 /* Either buf was NULL all along, or `realloc' failed but
90 we still have the original string. */
91 buf = path;
92#endif
958f238f 93
ffb7875d 94 return buf;
63bda0c1 95 }
63bda0c1 96
52a713fd
DL
97 /* The system call either cannot handle paths longer than a page
98 or can succeed without returning an absolute path. Just use the
ffb7875d 99 generic implementation right away. */
52a713fd 100 if (retval >= 0 || errno == ENAMETOOLONG)
fe0ec73e 101 {
8d04a97c 102#ifndef NO_ALLOCATION
ffb7875d
JM
103 if (buf == NULL && size == 0)
104 {
105 free (path);
106 path = NULL;
fe0ec73e 107 }
958f238f 108#endif
fe0ec73e 109
fcdbd910 110 result = __getcwd_generic (path, size);
6973fc01 111
8d04a97c 112#ifndef NO_ALLOCATION
ffb7875d
JM
113 if (result == NULL && buf == NULL && size != 0)
114 free (path);
8d04a97c 115#endif
6973fc01 116
ffb7875d
JM
117 return result;
118 }
119
120 /* It should never happen that the `getcwd' syscall failed because
121 the buffer is too small if we allocated the buffer ourselves
122 large enough. */
123 assert (errno != ERANGE || buf != NULL || size != 0);
fe0ec73e 124
8d04a97c 125#ifndef NO_ALLOCATION
ffb7875d 126 if (buf == NULL)
fe0ec73e 127 free (path);
8d04a97c 128#endif
fe0ec73e 129
ffb7875d 130 return NULL;
fe0ec73e 131}
db25266c 132libc_hidden_def (__getcwd)
fe0ec73e 133weak_alias (__getcwd, getcwd)