---
name: "path"
section: "3"
platform: "macos"
package: "ksh"
version: "42"
release: "macOS 26.5"
platforms: ["macos"]
url: "https://new.carta.tech/path"
---

# path(3)

file path routines

## NAME

path - file path routines

## SYNOPSIS

```
#include <ast.h>
char*     pathaccess(char* path, const char* dirs, const char* a, const char* b, int mode);
char*     pathbin(void);
char*     pathcanon(char* path, int flags);
char*     pathcat(char* path, const char* dirs, int sep, const char* a, const char* b);
char*     pathcd(char* path, const char* home);
int       pathcheck(const char* package, const char* tool, Pathcheck_t* pc);
int       pathgetlink(const char* name, char* buf, int siz);
char*     pathkey(char* key, char* attr, const char* lang, const char* path);
char*     pathnext(char* path, char* extra, long* visits);
char*     pathpath(char* path, const char* p, const char* a, int mode);
char*     pathprobe(char* path, char* attr, const char* lang, const char* tool, const char* proc, int op);
char*     pathrepl(char* path, const char* match, const char* replace);
int       pathsetlink(const char* text, char* name);
char*     pathshell(void);
int       pathstat(const char* path, struct stat* st);
char*     pathtemp(char* path, const char* dir, const char* pfx);
```

## DESCRIPTION

*These routines operate on file path names.* *Path buffers are assumed to be of size* $1$2PATH\_MAXPATH\_MAXPATH\_MAXPATH\_MAXPATH\_MAXPATH\_MAXPATH\_MAXPATH\_MAX $1$2\<ast.h\>\<ast.h\>\<ast.h\>\<ast.h\>\<ast.h\>\<ast.h\>\<ast.h\>\<ast.h\> always defines $1$2PATH\_MAXPATH\_MAXPATH\_MAXPATH\_MAXPATH\_MAXPATH\_MAXPATH\_MAXPATH\_MAX even if it indeterminant on the local system. Yes, this was probably a bad choice, but it was made about 10 years ago. We will probably move to a \<stk.h\> based implementation.

$1$2pathaccesspathaccesspathaccesspathaccesspathaccesspathaccesspathaccesspathaccess constructs a path in $1$2pathpathpathpathpathpathpathpath to the file $1$2a/ba/ba/ba/ba/ba/ba/ba/b with access $1$2modemodemodemodemodemodemodemode using the $1$2:::::::: separated directories in  *dirs*. Both *a* and *b* may be $1$200000000 $1$2modemodemodemodemodemodemodemode is the inclusive-or of:

- $1$2F\_OKF\_OKF\_OKF\_OKF\_OKF\_OKF\_OKF\_OK

  File exists.

- $1$2R\_OKR\_OKR\_OKR\_OKR\_OKR\_OKR\_OKR\_OK

  Read permission on file.

- $1$2W\_OKW\_OKW\_OKW\_OKW\_OKW\_OKW\_OKW\_OK

  Write permission on file.

- $1$2X\_OKX\_OKX\_OKX\_OKX\_OKX\_OKX\_OKX\_OK

  Execute permission on file.

- $1$2PATH\_REGULARPATH\_REGULARPATH\_REGULARPATH\_REGULARPATH\_REGULARPATH\_REGULARPATH\_REGULARPATH\_REGULAR

  A regular file.

- $1$2PATH\_ABSOLUTEPATH\_ABSOLUTEPATH\_ABSOLUTEPATH\_ABSOLUTEPATH\_ABSOLUTEPATH\_ABSOLUTEPATH\_ABSOLUTEPATH\_ABSOLUTE

  Generated path name is rooted at $1$2//////// *path* is returned, 0 on error.

$1$2pathbinpathbinpathbinpathbinpathbinpathbinpathbinpathbin returns a pointer to the  $1$2:::::::: separated list of directories to search for executable commands. The $1$2PATHPATHPATHPATHPATHPATHPATHPATH environment variable is first consulted. If not defined then $1$2confstr(\_CS\_PATH,...)confstr(\_CS\_PATH,...)confstr(\_CS\_PATH,...)confstr(\_CS\_PATH,...)confstr(\_CS\_PATH,...)confstr(\_CS\_PATH,...)confstr(\_CS\_PATH,...)confstr(\_CS\_PATH,...) is used. A valid string is always returned.

