The kernel stores pathnames as C strings,
that is,
sequences of non-null bytes terminated by a null byte.
-The kernel has a few general rules that apply to all pathnames:
+There are a few general rules that apply to all pathnames:
.IP \[bu] 3
The last byte in the sequence needs to be a null byte.
.IP \[bu]
.P
Some filesystems or APIs may apply further restrictions,
such as requiring shorter filenames,
-or restricting the allowed characters in a filename.
+or restricting the allowed bytes in a filename.
.P
-User-space programs treat pathnames differently.
-They typically expect pathnames to
-use a consistent character encoding.
-For maximum interoperability,
-programs should use
-.BR nl_langinfo (3)
-to determine the current locale's codeset.
-Pathnames should be encoded and decoded using the current locale's codeset
-in order to help prevent mojibake.
For maximum interoperability,
programs and users should also
limit the characters that they use for their own pathnames to
.UR https://pubs.opengroup.org/\:onlinepubs/\:9799919799/\:basedefs/\:V1_chap03.html#tag_03_265
Portable Filename Character Set
.UE .
-.SH EXAMPLES
-The following program demonstrates
-how to ensure that a pathname uses the proper encoding.
-The program starts with a UTF-32 encoded pathname.
-It then calls
-.BR nl_langinfo (3)
-in order to determine what the current locale's codeset is.
-After that, it uses
-.BR iconv (3)
-to convert the UTF-32-encoded pathname into a locale-codeset-encoded pathname.
-Finally,
-the program uses the locale-codeset-encoded pathname
-to create a file that contains the message \[lq]Hello, world!\[rq].
-.SS Program source
-.\" SRC BEGIN (pathname_encoding_example.c)
-.EX
-#include <err.h>
-#include <iconv.h>
-#include <langinfo.h>
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <uchar.h>
-\&
-#define NELEMS(a) (sizeof(a) / sizeof(a[0]))
-\&
-int
-main(void)
-{
- char *locale_pathname;
- char *in, *out;
- FILE *fp;
- size_t size;
- size_t inbytes, outbytes;
- iconv_t cd;
- char32_t utf32_pathname[] = U"María";
-\&
- if (setlocale(LC_ALL, "") == NULL)
- err(EXIT_FAILURE, "setlocale");
-\&
- size = NELEMS(utf32_pathname) * MB_CUR_MAX;
- locale_pathname = malloc(size);
- if (locale_pathname == NULL)
- err(EXIT_FAILURE, "malloc");
-\&
- cd = iconv_open(nl_langinfo(CODESET), "UTF\-32");
- if (cd == (iconv_t)\-1)
- err(EXIT_FAILURE, "iconv_open");
-\&
- in = (char *) utf32_pathname;
- inbytes = sizeof(utf32_pathname);
- out = locale_pathname;
- outbytes = size;
- if (iconv(cd, &in, &inbytes, &out, &outbytes) == (size_t) \-1)
- err(EXIT_FAILURE, "iconv");
-\&
- if (iconv_close(cd) == \-1)
- err(EXIT_FAILURE, "iconv_close");
-\&
- fp = fopen(locale_pathname, "w");
- if (fp == NULL)
- err(EXIT_FAILURE, "fopen");
-\&
- fputs("Hello, world!\[rs]n", fp);
- if (fclose(fp) == EOF)
- err(EXIT_FAILURE, "fclose");
-\&
- free(locale_pathname);
- exit(EXIT_SUCCESS);
-}
-.EE
-.\" SRC END
.SH SEE ALSO
.BR limits.h (0p),
.BR open (2),
.BR fpathconf (3),
-.BR iconv (3),
-.BR nl_langinfo (3),
.BR path_resolution (7),
.BR mount (8)