1 /* Copyright (C) 2011-2024 Free Software Foundation, Inc.
2 This file is part of gnulib.
4 This file is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2.1 of the
7 License, or (at your option) any later version.
9 This file is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
25 #if defined _WIN32 && !defined __CYGWIN__
28 wgetcwd (wchar_t *buf
, size_t size
)
34 <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/getcwd-wgetcwd>
35 Note that for a directory consisting of LEN wide characters, the SIZE
36 argument to _wgetcwd needs to be >= LEN + 3, not only >= LEN + 1, with
37 some versions of the Microsoft runtime libraries. */
39 /* Handle single size operations. */
42 /* Check SIZE argument. */
48 /* Invoke _wgetcwd as-is. In this case, the caller does not expect
49 an ENOMEM error; therefore don't use temporary memory. */
50 return _wgetcwd (buf
, size
);
55 /* Allocate room for two more wide characters, so that directory names
56 of length <= SIZE - 1 can be returned. */
57 buf
= malloc ((size
+ 2) * sizeof (wchar_t));
63 result
= _wgetcwd (buf
, size
+ 2);
69 if (wcslen (result
) >= size
)
75 /* Shrink result before returning it. */
76 wchar_t *shrinked_result
= realloc (result
, size
* sizeof (wchar_t));
77 if (shrinked_result
!= NULL
)
78 result
= shrinked_result
;
82 /* Flexible sizing requested. Avoid over-allocation for the common
83 case of a name that fits within a 4k page, minus some space for
84 local variables, to be sure we don't skip over a guard page. */
86 wchar_t tmp
[4032 / sizeof (wchar_t)];
87 size
= sizeof tmp
/ sizeof (wchar_t);
88 wchar_t *ptr
= _wgetcwd (tmp
, size
);
91 result
= _wcsdup (ptr
);
100 /* My what a large directory name we have. */
104 wchar_t *ptr
= realloc (buf
, size
* sizeof (wchar_t));
112 result
= _wgetcwd (buf
, size
);
114 while (!result
&& errno
== ERANGE
);
120 /* Here result == buf. */
121 /* Shrink result before returning it. */
122 size_t actual_size
= wcslen (result
) + 1;
123 if (actual_size
< size
)
125 wchar_t *shrinked_result
=
126 realloc (result
, actual_size
* sizeof (wchar_t));
127 if (shrinked_result
!= NULL
)
128 result
= shrinked_result
;