dup 和dup2

2019-05-08  本文已影响0人  perryn

dup

dup2

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define FILE_NAME "/tmp/out"
static void redirect_stdout_without_dup() {
  fprintf(stdout, "pid=%d\n", getpid());
  const char *str = "my dup\n";
  //关闭 stdout
  close(1);
  //当前process中描述符表中最小可用的下标是1,因为刚刚关闭
  int fd = open(FILE_NAME, O_RDWR | O_CREAT | O_TRUNC, 0666);
  if (fd > 0) {
    // stdout 在每个进程描述表中的下标为1
    //此时,数据是写到了刚刚打开的fd中,新打开的fd返回的是1
    fprintf(stdout, " open fd=%d\n", fd);
    // write 操作也是写到fd=1中,当前进程中文件描述符为1的并不是标准输出
    write(fd, str, strlen(str));
    close(1);
  }
}

static void redirect_stdout_with_dup() {
  fprintf(stdout, "pid=%d\n", getpid());
  const char *str = "my dup";
  //默认打开fd,在当前进程描述表中fd并不是{0,1,2}
  int fd = open(FILE_NAME, O_RDWR | O_CREAT | O_TRUNC, 0666);
  if (fd > 0) {
    //关闭标准的输出的文件描述符
    close(1);
    //拷贝fd到当前进程描述符中最小的下标位置,当前最小的下标应该是刚刚关闭的1
    dup(fd);
    // fprintf的内容写入到了fd中,并没有写入到标准输出中
    fprintf(stdout, " open fd=%d\n", fd);
    write(fd, str, strlen(str));
    //关闭当前文件描述符
    close(fd);
  }
}
static void redirect_stdout_with_dup2() {
  fprintf(stdout, "pid=%d\n", getpid());
  const char *str = "i'm dup2\n";
  //打开一个新的文件描述符
  int fd = open(FILE_NAME, O_RDWR | O_CREAT | O_TRUNC, 0666);
  if (fd > 0) {
    //如果1号文件描述符是打开状态,就关闭1号文件描述符
    //把当前进程中文件描述符表中下标为fd的指针拷贝下标为1的空间
    //如果fd==1就直接返回fd
    dup2(fd, 1); // equals: close(1) and dup(fd)
    // fd和1号文件描述符指向相同的文件结构体指针
    fprintf(stdout, "%d already redirect to stdout\n", fd);
    write(fd, str, strlen(str));
    //刷盘操作
    if (fd != 1) {
      close(fd);
    }
  }
}
int main(void) {
  /*
redirect_stdout_without_dup();
redirect_stdout_with_dup();
*/
  redirect_stdout_with_dup2();
  for (;;) {
    sleep(1);
  }
  return 0;
}
image.png

结论

上一篇 下一篇

猜你喜欢

热点阅读