[单刷APUE系列]第一章——Unix基础知识[1]
[单刷APUE系列]第一章——Unix基础知识[2]
[单刷APUE系列]第二章——Unix标准及实现
[单刷APUE系列]第三章——文件I/O
[单刷APUE系列]第四章——文件和目录[1]
[单刷APUE系列]第四章——文件和目录[2]
[单刷APUE系列]第五章——标准I/O库
[单刷APUE系列]第六章——系统数据文件和信息
[单刷APUE系列]第七章——进程环境
[单刷APUE系列]第八章——进程控制[1]
[单刷APUE系列]第八章——进程控制[2]
[单刷APUE系列]第九章——进程关系
[单刷APUE系列]第十章——信号[1]express
Unix编程环境和C程序设计语言是如此的广泛,并且标准化工做作了很是多,可是20世纪80年代Unix版本种类的剧增以及他们差异的扩大致使跨平台移植变得愈来愈难,不少用户都呼吁对其进行标准化。
Unix标准化有四个,ISO C、IEEE POSIX、Single Unix Specification、FIPS编程
ISO C标准如今由ISO/IEC的C程序设计语言国际标准工做组维护和开发。ISO C标准的意图是提供C程序的可移植性,使其能适应于大量的操做系统。标准不但定义了C程序设计语言的语法,还规定了必备的标准库。
1989年,C程序设计语言的ANSI标准被采纳为国际标准,也是最先的一次标准化过程,目前被称为C89标准
1999年,ISO C标准被更新,在C89的基础上增长了基本数据类型、关键字和一些系统函数,这也是目前主流的C语言编译器标准,即C99标准,是继C89之后的第二个C语言官方标准。自1999年以来,也有3次技术勘误用于修正ISO C标准,分别于2001年、2004年和2007年,2011年还更新了C11标准,可是很是遗憾的是,标准审批和实际生产仍是有必定时间延迟,因此C11标准目前还并不是主流。
根据ISO C标准,C程序设计语言有24个头文件,目前全部的Unix环境都支持这些头文件。segmentfault
头文件 | 说明 |
---|---|
<assert.h> | 验证程序断言 |
<complex.h> | 复数运算支持 |
<ctype.h> | 字符分类和映射支持 |
<errno.h> | 错误码 |
<fenv.h> | 浮点环境 |
<float.h> | 浮点支持 |
<inttypes.h> | 整型格式转换 |
<iso646.h> | 赋值、关系、一元操做符宏 |
<limits.h> | 实现常量 |
<locale.h> | 本地化支持 |
<math.h> | 数学运算库 |
<setjmp.h> | 非局部goto |
<signal.h> | 信号支持 |
<stdarg.h> | 可变长度参数 |
<stdbool.h> | 布尔类型支持 |
<stddef.h> | 标准定义 |
<stdint.h> | 标准整形 |
<stdio.h> | 标准输入输出 |
<stdlib.h> | 实用函数库 |
<string.h> | 字符串操做 |
<tgmath.h> | 通用类型数学宏 |
<time.h> | 时间日期支持 |
<wchar.h> | 多字节宽字符支持 |
<wctype.h> | 宽字符分类和映射支持 |
IEEE POSIX在原书内指的是IEEE 1003.1操做系统接口标准,该标准的1988版本递交给ISO,最终成为了国际标准POSIX.1,然后IEEE 1003.1工做组对其做出不少修订,包括了著名的pthreads多线程接口。POSIX标准不只包含了ISO C标准函数库,还根据标准要求提供包含了系统调用和库函数的头文件,在这里就不一一列出了。因为POSIX标准只是定义了操做系统接口而非实现,因此并未区分系统调用和库函数。其接口分为两部分,一部分是强制规定必须的部分,而另一部分是非强制要求的可选部分,多线程
Single Unix Specification是POSIX.1标准的一个超集,它定义了一系列附加接口扩展了POSIX.1的功能,Open Group拥有Unix商标,他们定义了SUS标准,一个系统想要称为Unix系统,就必须实现这些接口,而且经过验收性测试,才能获得Unix商标使用权,其中就包括了Mac OS X系统,而Linux虽然实现了这些接口,可是从未提出过申请,因此Linux没有获得过Unix商标。app
FIPS是联邦信息处理标准,实际上并无什么卵用,只是美国政府采购的标准,后来还被撤回了。ide
在作Unix环境开发时,咱们常常遇到跨平台编译的问题,例如:x86_64和x86字长的不一样致使的数据类型长度不一致。不一样Unix版本对接口实现程度不一致。其中最重要的问题就是编译时限制和运行时限制。
编译时限制咱们能够经过在头文件中进行宏定义,而后使用include
指令包含这些头文件。也能够向编译器传入-Dmacroname=value
传入宏定义参数来动态定义这些限制。
运行时限制则要求进程调用库函数来得到系统内置的参数。
Unix系统提供了一下两种限制:函数
编译时限制(头文件)测试
运行时限制:sysconf
、pathconf
和fpathconf
ui
除了Unix系统要求的限制,C程序设计语言的ISO C标准也提供了编译时限制,全部的限制都被放在<limits.h>
头文件中,可是注意,这些限制的具体值其实是由Unix系统规定的而不是C语言规定。
例如<inttypes.h>
头文件,开发者能够利用它提供的常量、宏和派生类型使其代码与显式指定大小的数据项兼容,而无论编译环境如何。众所周知,因为x86_64和x86之间的区别,整形类型所使用的内存空间是不一样的,也就是说,咱们极可能滥用整形致使边界溢出的问题,在实际开发中,推荐的方法是使用定长的整形,而不是int和long,而这个文件也包含了格式化字符串所须要的描述参数的宏定义,极大地方便了开发者的使用。
Unix系统标准规定的全部限制只包含两种:POSIX限制和XSI限制,对于开发者来讲,这两种限制没有任何区别,都是以一样的方式能够获取。
正如前文所言,限制分为编译时限制和运行时限制,运行时限制能够经过下列三个函数获取this
long sysconf(int name); long pathconf(const char *pathname, int name); long fpathconf(int fd, int name);
顺便更正一下原著关于fpathconf函数返回值的错误,原著是log,其实是long。
The pathconf() and fpathconf() functions provides a method for applications to determine the current value of a configurable system limit or option variable associated with a pathname or file descriptor.
很是简单易懂,这两个函数实际上没什么区别,只是用文件描述符来代替文件路径罢了。
_PC_LINK_MAX The maximum file link count. _PC_MAX_CANON The maximum number of bytes in terminal canonical input line. _PC_MAX_INPUT The minimum maximum number of bytes for which space is available in a terminal input queue. _PC_NAME_MAX The maximum number of bytes in a file name. _PC_PATH_MAX The maximum number of bytes in a pathname. _PC_PIPE_BUF The maximum number of bytes which will be written atomically to a pipe. _PC_CHOWN_RESTRICTED Return 1 if appropriate privileges are required for the chown(2) system call, otherwise 0. _PC_NO_TRUNC Return 1 if file names longer than KERN_NAME_MAX are truncated. _PC_VDISABLE Returns the terminal character disabling value. _PC_XATTR_SIZE_BITS Returns the number of bits used to store maximum extended attribute size in bytes. For example, if the maximum attribute size supported by a file system is 128K, the value returned will be 18. However a value 18 can mean that the maximum attribute size can be anywhere from (256KB - 1) to 128KB. As a special case, the resource fork can have much larger size, and some file system specific extended attributes can have smaller and preset size; for example, Finder Info is always 32 bytes.
上面就是pathconf
函数族可能获取的值,具体的能够参考<unistd.h>
_SC_ARG_MAX The maximum bytes of argument to execve(2). _SC_CHILD_MAX The maximum number of simultaneous processes per user id. _SC_CLK_TCK The frequency of the statistics clock in ticks per second. _SC_IOV_MAX The maximum number of elements in the I/O vector used by readv(2), writev(2), recvmsg(2), and sendmsg(2). _SC_NGROUPS_MAX The maximum number of supplemental groups. _SC_NPROCESSORS_CONF The number of processors configured. _SC_NPROCESSORS_ONLN The number of processors currently online. _SC_OPEN_MAX The maximum number of open files per user id. _SC_PAGESIZE The size of a system page in bytes. _SC_STREAM_MAX The minimum maximum number of streams that a process may have open at any one time. _SC_TZNAME_MAX The minimum maximum number of types supported for the name of a timezone. _SC_JOB_CONTROL Return 1 if job control is available on this system, otherwise -1. _SC_SAVED_IDS Returns 1 if saved set-group and saved set-user ID is available, otherwise -1. _SC_VERSION The version of IEEE Std 1003.1 (``POSIX.1'') with which the system attempts to comply. _SC_BC_BASE_MAX The maximum ibase/obase values in the bc(1) utility. _SC_BC_DIM_MAX The maximum array size in the bc(1) utility. _SC_BC_SCALE_MAX The maximum scale value in the bc(1) utility. _SC_BC_STRING_MAX The maximum string length in the bc(1) utility. _SC_COLL_WEIGHTS_MAX The maximum number of weights that can be assigned to any entry of the LC_COLLATE order keyword in the locale definition file. _SC_EXPR_NEST_MAX The maximum number of expressions that can be nested within parenthesis by the expr(1) utility. _SC_LINE_MAX The maximum length in bytes of a text-processing utility's input line. _SC_RE_DUP_MAX The maximum number of repeated occurrences of a regular expression permitted when using interval notation. _SC_2_VERSION The version of IEEE Std 1003.2 (``POSIX.2'') with which the system attempts to comply. _SC_2_C_BIND Return 1 if the system's C-language development facilities support the C-Language Bindings Option, otherwise -1. _SC_2_C_DEV Return 1 if the system supports the C-Language Development Utilities Option, otherwise -1. _SC_2_CHAR_TERM Return 1 if the system supports at least one terminal type capable of all operations described in IEEE Std 1003.2 (``POSIX.2''), otherwise -1. _SC_2_FORT_DEV Return 1 if the system supports the FORTRAN Development Utilities Option, otherwise -1. _SC_2_FORT_RUN Return 1 if the system supports the FORTRAN Runtime Utilities Option, otherwise -1. _SC_2_LOCALEDEF Return 1 if the system supports the creation of locales, otherwise -1. _SC_2_SW_DEV Return 1 if the system supports the Software Development Utilities Option, otherwise -1. _SC_2_UPE Return 1 if the system supports the User Portability Utilities Option, otherwise -1.
经常使用的就是这些,另外可能还有一些非标准参数,这里就不在叙述。想必你们也看出来了,以_SC_
开头的就是sysconf
,以_PC_
开头的就是pathconf
关于原著中不肯定的运行时限制,原文写的很是啰嗦,实际上没有什么卵用,由于虽然POSIX规定了不少限制,可是不少都没有被实际实现,因此碰到这种状况,只能使用条件编译、循环尝试、错误码判断等hack手段来搞定。
因为Unix版本众多,各自的实现也不一样,几乎每一个Unix实现都自带了自定义的功能选项,为了保证只使用POSIX标准规范定义,咱们可使用_POSIX_C_SOURCE
宏定义和_XOPEN_SOURCE
宏定义,这也被称为功能测试宏。咱们能够给C编译器传入-Dmacroname=value
的形式,也能够在头文件中设置宏定义。
为了保证跨平台开发使用一样的类型,Unix标准要求系统提供基本数据类型以供开发者使用,这些数据类型都已_t
结尾,根据系统字长和平台的不一样,他们具体的实现空间也不一样,可是至少保证了不会由于系统不一样而去关注具体实现细节。