• 沒有找到結果。

Exercises

Chapter 2. UNIX Standardization and Implementations

2.5. Limits

2.5.4. sysconf , pathconf , and fpathconf Functions

We've listed various minimum values that an implementation must support, but how do we find out the limits that a particular system actually supports? As we mentioned earlier, some of these limits might be available at compile time; others must be determined at runtime. We've also mentioned that some don't change in a given system, whereas others can change because they are associated with a file or directory. The runtime limits are obtained by calling one of the following three functions.

#include <unistd.h>

long sysconf(int name);

long pathconf(const char *pathname, int name);

long fpathconf(int filedes, int name);

All three return: corresponding value if OK, 1 on error (see later)

The difference between the last two functions is that one takes a pathname as its argument and the other takes a file descriptor argument.

Figure 2.10 lists the name arguments that sysconf uses to identify system limits. Constants beginning with _SC_ are used as arguments to sysconf to identify the runtime limit. Figure 2.11 lists the name arguments that are used by pathconf and fpathconf to identify system limits.

Constants beginning with _PC_ are used as arguments to pathconf and fpathconf to identify the runtime limit.

Figure 2.10. Limits and name arguments to

sysconf

Name of limit Description name argument

ARG_MAX maximum length, in bytes, of arguments to the exec functions _SC_ARG_MAX

ATEXIT_MAX maximum number of functions that can be registered with the atexit function

_SC_ATEXIT_MAX

CHILD_MAX maximum number of processes per real user ID _SC_CHILD_MAX

clock ticks/second number of clock ticks per second _SC_CLK_TCK

COLL_WEIGHTS_MAX maximum number of weights that can be assigned to an entry of the LC_COLLATE order keyword in the locale definition file

_SC_COLL_WEIGHTS_MAX

HOST_NAME_MAX maximum length of a host name as returned by gethostname _SC_HOST_NAME_MAX

IOV_MAX maximum number of iovec structures that can be used with readv or writev

_SC_IOV_MAX

LINE_MAX maximum length of a utility's input line _SC_LINE_MAX

LOGIN_NAME_MAX maximum length of a login name _SC_LOGIN_NAME_MAX

NGROUPS_MAX maximum number of simultaneous supplementary process group IDs per process

_SC_NGROUPS_MAX

OPEN_MAX maximum number of open files per process _SC_OPEN_MAX

PAGESIZE system memory page size, in bytes _SC_PAGESIZE

PAGE_SIZE system memory page size, in bytes _SC_PAGE_SIZE

RE_DUP_MAX number of repeated occurrences of a basic regular expression permitted by the regexec and regcomp functions when using the interval notation \{m,n\}

_SC_RE_DUP_MAX

STREAM_MAX maximum number of standard I/O streams per process at any given time; if defined, it must have the same value as FOPEN_MAX

_SC_STREAM_MAX

SYMLOOP_MAX number of symbolic links that can be traversed during pathname resolution

_SC_SYMLOOP_MAX

TTY_NAME_MAX length of a terminal device name, including the terminating null _SC_TTY_NAME_MAX

TZNAME_MAX maximum number of bytes for the name of a time zone _SC_TZNAME_MAX

This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks

.

Figure 2.11. Limits and name arguments to

pathconf

and

fpathconf

Name of limit Description name argument

FILESIZEBITS minimum number of bits needed to represent, as a signed integer value, the maximum size of a regular file allowed in the specified directory

_PC_FILESIZEBITS

LINK_MAX maximum value of a file's link count _PC_LINK_MAX

MAX_CANON maximum number of bytes on a terminal's canonical input queue _PC_MAX_CANON

MAX_INPUT number of bytes for which space is available on terminal's input queue

_PC_MAX_INPUT

NAME_MAX maximum number of bytes in a filename (does not include a null at end)

_PC_NAME_MAX

PATH_MAX maximum number of bytes in a relative pathname, including the terminating null

_PC_PATH_MAX

PIPE_BUF maximum number of bytes that can be written atomically to a pipe

_PC_PIPE_BUF

SYMLINK_MAX number of bytes in a symbolic link _PC_SYMLINK_MAX

We need to look in more detail at the different return values from these three functions.

All three functions return 1 and set errno to EINVAL if the name isn't one of the appropriate constants. The third column in Figures 2.10 and 2.11 lists the limit constants we'll deal with throughout the rest of this book.

1.

Some names can return either the value of the variable (a return value 0) or an indication that the value is indeterminate.

An indeterminate value is indicated by returning 1 and not changing the value of errno. 2.

The value returned for _SC_CLK_TCK is the number of clock ticks per second, for use with the return values from the times function (Section 8.16).

3.

There are some restrictions for the pathname argument to pathconf and the filedes argument to fpathconf. If any of these restrictions isn't met, the results are undefined.

The referenced file for _PC_MAX_CANON and _PC_MAX_INPUT must be a terminal file.

1.

The referenced file for _PC_LINK_MAX can be either a file or a directory. If the referenced file is a directory, the return value applies to the directory itself, not to the filename entries within the directory.

