做嵌入式开发时将标准输出输入到一个文件的一种方法

    通常,进行嵌入式开发的时候,调试信息都是通过串口来输出的,但是有时候某些问题必须到特定的现场才能重现,客户不一定有配套的串口线,或者根本没用过诸如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来复制第一个参数

三者区分和注意还未总结,以后补充。

原文地址:https://www.cnblogs.com/thammer/p/4964134.html