【转】APUE学习1:迈出第一步,编译myls.c

原文网址:http://blog.csdn.net/sddzycnqjn/article/details/7252444

注:以下写作风格均学习自潘云登前辈
/******************************************************************/  
By:             聂强
Date:          2012-2-12
Email:         sddzycnq@gmail.com
Homepage: http://blog.csdn.net/sddzycnqjn
Copyright: 该文章版权由聂强所有。可在非商业目的下任意传播和复制。
对于商业目的下对本文的任何行为需经作者同意。
/******************************************************************/
运行环境:Ubuntu 10.04.1 LTS
Linux version 2.6.32-24-generic
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
在当当网订购的《unix环境高级编程》还未到。求学心切,先下载了PDF版一睹为快。
但编译第一个例子就出现了问题:
             myls.c:1:19: apue.h: No such file or directory
             myls.c: In function `main':
             myls.c:13: error: `NULL' undeclared (first use in this function)
             myls.c:13: error: (Each undeclared identifier is reported only once
             myls.c:13: error: for each function it appears in.)
找不到头文件apue.h。
网友支招:
1. www.apuebook.com下载源代码。
2. 解压得到目录apue.2e。
3. 将 apue.2e/include下apue.h文件拷贝至/usr/include。
    此时,再编译还会出问题:
             /tmp/ccBBopm0.o(.text+0x2b): In function `main':
            : undefined reference to `err_quit'
            /tmp/ccBBopm0.o(.text+0x5f): In function `main':
            : undefined reference to `err_sys'
            collect2: ld returned 1 exit status
    提示找不到函数err_quit和err_sys。
4. 解决步骤3问题的办法:
在目录/usr/include,创建文件myerr.h。其中myerr.h内容为附录B中内容(现将代码贴出):
读书要仔细:
《unix环境高级编程》第5页作者有这样一句话“在这20行的程序中,有很多细节需要考虑”。
·首先,其中包含了一个头文件apue.h。本书中几乎每一个程序都包含此头文件。……。附录B中列出了这一头文件。
·……
·调用了两个自编的函数来对错误进行处理:err_sys和err_quit。……。这两个出错处理函数在附录B中说明,1.7节将更多地叙述出错处理。
  1. <span style="font-family:SimSun;">#include "apue.h"  
  2. #include <errno.h>/* for definition of errno */  
  3. #include <stdarg.h> /* ISO C variable aruments */  
  4.   
  5. static void err_doit(int, int, const char *, va_list);  
  6.   
  7. /* 
  8. * Nonfatal error related to a system call. 
  9. * Print a message and return. 
  10. */  
  11. void  
  12. err_ret(const char *fmt, ...)  
  13. {  
  14.     va_list ap;    va_start(ap, fmt);  
  15.     err_doit(1, errno, fmt, ap);  
  16.     va_end(ap);  
  17. }  
  18.   
  19. /* 
  20. * Fatal error related to a system call. 
  21. * Print a message and terminate. 
  22. */  
  23. void  
  24. err_sys(const char *fmt, ...)  
  25. {  
  26.     va_list ap;    va_start(ap, fmt);  
  27.     err_doit(1, errno, fmt, ap);  
  28.     va_end(ap);  
  29.     exit(1);  
  30. }  
  31.   
  32. /* 
  33. * Fatal error unrelated to a system call. 
  34. * Error code passed as explict parameter. 
  35. * Print a message and terminate. 
  36. */  
  37. void  
  38. err_exit(int error, const char *fmt, ...)  
  39. {  
  40.     va_list ap;    va_start(ap, fmt);  
  41.     err_doit(1, error, fmt, ap);  
  42.     va_end(ap);  
  43.     exit(1);  
  44. }  
  45.   
  46. /* 
  47. * Fatal error related to a system call. 
  48. * Print a message, dump core, and terminate. 
  49. */  
  50. void  
  51. err_dump(const char *fmt, ...)  
  52. {  
  53.     va_list ap;    va_start(ap, fmt);  
  54.     err_doit(1, errno, fmt, ap);  
  55.     va_end(ap);  
  56.     abort();  /* dump core and terminate */  
  57.     exit(1);  /* shouldn't get here */  
  58. }  
  59.   
  60. /* 
  61. * Nonfatal error unrelated to a system call. 
  62. * Print a message and return. 
  63. */  
  64. void  
  65. err_msg(const char *fmt, ...)  
  66. {  
  67.     va_list ap;    va_start(ap, fmt);  
  68.     err_doit(0, 0, fmt, ap);  
  69.     va_end(ap);  
  70. }  
  71.   
  72. /* 
  73. * Fatal error unrelated to a system call. 
  74. * Print a message and terminate. 
  75. */  
  76. void  
  77. err_quit(const char *fmt, ...)  
  78. {  
  79.     va_list ap;    va_start(ap, fmt);  
  80.     err_doit(0, 0, fmt, ap);  
  81.     va_end(ap);  
  82.     exit(1);  
  83. }  
  84.   
  85. /* 
  86. * Print a message and return to caller. 
  87. * Caller specifies "errnoflag". 
  88. */  
  89. static void  
  90. err_doit(int errnoflag, int error, const char *fmt, va_list ap)  
  91. {  
  92.     char    buf[MAXLINE];  
  93.    vsnprintf(buf, MAXLINE, fmt, ap);  
  94.    if (errnoflag)  
  95. snprintf(buf+strlen(buf), MAXLINE-strlen(buf), ": %s",  
  96.    strerror(error));  
  97.    strcat(buf, " ");  
  98.    fflush(stdout); /* in case stdout and stderr are the same */  
  99.    fputs(buf, stderr);  
  100.    fflush(NULL); /* flushes all stdio output streams */  
  101. }</span>  
5. 编辑/usr/include/apue.h。在最后一行#endif    /* _APUE_H */前面添加一个声明:#include "myerr.h"
OK,至此。
再次编译:gcc   -o myls myls.c 成功
运行:  ./myls  /dev
结果:
.
..
mixer
audio
dsp
……
……
port
null
mem
rfkill
vga_arbiter

posted on 2015-02-06 17:03  wi100sh  阅读(812)  评论(0编辑  收藏  举报

导航