[fs.path.generic]
# 31 Input/output library [[input.output]](./#input.output)
## 31.12 File systems [[filesystems]](filesystems#fs.path.generic)
### 31.12.6 Class path [[fs.class.path]](fs.class.path#fs.path.generic)
#### 31.12.6.2 Generic pathname format [fs.path.generic]
[pathname:](#nt:pathname "31.12.6.2 Generic pathname format [fs.path.generic]")
[*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]")opt [*root-directory*](#nt:root-directory "31.12.6.2 Generic pathname format [fs.path.generic]")opt [*relative-path*](#nt:relative-path "31.12.6.2 Generic pathname format [fs.path.generic]")
[root-name:](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]")
operating system dependent sequences of characters
implementation-defined sequences of characters
[root-directory:](#nt:root-directory "31.12.6.2 Generic pathname format [fs.path.generic]")
[*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")
[relative-path:](#nt:relative-path "31.12.6.2 Generic pathname format [fs.path.generic]")
[*filename*](#nt:filename "31.12.6.2 Generic pathname format [fs.path.generic]")
[*filename*](#nt:filename "31.12.6.2 Generic pathname format [fs.path.generic]") [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") [*relative-path*](#nt:relative-path "31.12.6.2 Generic pathname format [fs.path.generic]")
an empty path
[filename:](#nt:filename "31.12.6.2 Generic pathname format [fs.path.generic]")
non-empty sequence of characters other than [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") characters
[directory-separator:](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")
[*preferred-separator*](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]") [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")opt
[*fallback-separator*](#nt:fallback-separator "31.12.6.2 Generic pathname format [fs.path.generic]") [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")opt
[preferred-separator:](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]")
operating system dependent directory separator character
[fallback-separator:](#nt:fallback-separator "31.12.6.2 Generic pathname format [fs.path.generic]")
/, if [*preferred-separator*](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]") is not /
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13843)
A [*filename*](#def:filename "31.12.6.2 Generic pathname format [fs.path.generic]") is
the name of a file[.](#1.sentence-1)
The [*dot*](#def:dot,filename "31.12.6.2 Generic pathname format [fs.path.generic]") and [*dot-dot*](#def:dot-dot,filename "31.12.6.2 Generic pathname format [fs.path.generic]") filenames,
consisting solely of one and two period characters respectively,
have special meaning[.](#1.sentence-2)
The following characteristics of filenames are operating system dependent:
- [(1.1)](#1.1)
The permitted characters[.](#1.1.sentence-1)
[*Example [1](#example-1)*:
Some operating systems prohibit
the ASCII control characters (0x00 â 0x1F) in filenames[.](#1.1.sentence-2)
â *end example*]
[*Note [1](#note-1)*:
Wider portability can be achieved by limiting [*filename*](#nt:filename "31.12.6.2 Generic pathname format [fs.path.generic]") characters to the POSIX Portable Filename Character Set:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9 . _ -
â *end note*]
- [(1.2)](#1.2)
The maximum permitted length[.](#1.2.sentence-1)
- [(1.3)](#1.3)
Filenames that are not permitted[.](#1.3.sentence-1)
- [(1.4)](#1.4)
Filenames that have special meaning[.](#1.4.sentence-1)
- [(1.5)](#1.5)
Case awareness and sensitivity during path resolution[.](#1.5.sentence-1)
- [(1.6)](#1.6)
Special rules that may apply to file types other than regular
files, such as directories[.](#1.6.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13870)
Except in a [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]"),
multiple successive [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") characters are considered to
be the same as one [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") character[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13875)
The dot filename is treated as a reference to the current directory[.](#3.sentence-1)
The dot-dot filename is treated as a reference to the parent directory[.](#3.sentence-2)
What the dot-dot filename refers to
relative to [*root-directory*](#nt:root-directory "31.12.6.2 Generic pathname format [fs.path.generic]") is implementation-defined[.](#3.sentence-3)
Specific filenames may have special meanings for a particular operating system[.](#3.sentence-4)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13882)
A [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]") identifies the
starting location for pathname resolution ([[fs.class.path]](fs.class.path "31.12.6 Class path"))[.](#4.sentence-1)
If there are no operating system dependent [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]")*s*,
at least one implementation-defined [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]") is required[.](#4.sentence-2)
[*Note [2](#note-2)*:
Many operating systems define a name
beginning with two [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") characters
as a [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]") that identifies
network or other resource locations[.](#4.sentence-3)
Some operating systems
define a single letter followed by a colon
as a drive specifier â a [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]") identifying a specific device such as a disk drive[.](#4.sentence-4)
â *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13898)
If a [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]") is otherwise ambiguous,
the possibility with the longest sequence of characters is chosen[.](#5.sentence-1)
[*Note [3](#note-3)*:
On a POSIX-like operating system, it is impossible to have a[*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]") and a [*relative-path*](#nt:relative-path "31.12.6.2 Generic pathname format [fs.path.generic]") without an intervening [*root-directory*](#nt:root-directory "31.12.6.2 Generic pathname format [fs.path.generic]") element[.](#5.sentence-2)
â *end note*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13907)
[*Normalization*](#def:normalization,path "31.12.6.2 Generic pathname format [fs.path.generic]") of a generic format pathname means:
| [1.](#6.1) | If the path is empty, stop[.](#6.1.sentence-1) |
| --- | --- |
| [2.](#6.2) | Replace each slash character in the [*root-name*](#nt:root-name "31.12.6.2 Generic pathname format [fs.path.generic]") with a [*preferred-separator*](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]")[.](#6.2.sentence-1) |
| [3.](#6.3) | Replace each [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") with a [*preferred-separator*](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]")[.](#6.3.sentence-1)
[*Note [4](#note-4)*:
The generic pathname grammar defines [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") as one or more slashes and [*preferred-separator*](#nt:preferred-separator "31.12.6.2 Generic pathname format [fs.path.generic]")*s*[.](#6.3.sentence-2) â *end note*] |
| [4.](#6.4) | Remove each dot filename and any immediately following [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")[.](#6.4.sentence-1) |
| [5.](#6.5) | As long as any appear, remove a non-dot-dot filename immediately followed by a [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]") and a dot-dot filename, along with any immediately following [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")[.](#6.5.sentence-1) |
| [6.](#6.6) | If there is a [*root-directory*](#nt:root-directory "31.12.6.2 Generic pathname format [fs.path.generic]"), remove all dot-dot filenames and any [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")*s* immediately following them[.](#6.6.sentence-1)
[*Note [5](#note-5)*:
These dot-dot filenames attempt to refer to nonexistent parent directories[.](#6.6.sentence-2) â *end note*] |
| [7.](#6.7) | If the last filename is dot-dot, remove any trailing [*directory-separator*](#nt:directory-separator "31.12.6.2 Generic pathname format [fs.path.generic]")[.](#6.7.sentence-1) |
| [8.](#6.8) | If the path is empty, add a dot[.](#6.8.sentence-1) |
The result of normalization is a path in [*normal form*](#def:normal_form,path "31.12.6.2 Generic pathname format [fs.path.generic]"),
which is said to be [*normalized*](#def:normalized)[.](#6.sentence-2)