├── APUE ├── 1_10.c ├── 1_3.c ├── 1_4.c ├── 1_5.c ├── 1_6.c ├── 1_7.c ├── 1_8.c ├── 1_9.c ├── 2_16.c ├── 2_17.c ├── 3_1.c ├── 3_11.c ├── 3_12_1.c ├── 3_12_2.c ├── 3_2.c ├── 3_5.c ├── 4_12.c ├── 4_16.c ├── 4_21.c ├── 4_22.c ├── 4_23.c ├── 4_24.c ├── 4_25.c ├── 4_3.c ├── 4_8.c ├── 4_9.c ├── 5_11.c ├── 5_12.c ├── 5_13.c ├── 5_15.c ├── 5_4.c ├── 5_5.c ├── 6_11.c ├── 6_2.c ├── 7_1.c ├── 7_13.c ├── 7_16.c ├── 7_3.c ├── 7_4.c ├── 8_1.c ├── 8_12.c ├── 8_3.c ├── 8_5.c ├── 8_6.c ├── 8_8.c └── FuncPointer.c ├── Advanced Programming in the UNIX Environment 3rd Edition.pdf ├── Makefile ├── README.md ├── UNIX环境高级编程(中文第三版).pdf ├── src.3e.tar.gz └── unix高级编程apue习题答案.pdf /APUE/1_10.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | static void sig_int(int); 5 | 6 | int main(void){ 7 | char buf[MAXLINE]; 8 | pid_t pid; 9 | int status; 10 | 11 | if (signal(SIGINT,sig_int) == SIG_ERR){ 12 | err_sys("signal error"); 13 | } 14 | 15 | printf("%% "); 16 | while (fgets(buf, MAXLINE, stdin) != NULL){ 17 | if (buf[strlen(buf)-1] == '\n'){ 18 | buf[strlen(buf)-1] = 0; 19 | } 20 | 21 | if ((pid = fork()) < 0){ 22 | err_sys("fork error"); 23 | } else if (pid == 0){ 24 | execlp(buf, buf, (char*)0); 25 | err_ret("couldn't execute : %s", buf); 26 | exit(127); 27 | } 28 | 29 | if ((pid = waitpid(pid, &status, 0)) < 0){ 30 | err_sys("waitpid error"); 31 | } 32 | 33 | printf("%% "); 34 | } 35 | 36 | exit(0); 37 | } 38 | 39 | void sig_int(int signo){ 40 | printf("interrupt \n%% "); 41 | } -------------------------------------------------------------------------------- /APUE/1_3.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]){ 5 | DIR *dp; 6 | struct dirent *dirp; 7 | 8 | if (argc != 2){ 9 | err_quit("usage : ls directory_name"); 10 | } 11 | 12 | if ((dp = opendir(argv[1])) == NULL){ 13 | err_sys("Can't open %s", argv[1]); 14 | } 15 | 16 | while ((dirp = readdir(dp)) != NULL){ 17 | printf("%s\n", dirp->d_name); 18 | } 19 | 20 | closedir(dp); 21 | exit(0); 22 | } -------------------------------------------------------------------------------- /APUE/1_4.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | #define BUFFSIZE 4096 4 | 5 | int main(void){ 6 | int n = 0; 7 | char buf[BUFFSIZE]; 8 | 9 | while((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0){ 10 | if (write(STDOUT_FILENO, buf, n) != n){ 11 | err_sys("write error"); 12 | } 13 | } 14 | 15 | if (n < 0){ 16 | err_sys("read error"); 17 | } 18 | 19 | exit(0); 20 | } -------------------------------------------------------------------------------- /APUE/1_5.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | int main(void){ 4 | int c; 5 | while ((c = getc(stdin)) != EOF){ 6 | if (putc(c, stdout) == EOF){ 7 | err_sys("output error"); 8 | } 9 | } 10 | 11 | if (ferror(stdin)){ 12 | err_sys("input error"); 13 | } 14 | 15 | exit(0); 16 | } -------------------------------------------------------------------------------- /APUE/1_6.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | int main(void){ 4 | printf("hello world from process ID %ld\n", (long)getpid()); 5 | exit(0); 6 | } -------------------------------------------------------------------------------- /APUE/1_7.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | int main(void){ 5 | char buf[MAXLINE]; 6 | pid_t pid; 7 | int status; 8 | 9 | printf("%% "); 10 | while (fgets(buf, MAXLINE, stdin) != NULL){ 11 | if (buf[strlen(buf)-1] == '\n'){ 12 | buf[strlen(buf)-1] = 0; 13 | } 14 | 15 | if ((pid = fork()) < 0){ 16 | err_sys("fork error"); 17 | } else if (pid == 0){ 18 | execlp(buf, buf, (char*)0); 19 | err_ret("couldn't execute : %s", buf); 20 | exit(127); 21 | } 22 | 23 | if ((pid = waitpid(pid, &status, 0)) < 0){ 24 | err_sys("waitpid error"); 25 | } 26 | 27 | printf("%% "); 28 | } 29 | 30 | exit(0); 31 | } -------------------------------------------------------------------------------- /APUE/1_8.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | int main(int argc, char* argv[]){ 5 | fprintf(stderr, "EACCES : %s\n", strerror(EACCES)); 6 | errno = ENOENT; 7 | perror(argv[0]); 8 | exit(0); 9 | } -------------------------------------------------------------------------------- /APUE/1_9.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | int main(void){ 4 | printf("uid = %d, gid = %d\n", getuid(), getgid()); 5 | exit(0); 6 | } -------------------------------------------------------------------------------- /APUE/2_16.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | #ifdef PATH_MAX 5 | static long pathmax = PATH_MAX; 6 | #else 7 | static long pathmax = 0; 8 | #endif 9 | 10 | static long posix_version = 0; 11 | static long xsi_version = 0; 12 | 13 | #define PATH_MAX_GUESS 1024 14 | 15 | char* path_alloc(size_t *sizep){ 16 | char *ptr; 17 | size_t size; 18 | 19 | if (posix_version == 0){ 20 | posix_version = sysconf(_SC_VERSION); 21 | } 22 | 23 | if (xsi_version == 0){ 24 | xsi_version = sysconf(_SC_XOPEN_VERSION); 25 | } 26 | 27 | if (pathmax == 0){ 28 | errno = 0; 29 | if ((pathmax = pathconf("/", _PC_PATH_MAX)) < 0){ 30 | if (errno == 0){ 31 | pathmax = PATH_MAX_GUESS; 32 | } 33 | else{ 34 | err_sys("pathconf error for _PC_PATH_MAX"); 35 | } 36 | } 37 | else{ 38 | pathmax++; 39 | } 40 | } 41 | 42 | if ((posix_version < 200112L) && (xsi_version < 4)){ 43 | size = pathmax + 1; 44 | } 45 | else{ 46 | size = pathmax; 47 | } 48 | 49 | if ((ptr = malloc(size)) == NULL){ 50 | err_sys("malloc error for pathname"); 51 | } 52 | 53 | if (sizep != NULL){ 54 | *sizep = size; 55 | } 56 | 57 | return(ptr); 58 | } -------------------------------------------------------------------------------- /APUE/2_17.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | #include 4 | 5 | #ifdef OPEN_MAX 6 | static long openmax = OPEN_MAX; 7 | #else 8 | static long openmax = 0; 9 | #endif 10 | 11 | #define OPEN_MAX_GUESS 256 12 | 13 | long open_max(void){ 14 | if (openmax == 0){ 15 | errno = 0; 16 | if ((openmax = sysconf(_SC_OPEN_MAX)) < 0){ 17 | if (errno == 0){ 18 | openmax = OPEN_MAX_GUESS; 19 | } 20 | else{ 21 | err_sys("sysconf error for _SC_OPEN_MAX"); 22 | } 23 | } 24 | } 25 | 26 | return(openmax); 27 | } -------------------------------------------------------------------------------- /APUE/3_1.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | int main(void){ 4 | if (lseek(STDIN_FILENO, 0, SEEK_CUR) == -1){ 5 | printf("cannot seek\n"); 6 | } 7 | else{ 8 | printf("seek ok\n"); 9 | } 10 | 11 | exit(0); 12 | } -------------------------------------------------------------------------------- /APUE/3_11.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | int main(int argc, char* argv[]){ 5 | int val; 6 | 7 | if (argc != 2){ 8 | err_quit("usage : main "); 9 | } 10 | 11 | if ((val = fcntl(atoi(argv[1]), F_GETFL, 0)) < 0){ 12 | err_sys("fcntl error for fd %d", atoi(argv[1])); 13 | } 14 | 15 | switch (val & O_ACCMODE){ 16 | case O_RDONLY: 17 | printf("read only"); 18 | break; 19 | 20 | case O_WRONLY: 21 | printf("write only"); 22 | break; 23 | 24 | case O_RDWR: 25 | printf("read write"); 26 | break; 27 | 28 | default: 29 | err_dump("unknown access mode"); 30 | } 31 | 32 | if (val & O_APPEND){ 33 | printf(", append"); 34 | } 35 | 36 | if (val & O_NONBLOCK){ 37 | printf(", nonblocking"); 38 | } 39 | 40 | if (val & O_SYNC){ 41 | printf(", synchronous writes"); 42 | } 43 | 44 | # if !defined(_POSIX_C_SOURCE) && defined(O_FSYNC) && (O_FSYNC != O_SYNC) 45 | if (val & O_FSYNC){ 46 | printf(", synchronous writes"); 47 | } 48 | #endif 49 | 50 | putchar('\n'); 51 | exit(0); 52 | } -------------------------------------------------------------------------------- /APUE/3_12_1.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | void set_fl(int fd, int flags){ 5 | int val; 6 | 7 | if ((val = fcntl(fd, F_GETFL, 0)) < 0){ 8 | err_sys("fcntl F_GETFL error"); 9 | } 10 | 11 | val |= flags; 12 | 13 | if (fcntl(fd, F_SETFL, val) < 0){ 14 | err_sys("fcntl F_SETFL error"); 15 | } 16 | } -------------------------------------------------------------------------------- /APUE/3_12_2.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | void set_fl(int fd, int flags){ 5 | int val; 6 | 7 | if ((val = fcntl(fd, F_GETFL, 0)) < 0){ 8 | err_sys("fcntl F_GETFL error"); 9 | } 10 | 11 | val &= ~flags; 12 | 13 | if (fcntl(fd, F_SETFL, val) < 0){ 14 | err_sys("fcntl F_SETFL error"); 15 | } 16 | } -------------------------------------------------------------------------------- /APUE/3_2.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | char buf1[] = "abcdefghij"; 5 | char buf2[] = "ABCDEFGHIJ"; 6 | 7 | int main(void){ 8 | int fd; 9 | 10 | if ((fd = creat("file.hole", FILE_MODE)) < 0){ 11 | err_sys("creat error"); 12 | } 13 | 14 | if (write(fd, buf1, 10) != 10){ 15 | err_sys("buf1 write error"); 16 | } 17 | 18 | if (lseek(fd, 16834, SEEK_SET) == -1){ 19 | err_sys("lseek error"); 20 | } 21 | 22 | if (write(fd, buf2, 10) != 10){ 23 | err_sys("buf2 write error"); 24 | } 25 | 26 | exit(0); 27 | } -------------------------------------------------------------------------------- /APUE/3_5.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | #define BUFFSIZE 4096 4 | 5 | int main(void){ 6 | int n; 7 | char buf[BUFFSIZE]; 8 | 9 | while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0){ 10 | if (write(STDOUT_FILENO, buf, n) != n){ 11 | err_sys("write error"); 12 | } 13 | } 14 | 15 | if (n < 0){ 16 | err_sys("read error"); 17 | } 18 | 19 | exit(0); 20 | } -------------------------------------------------------------------------------- /APUE/4_12.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | int main(void){ 4 | struct stat statbuf; 5 | if (stat("foo", &statbuf) < 0){ 6 | err_sys("stat error for foo"); 7 | } 8 | 9 | if (chmod("foo", (statbuf.st_mode & ~S_IXGRP) | S_ISGID) < 0){ 10 | err_sys("chmod error for foo"); 11 | } 12 | 13 | if (chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0){ 14 | err_sys("chmod error for bar"); 15 | } 16 | 17 | exit(0); 18 | } -------------------------------------------------------------------------------- /APUE/4_16.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | int main(void){ 5 | if (open("tempfile", O_RDWR) < 0){ 6 | err_sys("open error"); 7 | } 8 | 9 | if (unlink("tempfile") < 0){ 10 | err_sys("unlink error"); 11 | } 12 | 13 | printf("file unlinked\n"); 14 | sleep(15); 15 | printf("done\n"); 16 | 17 | exit(0); 18 | } -------------------------------------------------------------------------------- /APUE/4_21.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | int main(int argc, char* argv[]){ 5 | int i, fd; 6 | struct stat statbuf; 7 | struct timespec times[2]; 8 | 9 | for (i = 1; i < argc; i++){ 10 | if (stat(argv[1], &statbuf) < 0){ 11 | err_ret("%s : stat error", argv[1]); 12 | continue; 13 | } 14 | 15 | if ((fd = open(argv[1], O_RDWR | O_TRUNC)) < 0){ 16 | err_ret("%s : open error", argv[1]); 17 | continue; 18 | } 19 | 20 | times[0] = statbuf.st_atim; 21 | times[1] = statbuf.st_mtim; 22 | 23 | if (funtime(fd, times) < 0){ 24 | err_ret("%s : funtime error", argv[1]); 25 | } 26 | 27 | exit(0); 28 | } 29 | } -------------------------------------------------------------------------------- /APUE/4_22.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | #include 4 | #include "2_16.c" 5 | 6 | typedef int Myfunc(const char *, const struct stat *, int); 7 | 8 | static Myfunc myfunc; 9 | static int myftw(char *, Myfunc *); 10 | static int dopath(Myfunc *); 11 | static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot; 12 | 13 | int main(int argc, char *argv[]){ 14 | int ret; 15 | if (argc != 2){ 16 | err_quit("usage : ftw "); 17 | } 18 | 19 | ret = myftw(argv[1], myfunc); 20 | ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock; 21 | if (ntot == 0){ 22 | ntot = 1; 23 | } 24 | 25 | printf("regular files = %7ld, %5.2f %%\n", nreg, nreg + 100.0 / ntot); 26 | printf("directories = %7ld, %5.2f %%\n", ndir, ndir + 100.0 / ntot); 27 | printf("block special = %7ld, %5.2f %%\n", nblk, nblk + 100.0 / ntot); 28 | printf("char special = %7ld, %5.2f %%\n", nchr, nchr + 100.0 / ntot); 29 | printf("FIFOs = %7ld, %5.2f %%\n", nfifo, nfifo + 100.0 / ntot); 30 | printf("symbolic links = %7ld, %5.2f %%\n", nslink, nslink + 100.0 / ntot); 31 | printf("sockets = %7ld, %5.2f %%\n", nsock, nsock + 100.0 / ntot); 32 | 33 | exit(ret); 34 | } 35 | 36 | #define FTW_F 1 37 | #define FTW_D 2 38 | #define FTW_DNR 3 39 | #define FTW_NS 4 40 | 41 | static char *fullpath; 42 | static size_t pathlen; 43 | 44 | static int myftw(char *pathname, Myfunc *func){ 45 | fullpath = path_alloc(&pathlen); 46 | 47 | if (pathlen <= strlen(pathname)){ 48 | pathlen = strlen(pathname) * 2; 49 | if ((fullpath = realloc(fullpath, pathlen)) == NULL){ 50 | err_sys("realloc failed"); 51 | } 52 | } 53 | strcpy(fullpath, pathname); 54 | return(dopath(func)); 55 | } 56 | static int dopath(Myfunc func){ 57 | struct stat statbuf; 58 | struct dirent *dirp; 59 | DIR *dp; 60 | int ret, n; 61 | if (lstat(fullpath, &statbuf) < 0){ 62 | return(func(fullpath, &statbuf, FTW_NS)); 63 | } 64 | 65 | if (S_ISDIR(statbuf.st_mode) == 0){ 66 | return(func(fullpath, &statbuf, FTW_F)); 67 | } 68 | 69 | if ((ret = func(fullpath, &statbuf, FTW_D)) != 0){ 70 | return(ret); 71 | } 72 | 73 | n = strlen(fullpath); 74 | 75 | if ((n + NAME_MAX + 2) > pathlen){ 76 | pathlen *= 2; 77 | if ((fullpath = realloc(fullpath, pathlen)) == NULL){ 78 | err_sys("realloc failed"); 79 | } 80 | } 81 | 82 | fullpath[n++] = '/'; 83 | fullpath[n] = 0; 84 | 85 | if ((dp = opendir(fullpath)) == NULL){ 86 | return(func(fullpath, &statbuf, FTW_DNR)); 87 | } 88 | 89 | while ((dirp = readdir(dp)) != NULL){ 90 | if (strcmp(dirp->d_name, ".") == 0 | strcmp(dirp->d_name, "..") == 0){ 91 | continue; 92 | } 93 | strcpy(&fullpath[n], dirp->d_name); 94 | if ((ret = dopath(func)) != 0){ 95 | break; 96 | } 97 | } 98 | 99 | fullpath[n-1] = 0; 100 | 101 | if (closedir(dp) < 0){ 102 | err_ret("can't close directory %s", fullpath); 103 | } 104 | 105 | return(ret); 106 | } 107 | 108 | static int myfunc(const char *pathname, const struct stat *statptr, int type){ 109 | switch (type){ 110 | case FTW_F: 111 | switch (statptr->st_mode & S_IFMT){ 112 | case S_IFREG: 113 | nreg++; 114 | break; 115 | 116 | case S_IFBLK: 117 | nblk++; 118 | break; 119 | 120 | case S_IFCHR: 121 | nchr++; 122 | break; 123 | 124 | case S_IFIFO: 125 | nfifo++; 126 | break; 127 | 128 | case S_IFLNK: 129 | nslink++; 130 | break; 131 | 132 | case S_IFSOCK: 133 | nsock++; 134 | break; 135 | 136 | case S_IFDIR: 137 | err_dump("for S_IFDIR for %s", pathname); 138 | } 139 | break; 140 | 141 | case FTW_D: 142 | ndir++; 143 | break; 144 | 145 | case FTW_DNR: 146 | err_ret("can't read directory %s", pathname); 147 | break; 148 | 149 | case FTW_NS: 150 | err_ret("stat error for %s", pathname); 151 | break; 152 | 153 | default: 154 | err_dump("unknown type %d for pathname %s", type, pathname); 155 | } 156 | 157 | return(0); 158 | } -------------------------------------------------------------------------------- /APUE/4_23.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | int main(void){ 4 | if (chdir("/tmp") < 0){ 5 | err_sys("chdir failed"); 6 | } 7 | 8 | printf("chdir to /tmp succeeded\n"); 9 | exit(0); 10 | } -------------------------------------------------------------------------------- /APUE/4_24.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | int main(void){ 4 | char *ptr; 5 | size_t size; 6 | 7 | if (chdir("/usr/spool/uucppublic") < 0){ 8 | err_sys("chdir failed"); 9 | } 10 | 11 | ptr = path_alloc(&size); 12 | 13 | if (getcwd(ptr, size) == NULL){ 14 | err_sys("getcwd failed"); 15 | } 16 | 17 | printf("%s\n", ptr); 18 | exit(0); 19 | } -------------------------------------------------------------------------------- /APUE/4_25.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]){ 5 | int i; 6 | struct stat buf; 7 | 8 | for (i = 1; i < argc; i++){ 9 | printf("%s : ", argv[i]); 10 | if (stat(argv[i], &buf) < 0){ 11 | err_ret("stat error"); 12 | continue; 13 | } 14 | 15 | printf("dev = %d/%d\n", MAJOR(buf.st_dev), MINOR(buf.st_dev)); 16 | if (S_ISCHR(buf.st_mode) || S_ISBLK(buf.st_mode)){ 17 | printf("(%s) rdev %d/%d\n", (S_ISCHR(buf.st_mode) ? "character" : "block", MAJOR(buf.st_rdev), MINOR(buf.st_rdev))); 18 | } 19 | printf("\n"); 20 | } 21 | 22 | exit(0); 23 | } -------------------------------------------------------------------------------- /APUE/4_3.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | int main(int argc, char* argv[]){ 4 | int i; 5 | struct stat buf; 6 | char* ptr; 7 | 8 | for (i = 1; i < argc; i++){ 9 | printf("%s : ", argv[i]); 10 | if (lstat(argv[i], &buf) < 0){ 11 | err_ret("lstat error"); 12 | continue; 13 | } 14 | 15 | if (S_ISREG(buf.st_mode)){ 16 | ptr = "regular"; 17 | } 18 | else if (S_ISDIR(buf.st_mode)){ 19 | ptr = "directory"; 20 | } 21 | else if (S_ISCHR(buf.st_mode)){ 22 | ptr = "character special"; 23 | } 24 | else if (S_ISBLK(buf.st_mode)){ 25 | ptr = "block special"; 26 | } 27 | else if (S_ISFIFO(buf.st_mode)){ 28 | ptr = "fifo"; 29 | } 30 | else if (S_ISLNK(buf.st_mode)){ 31 | ptr = "symbolic link"; 32 | } 33 | else if (S_ISSOCK(buf.st_mode)){ 34 | ptr = "socket"; 35 | } 36 | else { 37 | ptr = "** unknown mode **"; 38 | } 39 | 40 | printf("%s\n", ptr); 41 | } 42 | 43 | exit(0); 44 | } -------------------------------------------------------------------------------- /APUE/4_8.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | int main(int argc, char* argv[]){ 5 | if (argc != 2){ 6 | err_quit("usage : main "); 7 | } 8 | 9 | if (access(argv[1], R_OK) < 0){ 10 | err_ret("access error for %s", argv[1]); 11 | } 12 | else{ 13 | printf("read access OK\n"); 14 | } 15 | 16 | if (open(argv[1], O_RDONLY) < 0){ 17 | err_ret("open error for %s", argv[1]); 18 | } 19 | else{ 20 | printf("open for reading OK\n"); 21 | } 22 | 23 | exit(0); 24 | } -------------------------------------------------------------------------------- /APUE/4_9.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | #define RWRWRW (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) 5 | 6 | int main(void){ 7 | umask(0); 8 | if (creat("foo", RWRWRW) < 0){ 9 | err_sys("creat error for foo"); 10 | } 11 | umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); 12 | if (creat("bar", RWRWRW) < 0){ 13 | err_sys("creat error for bar"); 14 | } 15 | 16 | exit(0); 17 | } -------------------------------------------------------------------------------- /APUE/5_11.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | void pr_stdio(const char *, FILE *); 4 | int is_unbuffered(FILE *); 5 | int is_linebuffered(FILE *); 6 | int buffer_size(FILE *); 7 | 8 | int main(void){ 9 | FILE *fp; 10 | 11 | fputs("enter any character\n", stdout); 12 | if (getchar() == EOF){ 13 | err_sys("getchar error"); 14 | } 15 | 16 | fputs("one line to standard error\n", stderr); 17 | 18 | pr_stdio("stdin", stdin); 19 | pr_stdio("stdout", stdout); 20 | pr_stdio("stderr", stderr); 21 | 22 | if ((fp = fopen("/etc/passwd", "r")) == NULL){ 23 | err_sys("fopen error"); 24 | } 25 | 26 | if (getc(fp) == EOF){ 27 | err_sys("getc error"); 28 | } 29 | 30 | pr_stdio("/etc/passwd", fp); 31 | 32 | exit(0); 33 | } 34 | 35 | void pr_stdio(const char *name, FILE *fp){ 36 | printf("stream = %s, ", name); 37 | if (is_unbuffered(fp)){ 38 | printf("unbuffered"); 39 | } 40 | else if (is_linebuffered(fp)){ 41 | printf("line buffered"); 42 | } 43 | else{ 44 | printf("full buffered"); 45 | } 46 | 47 | printf(", buffer size = %d\n", buffer_size(fp)); 48 | } 49 | 50 | int is_unbuffered(FILE *fp){ 51 | return(fp->_flags & _IONBF); 52 | } 53 | 54 | int is_linebuffered(FILE *fp){ 55 | return(fp->_flags & _IOLBF); 56 | } 57 | 58 | int buffer_size(FILE *fp){ 59 | return(fp->_IO_buf_end - fp->_IO_buf_base); 60 | } -------------------------------------------------------------------------------- /APUE/5_12.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | int main(void){ 4 | char name[L_tmpnam], line[MAXLINE]; 5 | FILE *fp; 6 | 7 | printf("%s\n", tmpnam(NULL)); 8 | 9 | tmpnam(name); 10 | printf("%s\n", name); 11 | 12 | if ((fp = tmpfile()) == NULL){ 13 | err_sys("tmpfile error"); 14 | } 15 | 16 | fputs("one line of output\n", fp); 17 | rewind(fp); 18 | 19 | if (fgets(line, sizeof(line), fp) == NULL){ 20 | err_sys("fgets error"); 21 | } 22 | 23 | fputs(line, stdout); 24 | exit(0); 25 | } -------------------------------------------------------------------------------- /APUE/5_13.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | void make_tmp(char *template); 4 | 5 | int main(void){ 6 | char good_template[] = "/tmp/dirXXXXXX"; 7 | char *bad_template = "/tmp/dirXXXXXX"; 8 | 9 | printf("trying to create first temp file...\n"); 10 | make_tmp(good_template); 11 | printf("trying to create second temp file...\n"); 12 | make_tmp(bad_template); 13 | 14 | exit(0); 15 | } 16 | 17 | void make_tmp(char *template){ 18 | int fd; 19 | struct stat statbuf; 20 | 21 | if ((fd = mkstemp(template)) < 0){ 22 | err_sys("mkstemp error"); 23 | } 24 | printf("temp name = %s\n", template); 25 | close(fd); 26 | 27 | if (stat(template, &statbuf) < 0){ 28 | if (errno == ENOENT){ 29 | printf("file doesn't exist\n"); 30 | } 31 | else{ 32 | err_sys("stat error"); 33 | } 34 | } 35 | else{ 36 | printf("file exist\n"); 37 | unlink(template); 38 | } 39 | } -------------------------------------------------------------------------------- /APUE/5_15.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | #define BSZ 48 4 | 5 | int main(void){ 6 | FILE *fp; 7 | char buf[BSZ]; 8 | 9 | memset(buf, 'a', BSZ-2); 10 | buf[BSZ-2] = '\0'; 11 | buf[BSZ-1] = 'X'; 12 | 13 | if ((fp = fmemopen(buf, BSZ, "w+")) == NULL){ 14 | err_sys("fmemopen error"); 15 | } 16 | 17 | printf("initial buffer contents : %s\n", buf); 18 | fprintf(fp, "hello world"); 19 | printf("before flush : %s\n", buf); 20 | fflush(fp); 21 | printf("after flush : %s\n", buf); 22 | printf("length of string in buffer = %ld\n", (long)strlen(buf)); 23 | 24 | 25 | memset(buf, 'b', BSZ-2); 26 | buf[BSZ-2] = '\0'; 27 | buf[BSZ-1] = 'X'; 28 | fprintf(fp, "hello world"); 29 | fseek(fp, 0, SEEK_SET); 30 | printf("after fseek : %s\n", buf); 31 | printf("length of string in buffer = %ld\n", (long)strlen(buf)); 32 | 33 | 34 | 35 | memset(buf, 'c', BSZ-2); 36 | buf[BSZ-2] = '\0'; 37 | buf[BSZ-1] = 'X'; 38 | fprintf(fp, "hello world"); 39 | fclose(fp); 40 | printf("after fclose : %s\n", buf); 41 | printf("length of string in buffer = %ld\n", (long)strlen(buf)); 42 | 43 | return(0); 44 | } -------------------------------------------------------------------------------- /APUE/5_4.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | int main(void){ 4 | int c; 5 | 6 | while ((c = getc(stdin)) != EOF){ 7 | if (putc(c, stdout) == EOF){ 8 | err_sys("output error"); 9 | } 10 | } 11 | 12 | if (ferror(stdin)){ 13 | err_sys("input error"); 14 | } 15 | 16 | exit(0); 17 | } -------------------------------------------------------------------------------- /APUE/5_5.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | int main(void){ 4 | char buf[MAXLINE]; 5 | 6 | while (fgets(buf, MAXLINE, stdin) != NULL){ 7 | if (fputs(buf, stdout) == EOF){ 8 | err_sys("output error"); 9 | } 10 | } 11 | 12 | if (ferror(stdin)){ 13 | err_sys("input error"); 14 | } 15 | 16 | exit(0); 17 | } -------------------------------------------------------------------------------- /APUE/6_11.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(void){ 6 | time_t t; 7 | struct tm *tmp; 8 | char buf1[16]; 9 | char buf2[64]; 10 | 11 | time(&t); 12 | tmp = localtime(&t); 13 | 14 | if (strftime(buf1, 16, "time and date : %r, %a %b %d, %Y", tmp) == 0){ 15 | printf("buffer length 16 is too small\n"); 16 | } 17 | else{ 18 | printf("%s\n", buf1); 19 | } 20 | 21 | if (strftime(buf2, 64, "time and date : %r, %a %b %d, %Y", tmp) == 0){ 22 | printf("buffer length 64 is too small\n"); 23 | } 24 | else{ 25 | printf("%s\n", buf2); 26 | } 27 | 28 | exit(0); 29 | } -------------------------------------------------------------------------------- /APUE/6_2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct passwd *getpwnam(const char *name){ 6 | struct passwd *ptr; 7 | setpwent(); 8 | 9 | while ((ptr = getpwent) != NULL){ 10 | if (strcmp(name, ptr->pw_name) == 0){ 11 | break; 12 | } 13 | } 14 | 15 | endpwent(); 16 | return(ptr); 17 | } -------------------------------------------------------------------------------- /APUE/7_1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void){ 4 | printf("hello world\n"); 5 | } -------------------------------------------------------------------------------- /APUE/7_13.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | static void f1(int, int, int, int); 5 | static void f2(void); 6 | 7 | static jmp_buf jmpbuffer; 8 | static int globval; 9 | 10 | int main(void){ 11 | int autoval; 12 | register int regival; 13 | volatile int volaval; 14 | static int statval; 15 | 16 | globval = 1; 17 | autoval = 2; 18 | regival = 3; 19 | volaval = 4; 20 | statval = 5; 21 | 22 | if (setjmp(jmpbuffer) != 0){ 23 | printf("after longjmp : \n"); 24 | printf("globval = %d, autoval = %d, regival = %d, volaval = %d, statval = %d\n", 25 | globval, autoval, regival, volaval, statval); 26 | exit(0); 27 | } 28 | 29 | globval = 95; 30 | autoval = 96; 31 | regival = 97; 32 | volaval = 98; 33 | statval = 99; 34 | 35 | f1(autoval, regival, volaval, statval); 36 | exit(0); 37 | } 38 | 39 | 40 | static void f1(int i, int j, int k, int l){ 41 | printf("in f1() : \n"); 42 | printf("globval = %d, autoval = %d, regival = %d, volaval = %d, statval = %d\n", 43 | globval, i, j, k, l); 44 | f2(); 45 | } 46 | 47 | static void f2(){ 48 | longjmp(jmpbuffer, 1); 49 | } -------------------------------------------------------------------------------- /APUE/7_16.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | #define doit(name) pr_limits(#name, name) 5 | 6 | static void pr_limits(char *, int); 7 | 8 | int main(void){ 9 | #ifdef RLIMIT_AS 10 | doit(RLIMIT_AS); 11 | #endif 12 | 13 | doit(RLIMIT_CORE); 14 | doit(RLIMIT_CPU); 15 | doit(RLIMIT_DATA); 16 | doit(RLIMIT_FSIZE); 17 | 18 | #ifdef RLIMIT_MEMLOCK 19 | doit(RLIMIT_MEMLOCK); 20 | #endif 21 | 22 | #ifdef RLIMIT_MSGQUEUE 23 | doit(RLIMIT_MSGQUEUE); 24 | #endif 25 | 26 | #ifdef RLIMIT_NICE 27 | doit(RLIMIT_NICE); 28 | #endif 29 | 30 | doit(RLIMIT_NOFILE); 31 | 32 | #ifdef RLIMIT_NPROC 33 | doit(RLIMIT_NPROC); 34 | #endif 35 | 36 | #ifdef RLIMIT_NPTS 37 | doit(RLIMIT_NPTS); 38 | #endif 39 | 40 | #ifdef RLIMIT_RSS 41 | doit(RLIMIT_RSS); 42 | #endif 43 | 44 | #ifdef RLIMIT_SBSIZE 45 | doit(RLIMIT_SBSIZE); 46 | #endif 47 | 48 | #ifdef RLIMIT_SIGPENDING 49 | doit(RLIMIT_SIGPENDING); 50 | #endif 51 | 52 | doit(RLIMIT_STACK); 53 | 54 | #ifdef RLIMIT_SWAP 55 | doit(RLIMIT_SWAP); 56 | #endif 57 | 58 | #ifdef RLIMIT_VMEM 59 | doit(RLIMIT_VMEM); 60 | #endif 61 | 62 | exit(0); 63 | } 64 | 65 | static void pr_limits(char *name, int resource){ 66 | struct rlimit limit; 67 | unsigned long long lim; 68 | 69 | if (getrlimit(resource, &limit) < 0){ 70 | err_sys("getrlimit error"); 71 | } 72 | 73 | printf("%-14s ", name); 74 | 75 | if (limit.rlim_cur == RLIM_INFINITY){ 76 | printf("(infinity) "); 77 | } 78 | else{ 79 | lim = limit.rlim_cur; 80 | printf("%10lld ", lim); 81 | } 82 | 83 | if (limit.rlim_max == RLIM_INFINITY){ 84 | printf("(infinity) "); 85 | } 86 | else{ 87 | lim = limit.rlim_max; 88 | printf("%10lld ", lim); 89 | } 90 | 91 | putchar((int)'\n'); 92 | } -------------------------------------------------------------------------------- /APUE/7_3.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | static void my_exit1(void); 4 | static void my_exit2(void); 5 | 6 | int main(void){ 7 | if (atexit(my_exit2) != 0){ 8 | err_sys("can't register my_exit2"); 9 | } 10 | 11 | if (atexit(my_exit1) != 0){ 12 | err_sys("can't register my_exit1"); 13 | } 14 | 15 | if (atexit(my_exit1) != 0){ 16 | err_sys("can't register my_exit1"); 17 | } 18 | 19 | printf("main is done\n"); 20 | return(0); 21 | } 22 | 23 | static void my_exit1(void){ 24 | printf("first exit handler\n"); 25 | } 26 | 27 | static void my_exit2(void){ 28 | printf("second exit handler\n"); 29 | } -------------------------------------------------------------------------------- /APUE/7_4.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | int main(int argc, char *argv[]){ 4 | int i; 5 | 6 | for (i = 0; i < argc; i++){ 7 | printf("argv[%d] : %s\n", i, argv[i]); 8 | } 9 | 10 | exit(0); 11 | } -------------------------------------------------------------------------------- /APUE/8_1.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | int globvar = 6; 4 | char buf[] = "a write to stdout\n"; 5 | 6 | int main(void){ 7 | int var; 8 | pid_t pid; 9 | 10 | var = 88; 11 | if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf) - 1){ 12 | err_sys("write error"); 13 | } 14 | printf("before fork : \n"); 15 | 16 | if ((pid = fork()) < 0){ 17 | err_sys("fork error"); 18 | } 19 | else if (pid == 0){ 20 | globvar++; 21 | var++; 22 | } 23 | else{ 24 | sleep(2); 25 | } 26 | 27 | printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar, var); 28 | 29 | exit(0); 30 | } -------------------------------------------------------------------------------- /APUE/8_12.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | static void charactatime(char *); 4 | 5 | int main(void){ 6 | pid_t pid; 7 | 8 | if ((pid = fork()) < 0){ 9 | err_sys("fork error"); 10 | } 11 | else if (pid == 0){ 12 | charactatime("output from child\n"); 13 | } 14 | else{ 15 | charactatime("output from parent\n"); 16 | } 17 | 18 | exit(0); 19 | } 20 | 21 | static void charactatime(char *str){ 22 | char* ptr; 23 | int c; 24 | 25 | setbuf(stdout, NULL); 26 | for (ptr = str; (c = *ptr++) != 0;){ 27 | putc(c, stdout); 28 | } 29 | } -------------------------------------------------------------------------------- /APUE/8_3.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | 3 | int globvar = 6; 4 | 5 | int main(void){ 6 | int var; 7 | pid_t pid; 8 | 9 | var = 88; 10 | printf("before fork : \n"); 11 | 12 | if ((pid = vfork()) < 0){ 13 | err_sys("vfork error"); 14 | } 15 | else if (pid == 0){ 16 | globvar++; 17 | var++; 18 | _exit(0); 19 | } 20 | 21 | printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar, var); 22 | 23 | exit(0); 24 | } -------------------------------------------------------------------------------- /APUE/8_5.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | void pr_exit(int status){ 5 | if (WIFEXITED(status)){ 6 | printf("normal termination, exit status = %d\n", WEXITSTATUS(status)); 7 | } 8 | else if (WIFSIGNALED(status)){ 9 | printf("abnormal termination, signal number = %d%s\n", WTERMSIG(status), 10 | 11 | #ifdef WCOREDUMP 12 | WCOREDUMP(status) ? " (core file generated )" : ""); 13 | #else 14 | ""); 15 | #endif 16 | } 17 | else if (WIFSTOPPED(status)){ 18 | printf("child stopped, signal number = %d\n", WSTOPSIG(status)); 19 | } 20 | } -------------------------------------------------------------------------------- /APUE/8_6.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | void pr_exit(int status); 5 | 6 | int main(void){ 7 | pid_t pid; 8 | int status; 9 | 10 | if ((pid = fork()) < 0){ 11 | err_sys("fork error"); 12 | } 13 | else if(pid == 0){ 14 | exit(7); 15 | } 16 | 17 | if (wait(&status) != pid){ 18 | err_sys("wait error"); 19 | } 20 | pr_exit(status); 21 | 22 | if ((pid = fork()) < 0){ 23 | err_sys("fork error"); 24 | } 25 | else if(pid == 0){ 26 | abort(); 27 | } 28 | 29 | if (wait(&status) != pid){ 30 | err_sys("wait error"); 31 | } 32 | pr_exit(status); 33 | 34 | if ((pid = fork()) < 0){ 35 | err_sys("fork error"); 36 | } 37 | else if(pid == 0){ 38 | status /= 0; 39 | } 40 | 41 | if (wait(&status) != pid){ 42 | err_sys("wait error"); 43 | } 44 | pr_exit(status); 45 | 46 | exit(0); 47 | } 48 | 49 | void pr_exit(int status){ 50 | if (WIFEXITED(status)){ 51 | printf("normal termination, exit status = %d\n", WEXITSTATUS(status)); 52 | } 53 | else if (WIFSIGNALED(status)){ 54 | printf("abnormal termination, signal number = %d%s\n", WTERMSIG(status), 55 | 56 | #ifdef WCOREDUMP 57 | WCOREDUMP(status) ? " (core file generated )" : ""); 58 | #else 59 | ""); 60 | #endif 61 | } 62 | else if (WIFSTOPPED(status)){ 63 | printf("child stopped, signal number = %d\n", WSTOPSIG(status)); 64 | } 65 | } -------------------------------------------------------------------------------- /APUE/8_8.c: -------------------------------------------------------------------------------- 1 | #include "apue.h" 2 | #include 3 | 4 | int main(void){ 5 | pid_t pid; 6 | if ((pid = fork()) < 0){ 7 | err_sys("fork error"); 8 | } 9 | else if (pid == 0){ 10 | if ((pid = fork()) < 0){ 11 | err_sys("fork error"); 12 | } 13 | else if (pid > 0){ 14 | exit(0); 15 | } 16 | 17 | sleep(2); 18 | printf("second child, parent pid = %ld\n", (long)getppid()); 19 | exit(0); 20 | } 21 | 22 | if (waitpid(pid, NULL, 0) != pid){ 23 | err_sys("waitpid error"); 24 | } 25 | 26 | exit(0); 27 | } -------------------------------------------------------------------------------- /APUE/FuncPointer.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef int Myfunc(int a, int b); 4 | 5 | Myfunc myfunc; 6 | 7 | int myftw(int , int , Myfunc *); 8 | 9 | int main(void){ 10 | int x = 3; 11 | int y = 4; 12 | int ret = myftw(&x, &y, &myfunc); 13 | printf("%d\n", ret); 14 | 15 | return 0; 16 | } 17 | 18 | int myfunc(int a, int b){ 19 | return (a < b); 20 | } 21 | 22 | int myftw(int a, int b, Myfunc *func){ 23 | return func(a, b); 24 | } -------------------------------------------------------------------------------- /Advanced Programming in the UNIX Environment 3rd Edition.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lincheng1993/apue/9b3925f532472c521b945ec59a2d5426c1a09461/Advanced Programming in the UNIX Environment 3rd Edition.pdf -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Find out all the include and source files for 2 | SRC_FILE := $(wildcard *.c) 3 | OBJ_FILE := $(subst .c,.o,$(SRC_FILE)) 4 | TARGET := main 5 | CFLAGS := -std=c99 6 | 7 | .PHONY: all 8 | 9 | all: $(TARGET) 10 | 11 | $(TARGET): $(OBJ_FILE) 12 | $(CC) -o $@ $^ 13 | %.o: %.c 14 | $(CC) -o $@ -c $< $(CFLAGS) 15 | 16 | clean: 17 | rm $(OBJ_FILE) $(TARGET) -f 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # apue 2 | Advanced Programming in the UNIX 3 | -------------------------------------------------------------------------------- /UNIX环境高级编程(中文第三版).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lincheng1993/apue/9b3925f532472c521b945ec59a2d5426c1a09461/UNIX环境高级编程(中文第三版).pdf -------------------------------------------------------------------------------- /src.3e.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lincheng1993/apue/9b3925f532472c521b945ec59a2d5426c1a09461/src.3e.tar.gz -------------------------------------------------------------------------------- /unix高级编程apue习题答案.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lincheng1993/apue/9b3925f532472c521b945ec59a2d5426c1a09461/unix高级编程apue习题答案.pdf --------------------------------------------------------------------------------