Skip to content

Commit

Permalink
update: Chapter2 UNIX 标准及实现
Browse files Browse the repository at this point in the history
  • Loading branch information
MeiK2333 committed Apr 20, 2018
1 parent 5b7506d commit 3b71e81
Show file tree
Hide file tree
Showing 8 changed files with 299 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Chapter-01/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ pid: 90612
% ^Cinterrupt
^C% interrupt
[另开一个控制台]
kill 90612
$ kill 90612
[刚刚的程序]
% Terminated: 15
```
Expand Down
24 changes: 24 additions & 0 deletions Chapter-02/2.5.1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <stdio.h>
#include <limits.h>

int main() {
printf("CHAR_BIT: %d\n", CHAR_BIT);
printf("CHAR_MAX: %d\n", CHAR_MAX);
printf("CHAR_MIN: %d\n", CHAR_MIN);
printf("SCHAR_MAX: %d\n", SCHAR_MAX);
printf("SCHAR_MIN: %d\n", SCHAR_MIN);
printf("INT_MAX: %d\n", INT_MAX);
printf("INT_MIN: %d\n", INT_MIN);
printf("UINT_MAX: %d\n", UINT_MAX);
printf("SHRT_MAX: %d\n", SHRT_MAX);
printf("SHRT_MIN: %d\n", SHRT_MIN);
printf("USHRT_MAX: %d\n", USHRT_MAX);
printf("LONG_MAX: %ld\n", LONG_MAX);
printf("LONG_MIN: %ld\n", LONG_MIN);
printf("ULONG_MAX: %lu\n", ULONG_MAX);
printf("LLONG_MAX: %lld\n", LLONG_MAX);
printf("LLONG_MIN: %lld\n", LLONG_MIN);
printf("ULLONG_MAX: %llu\n", ULLONG_MAX);
printf("MB_LEN_MAX: %d\n", MB_LEN_MAX);
return 0;
}
88 changes: 88 additions & 0 deletions Chapter-02/2.5.4.awk
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/awk -f
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")
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 %%ld\\n\", (long)%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 %%ld\\n\", (long)%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")
}
1 change: 1 addition & 0 deletions Chapter-02/2.5.4.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include
50 changes: 50 additions & 0 deletions Chapter-02/2.5.5.1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "apue.h"
#include <errno.h>
#include <limits.h>

#ifdef PATH_MAX
static long pathmax = PATH_MAX;
#else
static long pathmax = 0;
#endif

static long posix_version = 0;
static long xsi_version = 0;

#define PATH_MAX_GUESS 1024

char *path_alloc(size_t *sizep) {
char *ptr;
size_t size;

if (posix_version == 0)
posix_version = sysconf(_SC_VERSION);

if (xsi_version == 0)
xsi_version = sysconf(_SC_XOPEN_VERSION);

if (pathmax == 0) {
errno = 0;
if ((pathmax = pathconf("/", _PC_PATH_MAX)) < 0) {
if (errno == 0)
pathmax = PATH_MAX_GUESS;
else
err_sys("pathconf error for _PC_PATH_MAX");
} else {
pathmax++;
}
}

if ((posix_version < 200112L) && (xsi_version < 4))
size = pathmax + 1;
else
size = pathmax;

if ((ptr = malloc(size)) == NULL)
err_sys("malloc error for pathname");

if (sizep != NULL)
*sizep = size;

return (ptr);
}
29 changes: 29 additions & 0 deletions Chapter-02/2.5.5.2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "apue.h"
#include <errno.h>
#include <limits.h>

#ifdef OPEN_MAX
static long openmax = OPEN_MAX;
#else
static long openmax = 0;
#endif

#define OPEN_MAX_GUESS 256

long open_max() {
if (openmax == 0) {
errno = 0;
if ((openmax = sysconf(_SC_OPEN_MAX)) < 0) {
if (errno == 0)
openmax = OPEN_MAX_GUESS;
else
err_sys("sysconf error for _SC_OPEN_MAX");
}
}
return (openmax);
}

int main() {
printf("%ld\n", open_max());
return 0;
}
105 changes: 105 additions & 0 deletions Chapter-02/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
## UNIX 标准及实现


### 随书代码


#### 2.5.1.c

```<limits.h>``` 中定义的整型值大小

```shell
$ gcc 2.5.1.c
$ ./a.out
CHAR_BIT: 8
CHAR_MAX: 127
CHAR_MIN: -128
SCHAR_MAX: 127
SCHAR_MIN: -128
INT_MAX: 2147483647
INT_MIN: -2147483648
UINT_MAX: -1
SHRT_MAX: 32767
SHRT_MIN: -32768
USHRT_MAX: 65535
LONG_MAX: 9223372036854775807
LONG_MIN: -9223372036854775808
ULONG_MAX: 18446744073709551615
LLONG_MAX: 9223372036854775807
LLONG_MIN: -9223372036854775808
ULLONG_MAX: 18446744073709551615
MB_LEN_MAX: 6
```


#### 2.5.4.awk && 2.5.4.c

```shell
$ awk -f 2.5.4.awk > conf.c
$ gcc conf.c -lapue
```

[conf.c](conf.c)


#### 2.5.5.2.c

```shell
$ gcc 2.5.5.2.c -lapue
$ ./a.out
10240
```


### 习题


#### 在 2.8 节中提到一些基本系统数据类型可以在多个头文件中定义。例如,在 FreeBSD 8.0 中,size_t 在29 个不同的头文件中都有定义。由于一个程序可能包含这 29 个不同的头文件,但是 ISO C 却不允许对同一个名字进行多次 typedef ,那么如何编写这些头文件呢?

使用宏定义保护。

```
#ifndef _MACHINE_TYPES_H_
#define _MACHINE_TYPES_H_
typedef int _int32_t;
typedef unsigned int _uint32_t;
.........
typedef _uint32_t _size_t;
.........
#enddef
```


#### 检查系统的头文件,列出实现基本系统数据类型所用到的实际数据类型

待续


#### 改写图2-17中的程序,使其在 ```sysconf``````OPEN_MAX``` 限制返回 ```LONG_MAX``` 时,避免进行不必要的处理

```sysconf``` 没有能够准确获得 ```OPEN_MAX``` 限制的时候,可以使用 ```getrlimit``` 来获得。

```C
long open_max()
{
struct rlimit rl;
if (openmax == 0){
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);
}
```
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
## 目录
* [环境配置](apue.3e/)
* [Chapter 1: UNIX 基础知识](Chapter-01/)
* [UNIX 标准及实现](Chapter-02/)

0 comments on commit 3b71e81

Please sign in to comment.