10.28.2015

Linux C dup2()

這一次要記下來的東西,個人認為,在學習的過程中,的確是有一點點的難度。因為它不單單只是Pipe的觀念而已,還有對檔案描述子 (FD)的認知。

這個學習心得,牽扯到fork(), pipe(), dup2(), dup(), FD的觀念,我很難在Blog中一字一句描述地很清楚。程式碼只是留給自己的學習紀錄而已。

功能說明:複製FD。

標頭檔:#include <unistd.h>

函式宣告:int dup2(int oldfd, int newfd);

函式說明:dup2()用來複製引數oldfd所指的FD,並將它拷貝到引數newfd后一塊傳回。若引數newfd為一已開啟的FD,則newfd所指的檔案會先被關閉。dup2()所複製的FD,與原來的FD共享各種檔案狀態。

回傳值:當複製成功時,則傳回最小及尚未使用的FD;若有錯誤則傳回-1。

範例:
// dup2.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>

int 
main()
{
    pid_t pid = 1;
    int fd[2], nRet = 0;
    char szSend[16], szRecv[32];

    bzero((void *)&fd, sizeof(int) * 2);
    if (pipe(fd) != 0) {
        perror("Create pipe() failed (error)!! \n");
        exit(EXIT_FAILURE);
    }
//  printf("fd[0] = %d; fd[1] = %d \n", fd[0], fd[1]);
    memset(&szSend, '\0', sizeof(char) * 16);
    pid = fork();
    if (pid == 0) {
        close(STDIN_FILENO);

        dup2(fd[1], STDOUT_FILENO);
        close(fd[0]);
        close(fd[1]);

        strcpy(szSend, "Hello!! ");
        write(STDOUT_FILENO, (void *)szSend, strlen(szSend));
        exit(EXIT_SUCCESS);
    }
    waitpid(0, &nRet, 0);

    dup2(fd[0], STDIN_FILENO);
//  close(STDOUT_FILENO); // Don't close it!!
    close(fd[0]);
    close(fd[1]);

    memset(&szRecv, '\0', sizeof(char) * 32);
    read(STDIN_FILENO, (void *)szRecv, sizeof(char) * 32);
    strcat(szRecv, "World!! ");
    printf("szRecv: %s (%d) \n", szRecv, strlen(szRecv));
 
    return 0;
}
執行結果:

[root@localhost ~]# ./dup2
szRecv: Hello!! World!! (16)
[root@localhost ~]#

沒有留言:

張貼留言