2.

The referenced file for _PC_FILESIZEBITS and _PC_NAME_MAX must be a directory. The return value applies to filenames within the directory.

3.

The referenced file for _PC_PATH_MAX must be a directory. The value returned is the maximum length of a relative pathname when the specified directory is the working directory. (Unfortunately, this isn't the real maximum length of an absolute pathname, which is what we want to know. We'll return to this problem in Section 2.5.5.)

4.

The referenced file for _PC_PIPE_BUF must be a pipe, FIFO, or directory. In the first two cases (pipe or FIFO) the return value is the limit for the referenced pipe or FIFO. For the other case (a directory) the return value is the limit for any FIFO created in that directory.

5.

The referenced file for _PC_SYMLINK_MAX must be a directory. The value returned is the maximum length of the string that a symbolic link in that directory can contain.

6.

Example

The awk(1) program shown in Figure 2.12 builds a C program that prints the value of each pathconf and sysconf symbol.

The awk program reads two input filespathconf.sym and sysconf.symthat contain lists of the limit name and symbol, separated by tabs. All symbols are not defined on every platform, so the awk program surrounds each call to pathconf and sysconf with the necessary #ifdef statements.

For example, the awk program transforms a line in the input file that looks like

NAME_MAX _PC_NAME_MAX

into the following C code:

#ifdef NAME_MAX

printf("NAME_MAX is defined to be %d\n", NAME_MAX+0);

#else

printf("no symbol for NAME_MAX\n");

#endif

#ifdef _PC_NAME_MAX

pr_pathconf("NAME_MAX =", argv[1], _PC_NAME_MAX);

#else

printf("no symbol for _PC_NAME_MAX\n");

#endif

The program in Figure 2.13, generated by the awk program, prints all these limits, handling the case in which a limit is not defined.

Figure 2.14 summarizes results from Figure 2.13 for the four systems we discuss in this book. The entry "no symbol" means that the system doesn't provide a corresponding _SC or _PC symbol to query the value of the constant. Thus, the limit is undefined in this case. In contrast, the entry "unsupported" means that the symbol is defined by the system but unrecognized by the sysconf or pathconf functions.

The entry "no limit" means that the system defines no limit for the constant, but this doesn't mean that the limit is infinite.

We'll see in Section 4.14 that UFS is the SVR4 implementation of the Berkeley fast file system. PCFS is the MS-DOS FAT file system implementation for Solaris.

Figure 2.12. Build C program to print all supported configuration limits

BEGIN {

printf("#include \"apue.h\"\n") printf("#include <errno.h>\n") printf("#include <limits.h>\n") printf("\n")

printf("static void pr_sysconf(char *, int);\n") printf("static void pr_pathconf(char *, char *, int);\n") printf("\n")

printf("int\n")

printf("main(int argc, char *argv[])\n") printf("{\n")

This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks

.

printf("\tif (argc != 2)\n")

printf("\t\terr_quit(\"usage: a.out <dirname>\");\n\n") FS="\t+"

while (getline <"sysconf.sym" > 0) { printf("#ifdef %s\n", $1)

printf("\tprintf(\"%s defined to be %%d\\n\", %s+0);\n", $1, $1) printf("#else\n")

printf("\tprintf(\"no symbol for %s\\n\");\n", $1) printf("#endif\n")

printf("#ifdef %s\n", $2)

printf("\tpr_sysconf(\"%s =\", %s);\n", $1, $2) printf("#else\n")

printf("\tprintf(\"no symbol for %s\\n\");\n", $2) printf("#endif\n")

}

close("sysconf.sym")

while (getline <"pathconf.sym" > 0) { printf("#ifdef %s\n", $1)

printf("\tprintf(\"%s defined to be %%d\\n\", %s+0);\n", $1, $1) printf("#else\n")

printf("\tprintf(\"no symbol for %s\\n\");\n", $1) printf("#endif\n")

printf("#ifdef %s\n", $2)

printf("\tpr_pathconf(\"%s =\", argv[1], %s);\n", $1, $2) printf("#else\n")

printf("\tprintf(\"no symbol for %s\\n\");\n", $2) printf("#endif\n")

}

close("pathconf.sym") exit

} END {

printf("\texit(0);\n") printf("}\n\n") printf("static void\n")

printf("pr_sysconf(char *mesg, int name)\n") printf("{\n")

printf("\tlong val;\n\n") printf("\tfputs(mesg, stdout);\n") printf("\terrno = 0;\n")

printf("\tif ((val = sysconf(name)) < 0) {\n") printf("\t\tif (errno != 0) {\n")

printf("\t\t\tif (errno == EINVAL)\n")

printf("\t\t\t\tfputs(\" (not supported)\\n\", stdout);\n") printf("\t\t\telse\n")

printf("\t\t\t\terr_sys(\"sysconf error\");\n") printf("\t\t} else {\n")

printf("\t\t\tfputs(\" (no limit)\\n\", stdout);\n") printf("\t\t}\n")

printf("\t} else {\n")

printf("\t\tprintf(\" %%ld\\n\", val);\n") printf("\t}\n")

printf("}\n\n") printf("static void\n")

printf("pr_pathconf(char *mesg, char *path, int name)\n") printf("{\n")

printf("\tlong val;\n") printf("\n")

printf("\tfputs(mesg, stdout);\n") printf("\terrno = 0;\n")

printf("\tif ((val = pathconf(path, name)) < 0) {\n") printf("\t\tif (errno != 0) {\n")

printf("\t\t\tif (errno == EINVAL)\n")

printf("\t\t\t\tfputs(\" (not supported)\\n\", stdout);\n") printf("\t\t\telse\n")

printf("\t\t\t\terr_sys(\"pathconf error, path = %%s\", path);\n") printf("\t\t} else {\n")

printf("\t\t\tfputs(\" (no limit)\\n\", stdout);\n") printf("\t\t}\n")

printf("\t} else {\n")

printf("\t\tprintf(\" %%ld\\n\", val);\n") printf("\t}\n")

printf("}\n") }

