4 * Provides an implementation of the "realpath" function, conforming
5 * approximately to SUSv3, and adapted for use on native Microsoft(R)
8 * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
10 * This is free software. You may redistribute and/or modify it as you
11 * see fit, without restriction of copyright.
13 * This software is provided "as is", in the hope that it may be useful,
14 * but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of
15 * MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE. At no
16 * time will the author accept any form of liability for any damages,
17 * however caused, resulting from the use of this software.
26 *realpath( const char *__restrict__ name
, char *__restrict__ resolved
)
28 char *retname
= NULL
; /* we will return this, if we fail */
30 /* SUSv3 says we must set `errno = EINVAL', and return NULL,
31 * if `name' is passed as a NULL pointer.
37 /* Otherwise, `name' must refer to a readable filesystem object,
38 * if we are going to resolve its absolute path name.
41 else if( access( name
, 4 ) == 0 )
43 /* If `name' didn't point to an existing entity,
44 * then we don't get to here; we simply fall past this block,
45 * returning NULL, with `errno' appropriately set by `access'.
47 * When we _do_ get to here, then we can use `_fullpath' to
48 * resolve the full path for `name' into `resolved', but first,
49 * check that we have a suitable buffer, in which to return it.
52 if( (retname
= resolved
) == NULL
)
54 /* Caller didn't give us a buffer, so we'll exercise the
55 * option granted by SUSv3, and allocate one.
57 * `_fullpath' would do this for us, but it uses `malloc', and
58 * Microsoft's implementation doesn't set `errno' on failure.
59 * If we don't do this explicitly ourselves, then we will not
60 * know if `_fullpath' fails on `malloc' failure, or for some
61 * other reason, and we want to set `errno = ENOMEM' for the
62 * `malloc' failure case.
65 retname
= (char*)malloc( _MAX_PATH
);
68 /* By now, we should have a valid buffer.
69 * If we don't, then we know that `malloc' failed,
70 * so we can set `errno = ENOMEM' appropriately.
76 /* Otherwise, when we do have a valid buffer,
77 * `_fullpath' should only fail if the path name is too long.
80 else if( (retname
= _fullpath( retname
, name
, _MAX_PATH
)) == NULL
)
84 /* By the time we get to here,
85 * `retname' either points to the required resolved path name,
86 * or it is NULL, with `errno' set appropriately, either of which
87 * is our required return condition.
93 /* $RCSfile$: end of file */