unix环境高级编程 程序3-11(fileflags.c)全面解析
2017-01-18 11:09
204 查看
源程序:
#include "apue.h"
#include <fcntl.h>
int
main(int argc, char *argv[])
{
int val;
if (argc != 2)
err_quit("usage: a.out <descriptor#>");
if ((val = fcntl(atoi(argv[1]), F_GETFL, 0)) < 0)
err_sys("fcntl error for fd %d", atoi(argv[1]));
switch (val & O_ACCMODE) {
case O_RDONLY:
printf("read only");
break;
case O_WRONLY:
printf("write only");
break;
case O_RDWR:
printf("read write");
break;
default:
err_dump("unknown access mode");
}
if (val & O_APPEND)
printf(", append");
if (val & O_NONBLOCK)
printf(", nonblocking");
if (val & O_SYNC)
printf(", synchronous writes");
#if !defined(_POSIX_C_SOURCE) && defined(O_FSYNC) && (O_FSYNC != O_SYNC)
if (val & O_FSYNC)
printf(", synchronous writes");
#endif
putchar('\n');
exit(0);
}程序运行结果:(如何运行该书实例代码 参见
APUE.3e 安装(基于ubuntu12.0.4) )
root@ubuntu:/home/yuccess/shiyan/apue.3e/fileio# ./fileflags 0 < /dev/tty
read only
root@ubuntu:/home/yuccess/shiyan/apue.3e/fileio# ./fileflags 1 > temp.foo
root@ubuntu:/home/yuccess/shiyan/apue.3e/fileio# cat temp.foo
write only
root@ubuntu:/home/yuccess/shiyan/apue.3e/fileio# ./fileflags 2 2>>temp.foo
write only, append
root@ubuntu:/home/yuccess/shiyan/apue.3e/fileio# ./fileflags 5 5<>temp.foo
read write
问题1:./fileflags 0 < /dev/tty 什么意思?
知识点重定向(讲解重定向比较好的文章)
< /dev/tty 的意思就是将标准输入重定向为文件tty
0是main()第二个参数(在问题2中讲解)
第一个参数是./fileflags
问题2: ./fileflags 2 2>>temp.foo怎么解释。
有了重定向的知识后,我们知道了2>>temp.foo的意识就是 将一个标准错误输出重定向到一个文件或设备 追加到原来的文件
那么 中间的那个2 又是什么意思?从源程序说起
main(int argc, char *argv[]) main函数参数argv此时为什么?
可以用print()将argv打印出来,不过这样的话就得重新编译了。这时候采用GDB调试的方法,来查看argv。
step1:在终端输入gcc fileflags.c -g -o fileflags -l apue
step2:输入 gdb fileflags
step3:进入gdb后输入调试代码:
(gdb) l -->显示代码
(gdb) b -->设置断点
(gdb) r 2 2>>temp.foo -->run<
4000
/p>
(gdb) p argv[1] --> 显示结果为 $2 = 0xbffff565 "2"
(gdb) p *argv@2 -->显示数组里的前两个结果 $6 = {0xbffff537 "/home/yuccess/shiyan/apue.3e/fileio/fileflags", 0xbffff565 "2"}
至此我们gdb调试完毕,可以发现 2 是main的第二个参数,而 2>>temp.foo表示将标准输出重定向到temp.foo上(类似于 < /dev/tty),不是一个参数,至于为什么不太清清楚。
感受:gdb调试全键盘的操作,比vs2013、xcode神马的爽爆了啊!
附gdb调试常用命令:
在gdb中,和调试步进相关的命令主要有如下几条:
continue 继续运行程序直到下一个断点(类似于VS里的F5)
next 逐过程步进,不会进入子函数(类似VS里的F10)
setp 逐语句步进,会进入子函数(类似VS里的F11)
until 运行至当前语句块结束
finish 运行至函数结束并跳出,并打印函数的返回值(类似VS的Shift+F11)
问题3:下面这句 话的解释if ((val = fcntl(atoi(argv[1]), F_GETFL, 0)) < 0)
首先fcntl()函数的意思是改变/返回一个已经打开文件的属性。
参数F_GETFL说明,该函数要返回文件(第一个参数)的状态标识。
可以调试查看val的结果,如果想显示宏O_ACCMODE的值的话,需要在终端这样输入:gcc
-gdwarf-2 -g3 fileflags.c -l apue -o fileflags
具体细枝末节请参阅APUE 3.14小节
总结:至此已经基本完全理解了该实例,学习了重定向,GDB调试,fcntl等知识,通过调试实践APUE上面的知识,相信对初学linux编程的童鞋会有帮助。
接下来继续啃APUE。
#include "apue.h"
#include <fcntl.h>
int
main(int argc, char *argv[])
{
int val;
if (argc != 2)
err_quit("usage: a.out <descriptor#>");
if ((val = fcntl(atoi(argv[1]), F_GETFL, 0)) < 0)
err_sys("fcntl error for fd %d", atoi(argv[1]));
switch (val & O_ACCMODE) {
case O_RDONLY:
printf("read only");
break;
case O_WRONLY:
printf("write only");
break;
case O_RDWR:
printf("read write");
break;
default:
err_dump("unknown access mode");
}
if (val & O_APPEND)
printf(", append");
if (val & O_NONBLOCK)
printf(", nonblocking");
if (val & O_SYNC)
printf(", synchronous writes");
#if !defined(_POSIX_C_SOURCE) && defined(O_FSYNC) && (O_FSYNC != O_SYNC)
if (val & O_FSYNC)
printf(", synchronous writes");
#endif
putchar('\n');
exit(0);
}程序运行结果:(如何运行该书实例代码 参见
APUE.3e 安装(基于ubuntu12.0.4) )
root@ubuntu:/home/yuccess/shiyan/apue.3e/fileio# ./fileflags 0 < /dev/tty
read only
root@ubuntu:/home/yuccess/shiyan/apue.3e/fileio# ./fileflags 1 > temp.foo
root@ubuntu:/home/yuccess/shiyan/apue.3e/fileio# cat temp.foo
write only
root@ubuntu:/home/yuccess/shiyan/apue.3e/fileio# ./fileflags 2 2>>temp.foo
write only, append
root@ubuntu:/home/yuccess/shiyan/apue.3e/fileio# ./fileflags 5 5<>temp.foo
read write
问题1:./fileflags 0 < /dev/tty 什么意思?
知识点重定向(讲解重定向比较好的文章)
< /dev/tty 的意思就是将标准输入重定向为文件tty
0是main()第二个参数(在问题2中讲解)
第一个参数是./fileflags
问题2: ./fileflags 2 2>>temp.foo怎么解释。
有了重定向的知识后,我们知道了2>>temp.foo的意识就是 将一个标准错误输出重定向到一个文件或设备 追加到原来的文件
那么 中间的那个2 又是什么意思?从源程序说起
main(int argc, char *argv[]) main函数参数argv此时为什么?
可以用print()将argv打印出来,不过这样的话就得重新编译了。这时候采用GDB调试的方法,来查看argv。
step1:在终端输入gcc fileflags.c -g -o fileflags -l apue
step2:输入 gdb fileflags
step3:进入gdb后输入调试代码:
(gdb) l -->显示代码
(gdb) b -->设置断点
(gdb) r 2 2>>temp.foo -->run<
4000
/p>
(gdb) p argv[1] --> 显示结果为 $2 = 0xbffff565 "2"
(gdb) p *argv@2 -->显示数组里的前两个结果 $6 = {0xbffff537 "/home/yuccess/shiyan/apue.3e/fileio/fileflags", 0xbffff565 "2"}
至此我们gdb调试完毕,可以发现 2 是main的第二个参数,而 2>>temp.foo表示将标准输出重定向到temp.foo上(类似于 < /dev/tty),不是一个参数,至于为什么不太清清楚。
感受:gdb调试全键盘的操作,比vs2013、xcode神马的爽爆了啊!
附gdb调试常用命令:
命令 | 描述 |
---|---|
backtrace(或bt) | 查看各级函数调用及参数 |
finish | 连续运行到当前函数返回为止,然后停下来等待命令 |
frame(或f) 帧编号 | 选择栈帧 |
info(或i) locals | 查看当前栈帧局部变量的值 |
list(或l) | 列出源代码,接着上次的位置往下列,每次列10行 |
list 行号 | 列出从第几行开始的源代码 |
list 函数名 | 列出某个函数的源代码 |
next(或n) | 执行下一行语句 |
print(或p) | 打印表达式的值,通过表达式可以修改变量的值或者调用函数 |
quit(或q) | 退出gdb调试环境 |
set var | 修改变量的值 |
start | 开始执行程序,停在main函数第一行语句前面等待命令 |
step(或s) | 执行下一行语句,如果有函数调用则进入到函数中 |
continue 继续运行程序直到下一个断点(类似于VS里的F5)
next 逐过程步进,不会进入子函数(类似VS里的F10)
setp 逐语句步进,会进入子函数(类似VS里的F11)
until 运行至当前语句块结束
finish 运行至函数结束并跳出,并打印函数的返回值(类似VS的Shift+F11)
问题3:下面这句 话的解释if ((val = fcntl(atoi(argv[1]), F_GETFL, 0)) < 0)
首先fcntl()函数的意思是改变/返回一个已经打开文件的属性。
参数F_GETFL说明,该函数要返回文件(第一个参数)的状态标识。
可以调试查看val的结果,如果想显示宏O_ACCMODE的值的话,需要在终端这样输入:gcc
-gdwarf-2 -g3 fileflags.c -l apue -o fileflags
具体细枝末节请参阅APUE 3.14小节
总结:至此已经基本完全理解了该实例,学习了重定向,GDB调试,fcntl等知识,通过调试实践APUE上面的知识,相信对初学linux编程的童鞋会有帮助。
接下来继续啃APUE。
相关文章推荐
- UNIX环境高级编程中的11章程序11-2编译问题---undefined reference to `pthread_create'
- 由unix环境高级编程程序清单8-1fork()引发对缓冲的思考
- 解决unix环境高级编程的第一个程序运行问题
- UNIX环境高级编程程序1-2将标准输入复制到标准输出
- APUE(UNIX环境高级编程)程序架构编译分析(Makefile)
- UNIX 环境高级编程(六)—— 程序和进程
- Unix环境高级编程 程序清单
- UNIX高级环境编程的程序说明
- unix 环境高级编程-1.6-程序和进程
- APUE(UNIX环境高级编程)程序架构编译分析(Makefile)
- unix环境高级编程 FILE I/O笔记
- 读书笔记之UNIX环境高级编程(11)
- unix环境高级编程 FILE I/O笔记
- Unix环境高级编程笔记:11、线程
- UNIX环境高级编程第二版第一个程序运行成功
- UNIX环境C语言编程(11)-高级IO
- Unix高级编程:进程的同步、加载新的程序映像、环境变量
- UNIX环境高级编程第一章程序1-1列出目录文件
- UNIX环境高级编程第二版中编译程序提示“apue.h:找不到这个文件或目录”错误
- unix 环境高级编程 文件对象互斥flockfile()与funlockfile()