From d8452d22be42e2aa016f7d6709d927bf163c0153 Mon Sep 17 00:00:00 2001 From: Jiuzhu Dong Date: Mon, 25 Jan 2021 12:40:27 +0800 Subject: [PATCH] unistd/getcwd: enhance getcwd when buf is NULL N/A Change-Id: I595e1874349f089691dc5291f31fb376cf0e2e2c Signed-off-by: Jiuzhu Dong --- libs/libc/unistd/lib_getcwd.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/libs/libc/unistd/lib_getcwd.c b/libs/libc/unistd/lib_getcwd.c index 7e2c07defa8..50af97b4d47 100644 --- a/libs/libc/unistd/lib_getcwd.c +++ b/libs/libc/unistd/lib_getcwd.c @@ -63,6 +63,12 @@ * symbolic links. The 'size' argument is the size in bytes of the * character array pointed to by the 'buf' argument. * + * As an extension to the POSIX.1-2001 standard, getcwd() allocates + * the buffer dynamically using malloc if buf is NULL. In this case, + * the allocated buffer has the length size unless size is zero, when buf + * is allocated as big as necessary. The caller should free the + * returned buffer. + * * Input Parameters: * buf - a pointer to the location in which the current working directory * pathname is returned. @@ -74,7 +80,7 @@ * the error: * * EINVAL - * The 'size' argument is 0 or the 'buf' argument is NULL. + * The 'size' argument is 0 and the 'buf' argument is not NULL. * ERANGE * The size argument is greater than 0, but is smaller than the length * of the current working directory pathname +1. @@ -92,13 +98,18 @@ FAR char *getcwd(FAR char *buf, size_t size) /* Verify input parameters */ #ifdef CONFIG_DEBUG_FEATURES - if (!buf || !size) + if (buf && !size) { set_errno(EINVAL); return NULL; } #endif + if (!size) + { + size = PATH_MAX + 1; + } + /* If no working directory is defined, then default to the home directory */ pwd = getenv("PWD"); @@ -115,6 +126,16 @@ FAR char *getcwd(FAR char *buf, size_t size) return NULL; } + if (!buf) + { + buf = malloc(size); + if (!buf) + { + set_errno(ENOMEM); + return NULL; + } + } + /* Copy the cwd to the user buffer */ strcpy(buf, pwd);