Advanced Programming in the UNIX® Environment

(lily) #1
ptg10805159

50 UNIX Standardization and Implementations Chapter 2


POSIX.1 tries to help with thePATH_MAXvalue, but if this value is indeterminate,
we’restill out of luck. Figure2.16 shows a function that we’ll use throughout this text
to allocate storage dynamically for a pathname.
If the constantPATH_MAXis defined in<limits.h>,then we’reall set. If it’s not,
then we need to callpathconf.The value returned bypathconfis the maximum size
of a relative pathname when the first argument is the working directory, so we specify
the root as the first argument and add 1 to the result. Ifpathconfindicates that
PATH_MAXis indeterminate, we have to punt and just guess a value.
Versions of POSIX.1 prior to 2001 wereunclear as to whetherPATH_MAXincluded a
null byte at the end of the pathname. If the operating system implementation conforms
to one of these prior versions and doesn’t conform to any version of the Single UNIX
Specification (whichdoesrequirethe terminating null byte to be included), we need to
add 1 to the amount of memory we allocate for a pathname, just to be on the safe side.
The correct way to handle the case of an indeterminate result depends on how the
allocated space is being used. If we areallocating space for a call togetcwd,for
example — toreturn the absolute pathname of the current working directory; see
Section 4.23—and if the allocated space is too small, an error is returned anderrnois
set toERANGE.Wecould then increase the allocated space by callingrealloc(see
Section 7.8 and Exercise 4.16) and try again.We could keep doing this until the call to
getcwdsucceeded.

#include "apue.h"
#include <errno.h>
#include <limits.h>

#ifdef PATH_MAX
static long pathmax = PATH_MAX;
#else
static long pathmax = 0;
#endif

static long posix_version = 0;
static long xsi_version = 0;

/* If PATH_MAX is indeterminate, no guarantee this is adequate */
#define PATH_MAX_GUESS 1024

char *
path_alloc(size_t *sizep) /* also return allocated size, if nonnull */
{
char *ptr;
size_t size;

if (posix_version == 0)
posix_version = sysconf(_SC_VERSION);

if (xsi_version == 0)
xsi_version = sysconf(_SC_XOPEN_VERSION);

if (pathmax == 0) { /* first time through */
Free download pdf