---
name: "abs2rel"
section: "3"
platform: "freebsd"
package: "base"
version: "16.0-CURRENT-20261027-61c70dc16a79"
release: "FreeBSD 16.0-CURRENT (2026-10-27)"
platforms: ["freebsd"]
url: "https://new.carta.tech/abs2rel"
---

# abs2rel(3)

make a relative path name from an absolute path name

## NAME

**abs2rel** – make a relative path name from an absolute path name

## SYNOPSIS

library “libpathconv”

*char \**\

**abs2rel**(*const char \*path*, *const char \*base*, *char \*result*, *size\_t size*);

## DESCRIPTION

The **abs2rel**() function makes a relative path name from an absolute path name *path* based on a directory *base* and copies the resulting path name into the memory referenced by *result*. The *result* argument must refer to a buffer capable of storing at least *size* characters.

The resulting path name may include symbolic links. The **abs2rel**() function doesn't check whether or not any path exists.

## RETURN VALUES

The **abs2rel**() function returns relative path name on success. If an error occurs, it returns NULL.

## EXAMPLES

    char result\[MAXPATHLEN\];\
     char \*path = abs2rel("/usr/src/sys", "/usr/local/lib", result, MAXPATHLEN);

yields:

    path == "../../src/sys"

Similarly,

    path1 = abs2rel("/usr/src/sys", "/usr", result, MAXPATHLEN);\
     path2 = abs2rel("/usr/src/sys", "/usr/src/sys", result, MAXPATHLEN);

yields:

    path1 == "src/sys"\
     path2 == "."

## ERRORS

The **abs2rel**() function may fail and set the external variable *errno* to indicate the error.

- \[EINVAL\]

  The *base* directory isn't an absolute path name or the *size* argument is zero.

- \[ERANGE\]

  The *size* argument is greater than zero but smaller than the length of the pathname plus 1.

## SEE ALSO

[rel2abs(3)](/rel2abs/3.md)

## AUTHORS

Shigio Yamaguchi ⟨*shigio@tamacom.com*⟩

## BUGS

If the *base* directory includes symbolic links, the **abs2rel**() function produces the wrong path. For example, if '/sys' is a symbolic link to '/usr/src/sys',

    char \*path = abs2rel("/usr/local/lib", "/sys", result, MAXPATHLEN);

yields:

    path == "../usr/local/lib"         /\* It's wrong!! \*/

You should convert the base directory into a real path in advance.

    path = abs2rel("/sys/kern", realpath("/sys", resolvedname), result, MAXPATHLEN);

yields:

    path == "../../../sys/kern"        /\* It's correct but ... \*/

That is correct, but a little redundant. If you wish get the simple answer 'kern', do the following.

    path = abs2rel(realpath("/sys/kern", r1), realpath("/sys", r2),\
 								result, MAXPATHLEN);

The **realpath**() function assures correct result, but don't forget that **realpath**() requires that all but the last component of the path exist.
