fcntl() 함수에 대한 질문..

betterlife의 이미지

안녕하세요.
fcntl() 함수를 공부하다가 이해가 안되는 부분이 있어서...
file_status 에 분명히 아래와 같이 초기값을 줬는데 왜 결과가
다르게 나오는지 잘 모르겠습니다. 컴파일 가능한 짧은 소스를
올립니다.

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

static void check_file( int );

static int file_status = O_RDONLY | O_CREAT | O_TRUNC;

int main( void )
{
    int fd;

    fd = open( "fcntl_test.temp", file_status, 00644 );

    check_file( fd );

    return 0;
}

static void check_file( int fd )
{
    int stat_flags, access_flag;

    stat_flags = fcntl( fd, F_GETFL, 0 );

    access_flag = stat_flags & O_ACCMODE;

    if ( access_flag == O_RDONLY )
        printf( "O_RDONLY" );
    else if ( access_flag == O_WRONLY )
        printf( "O_WRONLY" );
    else if ( access_flag == O_RDWR )
        printf( "O_RDWR" );
    else
        printf( "unknown acess flag\n" );

    if ( stat_flags & O_CREAT )
        printf( " | O_CREAT " );

    if ( stat_flags & O_EXCL )
        printf( " | O_EXCL " );

    if ( stat_flags & O_TRUNC )
        printf( " | O_TRUNC" );

    if ( stat_flags & O_APPEND )
        printf( " | O_APPEND" );

    if ( stat_flags & O_NONBLOCK )
        printf( " | O_NONBLOCK" );

    printf( "\n" );
}

제 생각에 따르면 O_CREAT 와 O_TRUNC 도 출력이 되야되는데
출력이 안됩니다. O_RDONLY 만 출력이 됩니다. 이 소스는
제가 공부하고 있는 책에 있는겁니다. 그런데 책에 나온 출력을
보면 O_RDONLY 만 출력이 되어 있습니다. O_RDONLY 만 출력
되는것이 맞는거 같은데 왜 그런지를 모르겠습니다. 초기값에는
3개를 줬는데 왜 한개만 나오는지.... 알려주시면 감사드리겠습니
다. 읽어주셔서 감사합니다.
========================================
T_T.. os 가 다르면 결과도 다른것일까요? 저는 레드햇9를 쓰고
있고 책에는 SunOS와 HP-UX 의 결과값으로 O_RDONLY 만
나와 있습니다...
익명 사용자의 이미지

3개 다 나오는데요??

wariua의 이미지

저는 O_RDONLY만 나옵니다. 왜 그런가 하는 것에 대한 답은 O_ACCMODE의 정의와 설명에 나와 있습니다. /usr/include/fcntl.h를 따라서 /usr/include/bits/fcntl.h를 열어 보면 플래그들이 정의되어 있는데,

#define O_ACCMODE          0003
#define O_RDONLY             00
#define O_WRONLY             01
#define O_RDWR               02
#define O_CREAT            0100 /* not fcntl */
#define O_EXCL             0200 /* not fcntl */
#define O_NOCTTY           0400 /* not fcntl */
#define O_TRUNC           01000 /* not fcntl */
#define O_APPEND          02000
...

라고 되어 있습니다. 인즉 O_ACCMODE는 '읽기-쓰기-둘다'라는 접근 방식만을 다루는 마스크입니다. 이는 fcntl.h에 대한 man페이지에서도 확인하실 수 있습니다.
Quote:
The following values are file creation flags and are used in the oflag values to open(). They shall be bitwise-distinct.

O_CREAT ...
O_EXCL ...
O_NOCTTY ...
O_TRUNC ...

...

Mask for use with file access modes is as follows:

O_ACCMODE
Mask for file access modes.

File access modes used for open() and fcntl() are as follows:

O_RDONLY ...
O_RDWR ...
O_WRONLY ...


달리 생각을 해보자면 O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC 플래그는 파일을 여는 방식을 지정하는 플래그일 뿐, 열려있는 파일의 속성과는 관련이 없습니다. 그러니 일단 파일이 열리고 나면 의미가 없어지는 플래그이기에 fcntl(F_GETFL)로 얻어올 수 없다고 생각할 수도 있습니다.

$PWD `date`

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.