2.1 在2.8節中基本數據類型能夠在多個文件中定義。例如,在FreeBSD 8.0中,size_t在29個不一樣的文件中都有定義,因爲一個程序可能包含這29個不一樣的頭文件,在ISO C 卻不容許對同一個名字進行屢次typedef,那麼如何編寫這些頭文件呢?函數
爲了不屢次包含typedef語句,咱們能夠使用#ifndef標識ui
#ifndef _MACHINE_TYPES_H_ #define _MACHINE_TYPES_H_ typedef int _int32_t; typedef unsigned int _uint32_t; ......... typedef _uint32_t _size_t; ......... #enddef
2.2 檢查系統的頭文件,列出基本系統數據所用到的實際數據類型
一、我所使用的爲Linux系統,發行版爲Fedora,基本數據類型所在頭文件爲/usr/include/sys/types.h
中this
#include <bits/types.h> #ifdef __USE_MISC # ifndef __u_char_defined typedef __u_char u_char; typedef __u_short u_short; typedef __u_int u_int; typedef __u_long u_long; typedef __quad_t quad_t; typedef __u_quad_t u_quad_t; typedef __fsid_t fsid_t; # define __u_char_defined # endif #endif
這裏找到的仍然不是題目所要求的實際數據類型,咱們便從#include <bits/types.h>
中查找code
#include <features.h> #include <bits/wordsize.h> /* Convenience types. */ typedef unsigned char __u_char; typedef unsigned short int __u_short; typedef unsigned int __u_int; typedef unsigned long int __u_long; /* Fixed-size types, underlying types depend on word size and compiler. */ typedef signed char __int8_t; typedef unsigned char __uint8_t; typedef signed short int __int16_t; typedef unsigned short int __uint16_t; typedef signed int __int32_t; typedef unsigned int __uint32_t; #if __WORDSIZE == 64 typedef signed long int __int64_t; typedef unsigned long int __uint64_t; #else __extension__ typedef signed long long int __int64_t; __extension__ typedef unsigned long long int __uint64_t; #endif /* quad_t is also 64 bits. */ #if __WORDSIZE == 64 typedef long int __quad_t; typedef unsigned long int __u_quad_t; #else __extension__ typedef long long int __quad_t; __extension__ typedef unsigned long long int __u_quad_t; #endif
2.3 改寫圖2-17中的程序,使其在sysconf爲OPEN_MAX限制返回LONG_MAX時,避免進行沒必要要的處理。
一、源程序:ip
/************************************************************************* > File Name: openmax.c > Author: King > Mail: arturiapendragon_1@163.com > Created Time: 2017年05月03日 星期三 19時05分42秒 ************************************************************************/ #include "apue.h" #include <errno.h> #include <limits.h> #ifdef OPEN_MAX static long openmax = OPEN_MAX; #else static long openmax = 0; #endif /* * If OPEN_MAX is indeterminate, this might be inadequate */ #define OPEN_MAX_GUESS 256 long open_max(void) { if (openmax ==0){ /* first time through */ errno = 0; if ((openmax = sysconf(_SC_OPEN_MAX)) < 0) { if (errno == 0) openmax = OPEN_MAX_GUESS; /* it's indeterminate */ else err_sys("sysconf error for _SC_OEPN_MAX"); } } return(openmax); } int main(void) { printf("%ld\n",open_max()); }
執行結果爲:ci
king at Fedora in ~/apue/chapter2 $ gcc openmax.c king at Fedora in ~/apue/chapter2 $ ./a.out 1024
由於sysconf函數在Linux可能返回的是LONG,形成程序執行混亂:
所以,修改後的程序:get
/************************************************************************* > File Name: openmax.c > Author: King > Mail: arturiapendragon_1@163.com > Created Time: 2017年05月03日 星期三 19時05分42秒 ************************************************************************/ #include "apue.h" #include <errno.h> #include <limits.h> #include <sys/resource.h> //爲了支持getrlimit函數以及結構體rlimit的使用 #ifdef OPEN_MAX static long openmax = OPEN_MAX; #else static long openmax = 0; #endif /* * If OPEN_MAX is indeterminate, this might be inadequate */ #define OPEN_MAX_GUESS 256 long open_max(void) { struct rlimit rl; if (openmax ==0){ /* first time through */ errno = 0; if ((openmax = sysconf(_SC_OPEN_MAX)) < 0 || openmax==LONG_MAX) { if((openmax=getrlimit(RLIMIT_NOFILE,&rl))<0){ err_sys("can not get file limit\n"); }else if(openmax==RLIM_INFINITY) openmax = OPEN_MAX_GUESS; else openmax=rl.rlim_max; } } return(openmax); } int main(void) { printf("%ld\n",open_max()); }
經過man getrlimit可查看getrlimit函數的實現以及參數:it
The value RLIM_INFINITY denotes no limit on a resource (both in the structure returned by getrlimit() and in the structure passed to setrlimit()). RLIMIT_NOFILE Specifies a value one greater than the maximum file descriptor number that can be opened by this process. Attempts (open(2), pipe(2), dup(2), etc.) to exceed this limit yield the error EMFILE. (Historically, this limit was named RLIMIT_OFILE on BSD.)