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);