Figure 2.13. Print all possible

sysconf

and

pathconf

values

#include "apue.h"

#include <errno.h>

#include <limits.h>

static void pr_sysconf(char *, int);

static void pr_pathconf(char *, char *, int);

int

main(int argc, char *argv[]) {

if (argc != 2)

err_quit("usage: a.out <dirname>");

#ifdef ARG_MAX

printf("ARG_MAX defined to be %d\n", ARG_MAX+0);

#else

printf("no symbol for ARG_MAX\n");

#endif

#ifdef _SC_ARG_MAX

pr_sysconf("ARG_MAX =", _SC_ARG_MAX);

#else

printf("no symbol for _SC_ARG_MAX\n");

#endif

/* similar processing for all the rest of the sysconf symbols... */

#ifdef MAX_CANON

printf("MAX_CANON defined to be %d\n", MAX_CANON+0);

#else

printf("no symbol for MAX_CANON\n");

#endif

#ifdef _PC_MAX_CANON

pr_pathconf("MAX_CANON =", argv[1], _PC_MAX_CANON);

#else

printf("no symbol for _PC_MAX_CANON\n");

#endif

/* similar processing for all the rest of the pathconf symbols... */

exit(0);

} static void

pr_sysconf(char *mesg, int name) {

long val;

fputs(mesg, stdout);

errno = 0;

if ((val = sysconf(name)) < 0) { if (errno != 0) {

This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks

.

if (errno == EINVAL)

fputs(" (not supported)\n", stdout);

else

err_sys("sysconf error");

} else {

fputs(" (no limit)\n", stdout);

} } else {

printf(" %ld\n", val);

} }

static void

pr_pathconf(char *mesg, char *path, int name) {

long val;

fputs(mesg, stdout);

errno = 0;

if ((val = pathconf(path, name)) < 0) { if (errno != 0) {

if (errno == EINVAL)

fputs(" (not supported)\n", stdout);

else

err_sys("pathconf error, path = %s", path);

} else {

fputs(" (no limit)\n", stdout);

} } else {

printf(" %ld\n", val);

} }

Figure 2.14. Examples of configuration limits

Limit FreeBSD 5.2.1 Linux 2.4.22 Mac OS X 10.3

Solaris 9

UFS file system

PCFS file system

ARG_MAX 65,536 131,072 262,144 1,048,320 1,048,320

ATEXIT_MAX 32 2,147,483,647 no symbol no limit no limit

CHARCLASS_NAME_MAX no symbol 2,048 no symbol 14 14

CHILD_MAX 867 999 100 7,877 7,877

clock ticks/second 128 100 100 100 100

COLL_WEIGHTS_MAX 0 255 2 10 10

FILESIZEBITS unsupported 64 no symbol 41 unsupported

HOST_NAME_MAX 255 unsupported no symbol no symbol no symbol

IOV_MAX 1,024 no limit no symbol 16 16

LINE_MAX 2,048 2,048 2,048 2,048 2,048

LINK_MAX 32,767 32,000 32,767 32,767 1

LOGIN_NAME_MAX 17 256 no symbol 9 9

MAX_CANON 255 255 255 256 256

MAX_INPUT 255 255 255 512 512

NAME_MAX 255 255 765 255 8

NGROUPS_MAX 16 32 16 16 16

OPEN_MAX 1,735 1,024 256 256 256

PAGESIZE 4,096 4,096 4,096 8,192 8,192

PAGE_SIZE 4,096 4,096 no symbol 8,192 8,192

PATH_MAX 1,024 4,096 1,024 1,024 1,024

PIPE_BUF 512 4,096 512 5,120 5,120

RE_DUP_MAX 255 32,767 255 255 255

STREAM_MAX 1,735 16 20 256 256

SYMLINK_MAX unsupported no limit no symbol no symbol no symbol

SYMLOOP_MAX 32 no limit no symbol no symbol no symbol

TTY_NAME_MAX 255 32 no symbol 128 128

TZNAME_MAX 255 6 255 no limit no limit

This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks

.