$1$2pathcanonpathcanonpathcanonpathcanonpathcanonpathcanonpathcanonpathcanon canonicalizes the path *path* in place. A pointer to the trailing 0 in the canonicalized path is returned. A canonical path has: redundant  $1$2........ and $1$2//////// removed; $1$2................ moved to the front; $1$2/../../../../../../../.. preserved for super root hacks; $1$2........................ resolved if [*fs3d*(3)](/fs3d/3.md) is enabled. *flags is the inclusive-or of:*

- $1$2PATH\_DOTDOTPATH\_DOTDOTPATH\_DOTDOTPATH\_DOTDOTPATH\_DOTDOTPATH\_DOTDOTPATH\_DOTDOTPATH\_DOTDOT

  Each $1$2................ is checked for access.

- $1$2PATH\_EXISTSPATH\_EXISTSPATH\_EXISTSPATH\_EXISTSPATH\_EXISTSPATH\_EXISTSPATH\_EXISTSPATH\_EXISTS

  Path must exist at each component.

- $1$2PATH\_PHYSICALPATH\_PHYSICALPATH\_PHYSICALPATH\_PHYSICALPATH\_PHYSICALPATH\_PHYSICALPATH\_PHYSICALPATH\_PHYSICAL

  Symbolic links are resolved at each component.

0 is returned on error. If an error occurs and either of $1$2PATH\_DOTDOTPATH\_DOTDOTPATH\_DOTDOTPATH\_DOTDOTPATH\_DOTDOTPATH\_DOTDOTPATH\_DOTDOTPATH\_DOTDOT or $1$2PATH\_EXISTSPATH\_EXISTSPATH\_EXISTSPATH\_EXISTSPATH\_EXISTSPATH\_EXISTSPATH\_EXISTSPATH\_EXISTS is set then *path* will contain the components following the failure point.

