Unix环境高级编程学习笔记(一)
时间:2011-01-11 来源:巢北

#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#define MAXLINE 3
int
main(void)
{
char buf[MAXLINE];
pid_t pid;
int status;
printf("%% ");
while(fgets(buf, MAXLINE, stdin) != NULL)
{
int i;
for(i = 0; i<strlen(buf); i++)
printf("%c",buf[i]);
printf("Done");
if(buf[strlen(buf) -1] == '\n')
{
buf[strlen(buf)-1] = 0;
printf("Test %c",buf[strlen(buf)-1]);
}
if((pid = fork()) < 0)
{
printf("fork error\n");
}
else if(pid == 0)
{
printf("The current buf is %s", buf);
execlp(buf, buf, (char *)0);
}
if((pid = waitpid(pid, &status, 0)) < 0)
printf("waitpid error");
printf("%% ");
}
exit(0);
}
分析过程:
(gdb) b main
Breakpoint 1 at 0x80485be: file 1-5.c, line 14.
(gdb) r 1-5
Starting program: /home/helei/UnixProgram/1-5 1-5
Breakpoint 1, main () at 1-5.c:14
14 printf("%% ");
(gdb) n
15 while(fgets(buf, MAXLINE, stdin) != NULL)
(gdb) n
% pwd
18 for(i = 0; i<strlen(buf); i++)
(gdb) n
19 printf("%c",buf[i]);
(gdb) watch buf[i]
Hardware watchpoint 2: buf[i]
(gdb) watch i
Hardware watchpoint 3: i
(gdb) n
18 for(i = 0; i<strlen(buf); i++)
(gdb) n
Hardware watchpoint 2: buf[i]
Old value = 112 'p'
New value = 119 'w'
Hardware watchpoint 3: i
Old value = 0
New value = 1
0x080485f3 in main () at 1-5.c:18
18 for(i = 0; i<strlen(buf); i++)
(gdb) n
19 printf("%c",buf[i]);
(gdb) n
18 for(i = 0; i<strlen(buf); i++)
(gdb) n
Hardware watchpoint 2: buf[i]
Old value = 119 'w'
New value = 0 '\000'
Hardware watchpoint 3: i
Old value = 1
New value = 2
0x080485f3 in main () at 1-5.c:18
18 for(i = 0; i<strlen(buf); i++)
(gdb) n
20 printf("Done");
(gdb) n
21 if(buf[strlen(buf) -1] == '\n')
(gdb) n
26 if((pid = fork()) < 0)
(gdb) n
30 else if(pid == 0)
(gdb) n
36 if((pid = waitpid(pid, &status, 0)) < 0)
(gdb) n
38 printf("%% ");
(gdb) n
15 while(fgets(buf, MAXLINE, stdin) != NULL)
(gdb) n
18 for(i = 0; i<strlen(buf); i++)
(gdb) n
Hardware watchpoint 2: buf[i]
Old value = 0 '\000'
New value = 100 'd'
Hardware watchpoint 3: i
Old value = 2
New value = 0
0x080485d8 in main () at 1-5.c:18
18 for(i = 0; i<strlen(buf); i++)
(gdb) n
19 printf("%c",buf[i]);
(gdb) n
18 for(i = 0; i<strlen(buf); i++)
(gdb) n
Hardware watchpoint 2: buf[i]
Old value = 100 'd'
New value = 10 '\n'
Hardware watchpoint 3: i
Old value = 0
New value = 1
0x080485f3 in main () at 1-5.c:18
18 for(i = 0; i<strlen(buf); i++)
(gdb) n
19 printf("%c",buf[i]);
(gdb) n
pwDone% d
18 for(i = 0; i<strlen(buf); i++)
(gdb) n
Hardware watchpoint 2: buf[i]
Old value = 10 '\n'
New value = 0 '\000'
Hardware watchpoint 3: i
Old value = 1
New value = 2
0x080485f3 in main () at 1-5.c:18
18 for(i = 0; i<strlen(buf); i++)
(gdb) n
20 printf("Done");
(gdb) n
21 if(buf[strlen(buf) -1] == '\n')
(gdb) n
23 buf[strlen(buf)-1] = 0;
(gdb) n
24 printf("Test %c",buf[strlen(buf)-1]);
(gdb) n
26 if((pid = fork()) < 0)
(gdb) n
DoneTest dThe current buf is dwaitpid error% 30 else if(pid == 0)
结论:
(1)fget函数在已达到文件结尾或出错时返回NULL;
(2)若缓冲区不能足够容纳读入的一行,则缓冲区存储的是不完整的行,且以null字符结尾;
(3)输入的行未读完,剩余部分再从头写缓冲区,将覆盖原来的内容;
(4)读完最后一个字符\n后,再填null字符。
还未想明白的地方:
(1)在第一次写缓冲区和第二次写的间隔,子进程部分为何不执行(如调试部分加粗标记),求看官指点。