Mail Archives: djgpp-workers/2010/06/07/15:47:55
Lately I have observed that there is a realpath() test snippet in configure
scripts that checks if realpath accepts a NULL pointer as valid second argument.
According to POSIX-1003.1-2008, if a NULL pointer is passed, realpath shall
allocate a buffer of PATH_MAX bytes long to store the resolved path. This is
not the case with the current version of realpath which simply fails if a NULL
pointer is passed. The small patch below solves the issue making the version
more posix compliant. Of course, it will not make the test snippet itself work
because it is completely posix centric, neither less having a posix compliant
version will make porting efforts a little bit easier.
As usual suggestions, objections, corrections are welcome.
Regards,
Juan M. Guerrero
2010-06-06 Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
src/docs/kb/wc204.txi: Allow NULL pointer instead of pointer to allocated
buffer for POSIX compliance.
diff -aprNU5 djgpp.orig/src/docs/kb/wc204.txi djgpp/src/docs/kb/wc204.txi
--- djgpp.orig/src/docs/kb/wc204.txi 2009-09-15 09:14:08 +0000
+++ djgpp/src/docs/kb/wc204.txi 2010-06-07 20:27:32 +0000
@@ -1187,5 +1187,10 @@ but their usage is deprecated.
@findex _O_TEMPORARY AT r{, new flag accepted by @code{open}}
@findex open AT r{, supports temporary files}
The @code{_O_TEMPORARY} flag is an alias for the @code{O_TEMPORARY} flag
supported by @code{open}. It is supported to increase compatibility
with other C compilers.
+
+@findex realpath AT r{, and POSIX.1-2008 compliance}
+If the variable that shall contain the resolved path is a @code{NULL} pointer,
+then @code{realpath} will call @code{malloc} to allocate a buffer of @code{PATH_MAX}
+bytes to store the resolved path name and return this pointer to the caller.
diff -aprNU5 djgpp.orig/src/libc/posix/stdlib/realpath.c djgpp/src/libc/posix/stdlib/realpath.c
--- djgpp.orig/src/libc/posix/stdlib/realpath.c 2002-09-25 21:46:56 +0000
+++ djgpp/src/libc/posix/stdlib/realpath.c 2010-06-07 19:56:50 +0000
@@ -10,11 +10,11 @@
char *
realpath(const char *in, char *out)
{
char in1[PATH_MAX];
- if (in == NULL || out == NULL)
+ if (in == NULL)
{
errno = EINVAL;
return NULL;
}
@@ -22,10 +22,16 @@ realpath(const char *in, char *out)
{
errno = ENOENT;
return NULL;
}
+ if (out == NULL && (out = malloc((size_t)PATH_MAX)) == NULL)
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+
if (!__solve_symlinks(in, in1))
return NULL; /* Return errno from from __solve_dir_symlinks(). */
if (__canonicalize_path(in1, out, PATH_MAX) == NULL)
return NULL; /* Return errno from __canonicalize_path(). */
diff -aprNU5 djgpp.orig/src/libc/posix/stdlib/realpath.txh djgpp/src/libc/posix/stdlib/realpath.txh
--- djgpp.orig/src/libc/posix/stdlib/realpath.txh 2008-06-19 21:09:08 +0000
+++ djgpp/src/libc/posix/stdlib/realpath.txh 2010-06-07 19:56:50 +0000
@@ -27,19 +27,24 @@ Since the returned path name can be long
caller should ensure there is enough space in the buffer pointed to by
@var{out_path}. Use of ANSI-standard constant @code{FILENAME_MAX}
(defined on @file{stdio.h}) or Posix-standard constant @code{PATH_MAX}
(defined on @file{limits.h}) is recommended.
+If @var{out_path} is specified as @code{NULL}, then @code{realpath} uses
+@code{malloc} (@pxref{malloc}) to allocate a buffer of up to @code{PATH_MAX}
+bytes to hold the resolved path name, and returns a pointer to this buffer.
+The caller should deallocate this buffer using @code{free} (@pxref{free}).
+
@subheading Return Value
If successful, a pointer to the result buffer is returned. Otherwise,
@code{NULL} is returned and @code{errno} is set to indicate which error
was detected.
@subheading Portability
-@portability !ansi, posix
+@portability !ansi, posix-1003.1-2008
@subheading Example
@example
char oldpath[100], newpath[PATH_MAX];
- Raw text -