summaryrefslogtreecommitdiff
path: root/src/common/compat.c
diff options
context:
space:
mode:
authorcypherpunks <cypherpunks@torproject.org>2017-08-03 19:45:46 +0000
committerNick Mathewson <nickm@torproject.org>2017-08-04 12:22:53 -0400
commitbfe740f0658dc05e9cc624a46ae21bb098117197 (patch)
tree6753b8ef70bd675928ed3d76cab7e7d564d4be55 /src/common/compat.c
parent0265ced02b7a652c5941cb2c14ee1e0de0b1d90e (diff)
downloadtor-bfe740f0658dc05e9cc624a46ae21bb098117197.tar.gz
tor-bfe740f0658dc05e9cc624a46ae21bb098117197.zip
Refactor retrieving the current working directory
The GNU C Library (glibc) offers an function which allocates the necessary memory automatically [0]. When it is available, we use that. Otherwise we depend upon the `getcwd` function which requires a preallocated buffer (and its size). This function was used incorrectly by depending on the initial buffer size being big enough and otherwise failing to return the current working directory. The proper way of getting the current working directory requires a loop which doubles the buffer size if `getcwd` requires it. This code was copied from [1] with modifications to fit the context. [0] https://www.gnu.org/software/hurd/hurd/porting/guidelines.html [1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html
Diffstat (limited to 'src/common/compat.c')
-rw-r--r--src/common/compat.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/src/common/compat.c b/src/common/compat.c
index 4d110aba35..8e3d97420a 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -2349,15 +2349,26 @@ get_parent_directory(char *fname)
static char *
alloc_getcwd(void)
{
-#ifdef PATH_MAX
-#define MAX_CWD PATH_MAX
+#ifdef HAVE_GET_CURRENT_DIR_NAME
+ return get_current_dir_name();
#else
-#define MAX_CWD 4096
-#endif
+ size_t size = 1024;
+ char *buf = NULL;
+ char *ptr = NULL;
+
+ while (ptr == NULL) {
+ buf = tor_realloc(buf, size);
+ ptr = getcwd(buf, size);
- char path_buf[MAX_CWD];
- char *path = getcwd(path_buf, sizeof(path_buf));
- return path ? tor_strdup(path) : NULL;
+ if (ptr == NULL && errno != ERANGE) {
+ tor_free(buf);
+ return NULL;
+ }
+
+ size *= 2;
+ }
+ return buf;
+#endif
}
#endif