Linux2010.04.20 22:43
예전글인 이녀석
2008/12/22 - [Linux] - 심볼릭 링크에 대한 미스테리
왜 심볼릭 링크의 크기는 파일크기와 문자열 길이가 동일할까? 라는 의문이 들었는데,
not null-terminated 라고 함은, inode 쪽에서 filename 변수를 가지고,
실제로 filename 변수에는 \0(=NULL)이 없기 때문이 아닐까 싶다.

i-node에는 파일의 속성이 저장되고,
디렉토리 구조체에 파일의 i-node와 파일의 이름이 저장된다.
# vi /usr/include/bits/dirent.h
struct dirent
  {
#ifndef __USE_FILE_OFFSET64
    __ino_t d_ino;
    __off_t d_off;
#else
    __ino64_t d_ino;
    __off64_t d_off;
#endif
    unsigned short int d_reclen;
    unsigned char d_type;
    char d_name[256];           /* We must not include limits.h! */
  };

# vi /usr/include/bits/stat.h
struct stat
  {
    __dev_t st_dev;                     /* Device.  */
    unsigned short int __pad1;
#ifndef __USE_FILE_OFFSET64
    __ino_t st_ino;                     /* File serial number.  */
#else
    __ino_t __st_ino;                   /* 32bit file serial number.    */
#endif
    __mode_t st_mode;                   /* File mode.  */
    __nlink_t st_nlink;                 /* Link count.  */
    __uid_t st_uid;                     /* User ID of the file's owner. */
    __gid_t st_gid;                     /* Group ID of the file's group.*/
    __dev_t st_rdev;                    /* Device number, if device.  */
    unsigned short int __pad2;
#ifndef __USE_FILE_OFFSET64
    __off_t st_size;                    /* Size of file, in bytes.  */
#else
    __off64_t st_size;                  /* Size of file, in bytes.  */
#endif
    __blksize_t st_blksize;             /* Optimal block size for I/O.  */

#ifndef __USE_FILE_OFFSET64
    __blkcnt_t st_blocks;               /* Number 512-byte blocks allocated. */
#else
    __blkcnt64_t st_blocks;             /* Number 512-byte blocks allocated. */
#endif
#ifdef __USE_MISC
    /* Nanosecond resolution timestamps are stored in a format
       equivalent to 'struct timespec'.  This is the type used
       whenever possible but the Unix namespace rules do not allow the
       identifier 'timespec' to appear in the  header.
       Therefore we have to handle the use of this header in strictly
       standard-compliant sources special.  */
    struct timespec st_atim;            /* Time of last access.  */
    struct timespec st_mtim;            /* Time of last modification.  */
    struct timespec st_ctim;            /* Time of last status change.  */
# define st_atime st_atim.tv_sec        /* Backward compatibility.  */
# define st_mtime st_mtim.tv_sec
# define st_ctime st_ctim.tv_sec
#else
    __time_t st_atime;                  /* Time of last access.  */
    unsigned long int st_atimensec;     /* Nscecs of last access.  */
    __time_t st_mtime;                  /* Time of last modification.  */
    unsigned long int st_mtimensec;     /* Nsecs of last modification.  */
    __time_t st_ctime;                  /* Time of last status change.  */
    unsigned long int st_ctimensec;     /* Nsecs of last status change.  */
#endif
#ifndef __USE_FILE_OFFSET64
    unsigned long int __unused4;
    unsigned long int __unused5;
#else
    __ino64_t st_ino;                   /* File serial number.  */
#endif
  };

다르게 생각해 보자면,
directory table에 파일 이름이 저장되고, (심볼릭 링크)
속성으로 심볼릭 링크가 지정되며,
inode의 filesize는 string이 아닌 data로서 \0(=NULL)이 빠진 순수한 원본 경로만 들어가서
ls 시의 심볼릭 링크 파일의 크기가 예상과 달리 -1 크기로 나오는게 아닐까 싶다.

#include <unistd.h>
ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize);

Return Value
Upon successful completion, readlink() shall return the count of bytes placed in the buffer. Otherwise, it shall return a value of -1, leave the buffer unchanged, and set errno to indicate the error.

