通常,进行嵌入式开发的时候,调试信息都是通过串口来输出的,但是有时候某些问题必须到特定的现场才能重现,客户不一定有配套的串口线,或者根本没用过诸如SecureCRT这类的工具,你还得寄串口线,写个文档让他帮你抓log,还要人家原意,不过有其他更大众的方法,就是把log信息写入到u盘里的一个文件,通常我们信息的输出都是用printf函数,这里不考虑标准输入,标准输出,标准出错,反正都用printf输出到标准输出,原来这些都是通过串口输出的,现在要输出到文件里面,那么一种方法是直接对printf函数原型进行修改,不过有时候它是一个库,那就得采用别的变通方法:
1 fd = open("./logfile", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); 2 if ( fd < 0 ) 3 { 4 perror("open"); 5 return -1; 6 } 7 8 newfd = dup2(fd, STDOUT_FILENO); 9 if ( newfd < 0 ) 10 { 11 perror("dup2"); 12 close(fd); 13 } 14 printf("set a log ");
fflush(NULL); //由于newfd的输出由终端变成了文件(磁盘),IO的缓存机制也由行缓存变成了块缓存,因此需要刷一下缓存,否则内容可能还未写入文件,进程就已退出 15 close(fd);
dup2函数:
dup2() makes newfd be the copy of oldfd, closing newfd first if necessary, but note the following:
* If oldfd is not a valid file descriptor, then the call fails, and newfd is not closed.
* If oldfd is a valid file descriptor, and newfd has the same value as oldfd, then dup2() does nothing, and returns newfd.
使用newfd复制oldfd
这样操作之后,所有printf操作将输入到logfile这个文件里面,或者:
1 fd = open("./logfile", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); 2 if ( fd < 0 ) 3 { 4 perror("open"); 5 return -1; 6 } 7 8 close( STDOUT_FILENO); 9 newfd = dup( fd); 10 if ( newfd < 0 ) 11 { 12 perror("dup"); 13 close(fd); 14 }
fflush(NULL); //由于newfd的输出由终端变成了文件(磁盘),IO的缓存机制也由行缓存变成了块缓存,因此需要刷一下缓存,否则内容可能还未写入文件,进程就已退出
15 close(fd);
dup函数:
dup(oldfd) uses the lowest-numbered unused descriptor for the new descriptor.使用未用的最小fd来复制oldfd
或者:
1 fd = open("./logfile", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); 2 if ( fd < 0 ) 3 { 4 perror("open"); 5 return -1; 6 } 7 8 close(STDOUT_FILENO); 9 newfd = fcntl(fd, F_DUPFD, STDOUT_FILENO); 10 if ( newfd != STDOUT_FILENO ) 11 { 12 printf("not replace "); 13 return -1; 14 } 15
fflush(NULL); //由于newfd的输出由终端变成了文件(磁盘),IO的缓存机制也由行缓存变成了块缓存,因此需要刷一下缓存,否则内容可能还未写入文件,进程就已退出
16 close(fd);
使用最小的大于或等于第三个参数的fd来复制第一个参数
三者区分和注意还未总结,以后补充。