雑なメモ書き

気楽にいきます

file descriptorの現在位置とdupなど適当にみた

ファイルをopenしてreadすると、ファイルオフセットは読み込んだバイト数分だけ進められる。 このoffsetは最近だと通常意識しないのだが、故あって気になったので色々試す。

ファイル生成

echo "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa" > tmp
  • 30byte
ls -al tmp
-rw-r--r-- 1 root root 30 Feb 12 15:26 tmp

現在位置の表示

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

int
main(int argc, char *argv[])
{
    int fd,position;
    char buf;
    ssize_t s;

    fd = open("./tmp", O_RDONLY );

    while((s = read(fd, &buf, 1)) > 0){
        position = lseek(fd, 0, SEEK_CUR);
        printf("position:%d\tbuf:%d\tchar:%c\n", position, buf, buf);
    }

    return 0;
}

改行まで含めて30byteが出力される。

position:1   buf:97  char:a
position:2  buf:97  char:a
position:3  buf:97  char:a
position:4  buf:97  char:a
position:5  buf:97  char:a
position:6  buf:97  char:a
position:7  buf:97  char:a
position:8  buf:97  char:a
position:9  buf:97  char:a
position:10 buf:97  char:a
position:11 buf:97  char:a
position:12 buf:97  char:a
position:13 buf:97  char:a
position:14 buf:97  char:a
position:15 buf:97  char:a
position:16 buf:97  char:a
position:17 buf:97  char:a
position:18 buf:97  char:a
position:19 buf:97  char:a
position:20 buf:97  char:a
position:21 buf:97  char:a
position:22 buf:97  char:a
position:23 buf:97  char:a
position:24 buf:97  char:a
position:25 buf:97  char:a
position:26 buf:97  char:a
position:27 buf:97  char:a
position:28 buf:97  char:a
position:29 buf:97  char:a
position:30 buf:10  char:

dupを使う

  • ここからが本題で、dupを使用すると
  • 同一のfileを参照するfdがつくられる
  • 片方のfdからreadをするとdupでつくられたほうもpositionが移動していく
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
    int fd,tmpfd,position;
    char buf;
    ssize_t s;

    fd = open("./tmp", O_RDONLY );

    tmpfd = dup(fd);
    if (tmpfd == -1 && errno != EBADF) {
        exit(1);
    }

    while((s = read(fd, &buf, 1)) > 0){
        position = lseek(fd, 0, SEEK_CUR);
        printf("position:%d\tbuf:%d\tchar:%c\n", position, buf, buf);
        if(position == 7)
            break;
    }

    printf("tmpfd position:%ld\n", lseek(tmpfd, 0, SEEK_CUR));

    return 0;
}
position:1  buf:97 char:a
position:2 buf:97 char:a
position:3 buf:97 char:a
position:4 buf:97 char:a
position:5 buf:97 char:a
position:6 buf:97 char:a
position:7 buf:97 char:a
tmpfd position:7

file descriptorのフラグを見る

  • dupした場合にO_CLOEXECが取られるらしくて見たくてフラグをみる
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>


void printFlags(int);

int
main(int argc, char *argv[])
{
    int fd,tmpfd;
    char buf;
    ssize_t s;

    fd = open("/tmp/xxxxxx", O_CLOEXEC | O_RDWR | O_CREAT | O_TRUNC | O_APPEND, 0644);

    tmpfd = dup(fd);
    if (tmpfd == -1 && errno != EBADF) {
        exit(1);
    }

    printFlags(fd);

    return 0;
}

void
printFlags(int fd)
{
    int flags,accmode;
    flags = fcntl(fd, F_GETFL);
    if(flags == -1) {
        printf("fcntl\n");
        exit(1);
    }

    printf("fd: %d\n",fd);

    accmode = flags & O_ACCMODE;

    printf("\tO_RDONLY:%d\n",accmode == O_RDONLY ? 1 : 0);
    printf("\tO_WRONLY:%d\n",accmode == O_WRONLY ? 1 : 0);
    printf("\tO_RDWR:%d\n",accmode == O_RDWR ? 1 : 0);
    printf("\n");
    printf("\tO_NONBLOCK:%d\n", (flags & O_NONBLOCK) ? 1 : 0);
    printf("\tO_APPEND:%d\n", (flags & O_APPEND) ? 1 : 0);
}