[링크 : http://linux.die.net/man/3/readlink]

The readlink function gets the value of the symbolic link filename. The file name that the link points to is copied into buffer. This file name string is not null-terminated; readlink normally returns the number of characters copied. The size argument specifies the maximum number of characters to copy, usually the allocation size of buffer.

[링크 : http://www.gnu.org/s/libc/manual/html_node/Symbolic-Links.html]

APPLICATION USAGE
    Conforming applications should not assume that the returned contents of the symbolic link are null-terminated.

RATIONALE
    Since IEEE Std 1003.1-2001 does not require any association of file times with symbolic links, there is no requirement that file times be updated by readlink(). The type associated with bufsiz is a size_t in order to be consistent with both the ISO C standard and the definition of read(). The behavior specified for readlink() when bufsiz is zero represents historical practice. For this case, the standard developers considered a change whereby readlink() would return the number of non-null bytes contained in the symbolic link with the buffer buf remaining unchanged; however, since the stat structure member st_size value can be used to determine the size of buffer necessary to contain the contents of the symbolic link as returned by readlink(), this proposal was rejected, and the historical practice retained.

[링크 : http://www.opengroup.org/onlinepubs/000095399/functions/readlink.html]

신고

'Linux' 카테고리의 다른 글

ubuntu 9.10 에서 APM + viewvc + cvsgraph 돌리기  (0) 2010.04.28
enscript  (0) 2010.04.28
readlink() 와 심볼릭 링크, 그리고 inode(아이노드)  (0) 2010.04.20
pwd(getcwd), cd(chdir)  (4) 2010.04.19
wget  (4) 2010.04.10
/dev의 major minor에 대하여  (0) 2010.04.08
Posted by 구차니

댓글을 달아 주세요

Linux2009.11.18 16:03
if [ -f filename] 으로 파일의 유무를 확인할 수 있다.
물론 그 파일이 존재한다 하더라도 깨어진 심볼릭 링크라면 없는 파일로 나온다.
.. 당연한건가?

$ cat broken_link.sh
#/bin/sh
if [ -f test ]
then
        echo test exist
else
        echo test not exist
fi

$ ls -al
total 60
-r-xr-xr-x 1 morpheuz dev   71 Nov 18 15:37 broken_link.sh
lrwxrwxrwx 1 morpheuz dev    2 Nov 18 15:36 test -> tt

$ ./broken_link.sh
test not exist

$ touch tt
$ ls -al
total 60
-r-xr-xr-x 1 morpheuz dev   71 Nov 18 15:37 broken_link.sh
lrwxrwxrwx 1 morpheuz dev    2 Nov 18 15:36 test -> tt
-rw-rw-r-- 1 morpheuz dev    0 Nov 18 15:40 tt

$ ./broken_link.sh
test exist

[링크 : http://freeos.com/guides/lsst/ch03sec02.html]
신고
Posted by 구차니

댓글을 달아 주세요

Linux2008.12.22 12:02
-rwxr-xr-x 1 root root   76400 Jul  5  2007 libresolv-2.5.so
lrwxrwxrwx 1 root root      16 Apr 11  2008 libresolv.so.2 -> libresolv-2.5.so
-rwxr-xr-x 1 root root   44060 Jul  5  2007 librt-2.5.so
lrwxrwxrwx 1 root root      12 Apr 11  2008 librt.so.1 -> librt-2.5.so

심볼릭 링크를 보는데 의구심이 생겼다.

1. 어떻게 심볼릭 링크는 저장이 되는지
2. libresolv-2.5.so면 16글자인데, 그럼 null 포함하면 17byte인데 왜 파일 사이즈가 16인가?

/usr/share/file/magic 파일을 보면
 9280 # lnk files windows symlinks
 9281 0       string  \114\000\000\000\001\024\002\000\000\000\000\000\300\000\000\000\000\000\000\106        MS Windows shortcut
 라는 내용이 있는데, file 하면 나오는

lrwxrwxrwx  1 morpheuz dev      7 Dec 22 11:47 tt -> err.log
[morpheuz@dev stbmw]$ file tt
tt: symbolic link to `err.log'

file 결과에서 나온 "symbolic link t"o 라는 메시지는 magic 파일에서 검색되지 않는다.

그리고 readlink() / readlink 라는 녀석도 존재 하는데
이녀석이 심볼릭 링크의 실제 내용을 읽어 주는 녀석이라고 한다.
READLINK(1)                      User Commands                     READLINK(1)

NAME
       readlink - display value of a symbolic link

SYNOPSIS
       readlink [OPTION]... FILE

DESCRIPTION
       Display value of a symbolic link on standard output.

       -f, --canonicalize
              canonicalize  by  following every symlink in every component of the given name recursively; all but the
              last component must exist

       -e, --canonicalize-existing
              canonicalize by following every symlink in every component of the given name  recursively,  all  compo-
              nents must exist

       -m, --canonicalize-missing
              canonicalize  by  following  every  symlink  in  every component of the given name recursively, without
              requirements on components existence

       -n, --no-newline
              do not output the trailing newline

       -q, --quiet,

       -s, --silent
              suppress most error messages

       -v, --verbose
              report error messages

       --help display this help and exit

       --version
              output version information and exit
근데.. 해보니 머.. ls -l 이랑 별 차이도 없는데 -ㅁ-!
신고
Posted by 구차니

댓글을 달아 주세요

  1. 저런 사소한곳까지 관심을 가지시는군요 -_-;;;;

    저는 그냥... 아 심볼링 링크구나.. 하고 지나쳐버리는...

    2008.12.22 18:52 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • 그 멘트를 두번재 보는건가요 ㅎㅎ
      사소하면서도 어쩌면 참 중요한 내용일꺼 같아서 한번 파헤쳐 보고 있답니다. 솔찍히 학교에서도 아쉬웠던게 이렇게 속시원하게 파주지를 않더라구요 ㅎ

      2008.12.22 18:57 신고 [ ADDR : EDIT/ DEL ]
  2. 학교는 말 그대로 학교더라구요. -_-;
    수박의 겉모양이 어떻게 생겼는지는 알려주는데,

    그 속이 빨갛고 그 안에 까만 씨가 있다는 것은 스스로 알아내야 하는....

    그래서 스스로 노력하지 않으면 수박이라는 열매는 그냥 초록색 과일이겠거니 하고 생각하고 말게되는..

    2008.12.23 10:07 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • 그래도 학교에서 한번쯤은 수박씨를 심어 키우고 쪼개서 먹는 과정까지는 해주면 좋겠다는 생각이 들더라구요. 공부가 아닌 학습/암기만 강요하는 현재 교육 시스템에 문제도 있긴하지만, "왜?" 라는 의문을 가지지 않고 쉽게 점수를 따기 위해(외우는게 쉬운건 아니지만) 학습을 하는 모습은 참 안타깝기만 하더군요. 머.. 학점이 안나와서 대충 살아 가는 제가 할말은 아니지만 말이죠 ^^;

      2008.12.23 10:25 신고 [ ADDR : EDIT/ DEL ]