From 9221dca64f0c8b5de72727491e41cf63e902eaab Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 6 May 2024 03:16:24 +0200 Subject: Adding upstream version 2.8.5. Signed-off-by: Daniel Baumann --- gl/lib/getcwd-lgpl.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 gl/lib/getcwd-lgpl.c (limited to 'gl/lib/getcwd-lgpl.c') diff --git a/gl/lib/getcwd-lgpl.c b/gl/lib/getcwd-lgpl.c new file mode 100644 index 0000000..b224cfc --- /dev/null +++ b/gl/lib/getcwd-lgpl.c @@ -0,0 +1,126 @@ +/* Copyright (C) 2011-2019 Free Software Foundation, Inc. + This file is part of gnulib. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +/* Specification */ +#include + +#include +#include +#include + +#if GNULIB_GETCWD +/* Favor GPL getcwd.c if both getcwd and getcwd-lgpl modules are in use. */ +typedef int dummy; +#else + +/* Get the name of the current working directory, and put it in SIZE + bytes of BUF. Returns NULL if the directory couldn't be determined + (perhaps because the absolute name was longer than PATH_MAX, or + because of missing read/search permissions on parent directories) + or SIZE was too small. If successful, returns BUF. If BUF is + NULL, an array is allocated with 'malloc'; the array is SIZE bytes + long, unless SIZE == 0, in which case it is as big as + necessary. */ + +# undef getcwd +char * +rpl_getcwd (char *buf, size_t size) +{ + char *ptr; + char *result; + + /* Handle single size operations. */ + if (buf) + { + if (!size) + { + errno = EINVAL; + return NULL; + } + return getcwd (buf, size); + } + + if (size) + { + buf = malloc (size); + if (!buf) + { + errno = ENOMEM; + return NULL; + } + result = getcwd (buf, size); + if (!result) + { + int saved_errno = errno; + free (buf); + errno = saved_errno; + } + return result; + } + + /* Flexible sizing requested. Avoid over-allocation for the common + case of a name that fits within a 4k page, minus some space for + local variables, to be sure we don't skip over a guard page. */ + { + char tmp[4032]; + size = sizeof tmp; + ptr = getcwd (tmp, size); + if (ptr) + { + result = strdup (ptr); + if (!result) + errno = ENOMEM; + return result; + } + if (errno != ERANGE) + return NULL; + } + + /* My what a large directory name we have. */ + do + { + size <<= 1; + ptr = realloc (buf, size); + if (ptr == NULL) + { + free (buf); + errno = ENOMEM; + return NULL; + } + buf = ptr; + result = getcwd (buf, size); + } + while (!result && errno == ERANGE); + + if (!result) + { + int saved_errno = errno; + free (buf); + errno = saved_errno; + } + else + { + /* Trim to fit, if possible. */ + result = realloc (buf, strlen (buf) + 1); + if (!result) + result = buf; + } + return result; +} + +#endif -- cgit v1.2.3