$1$2pathcatpathcatpathcatpathcatpathcatpathcatpathcatpathcat concatenates the first *sep* separated path component in *dirs* with the path components *a* and *b* into $1$2pathpathpathpathpathpathpathpath The path is constructed in *path* by separating each path component with */*. Both *a* and *b* may be $1$200000000 A pointer to the next *sep* separated component in *dirs* is returned, $1$200000000 when there are no more components. $1$2pathcatpathcatpathcatpathcatpathcatpathcatpathcatpathcat is used by $1$2pathaccesspathaccesspathaccesspathaccesspathaccesspathaccesspathaccesspathaccess

$1$2pathcdpathcdpathcdpathcdpathcdpathcdpathcdpathcd sets the current working directory to *path* via [*chdir*(2)](/chdir/2.md). If *path* is longer than $1$2PATH\_MAXPATH\_MAXPATH\_MAXPATH\_MAXPATH\_MAXPATH\_MAXPATH\_MAXPATH\_MAX then it is split up into a sequence of relative paths and *chdir* is called on each of these. For any given system, if you got to a directory, then  $1$2pathcdpathcdpathcdpathcdpathcdpathcdpathcdpathcd can get you back, modulo permission and link changes.

$1$2pathcheckpathcheckpathcheckpathcheckpathcheckpathcheckpathcheckpathcheck is a stub for license libraries. See *license*(3).

$1$2pathgetlinkpathgetlinkpathgetlinkpathgetlinkpathgetlinkpathgetlinkpathgetlinkpathgetlink returns the 0-terminated symbolic link text for *path* in the buffer *bu* of size *siz*. The link text length is returned on success, -1 on error. Weird *universe (1)* interactions with dynamic symbolic links are handled by converting non-standard dynamic link text to $1$2pathsetsymlinkpathsetsymlinkpathsetsymlinkpathsetsymlinkpathsetsymlinkpathsetsymlinkpathsetsymlinkpathsetsymlink converts in the other direction.

$1$2pathkeypathkeypathkeypathkeypathkeypathkeypathkeypathkey generates in  *key* a 14 character lookup key (plus terminating 0) for the language *lang* processor in *path*. A poihter to the key is returned, 0 on error. If *key == 0* then space is allocated via [*malloc*(3)](/malloc/3.md). Key specific attribute *name=value* pairs are copied into *attr* if *attr != 0*.

$1$2pathpathpathpathpathpathpathpathpathpathpathpathpathpathpathpath constructs in *path* a path to *p* with [*access*(2)](/access/2.md) mode *mode* using the directories from $1$2pathbin()pathbin()pathbin()pathbin()pathbin()pathbin()pathbin()pathbin() If *a != 0* then *a*, *argv*\[0\] (if available via [*optget*(3)](/optget/3.md)), and the $1$2\_\_\_\_\_\_\_\_ environment variable (set by [*ksh*(1)](/ksh/1.md)*)* are used for related root searching. If  *p* also contains a  $1$2//////// then *../p* is searched for.

$1$2pathprobepathprobepathprobepathprobepathprobepathprobepathprobepathprobe generates in *path* the full path name of the *tool* specific [*probe*(1)](/probe/1.md) information file for the *lang* langauge processor *proc*. If *path == 0* then space is allocated via [*malloc*(3)](/malloc/3.md). Probe attribute *name=value* pairs are copied into *attr* if *attr != 0*. *op* may be one of:

- **-1**

  return the path name with no access checks or generation

- **0**

  message emitted information must be generated via [*probe*(1)](/probe/1.md)

- **1**

  no message emitted information must be probed via [*probe*(1)](/probe/1.md)

0 is returned if the information does not exist and cannot be generated.

$1$2pathreplpathreplpathreplpathreplpathreplpathreplpathreplpathrepl does an in-place replacement of the first occurrence of */match/* with */replace/* in *path*.

$1$2pathsetlinkpathsetlinkpathsetlinkpathsetlinkpathsetlinkpathsetlinkpathsetlinkpathsetlink creates a symbolic link *text* in the path *name*. See $1$2pathgetlinkpathgetlinkpathgetlinkpathgetlinkpathgetlinkpathgetlinkpathgetlinkpathgetlink above for weird *universe*(1) interactions hidden by this routine.

$1$2pathshellpathshellpathshellpathshellpathshellpathshellpathshellpathshell returns a pointer to the pathname for the shell for the current process. The $1$2SHELLSHELLSHELLSHELLSHELLSHELLSHELLSHELL environment variable is first consulted, but is rejected under suspicious ownership/setuid conditions of if it seems to point to [*csh*(1)](/csh/1.md)*;* otherwise $1$2confstr(\_CS\_SHELL,...)confstr(\_CS\_SHELL,...)confstr(\_CS\_SHELL,...)confstr(\_CS\_SHELL,...)confstr(\_CS\_SHELL,...)confstr(\_CS\_SHELL,...)confstr(\_CS\_SHELL,...)confstr(\_CS\_SHELL,...) is used. A valid string is always returned.

$1$2pathstatpathstatpathstatpathstatpathstatpathstatpathstatpathstat first tries and if that fails it tries The $1$2statstatstatstatstatstatstatstat or $1$2lstatlstatlstatlstatlstatlstatlstatlstat return value is returned.

$1$2pathtemppathtemppathtemppathtemppathtemppathtemppathtemppathtemp generates in *path* a temporary file path name of the form *dir/pfx\<pid\>.\<suf\>* where the length of *pfx*, if !=0, is limited to 5, the length of *\<pid\>* (the base 64 representation of the current process id) is limited to 3, and  *\<suf\>* (an internally generated suffix that avoid file confilicts) is limited to 3. The generated path name conforms to the classic UNIX 14 char and the DOS $1$28.38.38.38.38.38.38.38.3 limitations. Both  *dir* and *pfx* may be $1$200000000 [*access*(2)](/access/2.md) is used to avoid file conflicts but the generated path name is not created, so you could lose in a race.

## SEE ALSO

3d(1), [access(2)](/access/2.md), [confstr(3)](/confstr/3.md), [fs3d(3)](/fs3d/3.md), [lstat(2)](/lstat/2.md), [stat(2)](/stat/2.md)
