2011. 10. 23. 23:07

◎ 시스템들은 한계들(Lmists)을 다음과 같이 세 종류로 분류:

1. 컴파일 시점 한계들 (헤더)

2. 파일이나 디렉터리와는 무관한 실행시점 한계들(sysconf 함수)

3. 파일이나 디렉터리와 연관된 실행시점 한계들(pathconf, fpathconf 함수)

 

◎ Compile-time limits (헤더):

ISO C Limits : <limits.h> <stdio.h>

POSIX Limits : 일부<limits.h>-><bits/posix1_lim.h>,<bits/posix2_lim.h>

XSI Limits : 일부 <limits.h>-><bits/xopen_lim.h>

(우분투 kernel 3.0.x는 </usr/include/i386-linux-gnu/bits/*lim.h>에 정의)

 

◎ Runtime limits

특정한 시스템이 실제로 지원하는 한계를 알아내려면 일부는 컴파일 시점에서 알 수 있으나

어떤 것들은 반드시 실행시점에서 파악해야 한다. 또한 어떤 한계들은 주어진 한 시스템에서

변하지 않지만, 파일이나 디렉터리에 연관된 일부 한계들은 상황에 따라 변한다.

실행시점 한계들을 알고자 할 때 사용할 수 있는 함수들은 다음 세 가지이다.

#include <unistd.h>

long sysconf(int *name);

long pathconf(char *pathname, int name);

long fpathconf(int *filedes, int name);

 

all three return: 성공 해당 , 오류 -1.

name 인수에 적절한 상수가 지정되지 않으면 -1, errno EINVAL 설정.

ㆍ미결정인 한계의 경우 -1 반환되나 errno 설정하지 않음.

@ pathconf, fpathconf 두 함수는 기능은 동일하되,

하나는 pathname(경로명) 이며, 하나는 filedes(파일 디스크립터)를 받는다는 점에서 구별.

@ name : sysconf는 _SC_*로 시작, (f)pathconf는 _PC_*로 시작.

 

[ sysconf로 얻을 수 있는 한계들과 그에 해당하는 name 인수 값]

name argument

Description

_SC_ARG_MAX

exec* 함수들에 대한 인수들의 최대 길이 (바이트 단위)

_SC_ATEXIT_MAX

atexit 함수로 등록할 수 있는 함수들의 최대 개수

_SC_CHILD_MAX

실제 사용자 ID당 자식 프로세스 개수

_SC_CLK_TCK

1초 동안의 클록 틱 개수

_SC_COLL_WEIGHTS_MAX

로케일 정의 파일의 LC_COLLATE 순서 키워드의 한 항목에

배정할 수 있는 가중치들의 최대 개수

_SC_HOST_NAME_MAX

gethostname이 돌려주는 호스트 이름의 최대 길이

_SC_IOV_MAX

readv or writev에 사용할 수 있는 iovec 구조체의 최대 개수

_SC_LINE_MAX

utility의 입력 라인의 최대 길이

_SC_LOGIN_NAME_MAX

login 이름의 최대 길이

_SC_NGROUPS_MAX

프로세스당 동시적인 추가 그룹 ID 최대 개수

_SC_OPEN_MAX

프로세스당 열린 파일 최대 개수

_SC_PAGESIZE

시스템 메모리 페이지 크기(바이트 단위)

_SC_PAGE_SIZE

시스템 메모리 페이지 크기(바이트 단위)

_SC_RE_DUP_MAX

regexec 함수와 regcomp 함수에 구간 표기 \{m,n\}를 사용할 때

허용되는, 기본 정규표현식 안의 반복된 출현 횟수

_SC_STREAM_MAX

프로세스가 동시에 열어둘 수 있는 표준 I/O 스트림 최대 개수

(FOPEN_MAX와 같아야 함)

_SC_SYMLOOP_MAX

경로이름 해소 도중 운행될 수 있는 심볼릭 링크 개수

_SC_TTY_NAME_MAX

터미널 장치 이름의 길이(종료 널 문자 포함)

_SC_TZNAME_MAX

시간대 이름의 최대 바이트 수

 

[ (f)pathconf로 얻을 수 있는 한계들과 그에 해당하는 name 인수 값 ]

name argument

Description

_PC_FILESIZEBITS

지정된 디렉터리에 존재할 수 있는 정규 파일의 최대 크기를 하나의

부호 있는 정수 값으로 나타내는 데 필요한 최소 비트 수

_PC_LINK_MAX

파일의 최대 링크 개수

_PC_MAX_CANON

터미널의 표준 입력 대기열의 최대 바이트 수

_PC_MAX_INPUT

터미널의 입력 대기열에 사용할 수 있는 공간의 최대 바이트 수

_PC_NAME_MAX

파일이름의 최대 바이트 수(종료 널 문자는 뺀)

_PC_PATH_MAX

상대 경로이름의 최대 바이트 수(종료 널 문자 포함)

_PC_PIPE_BUF

파이프에 원자적으로 기록될 수 있는 최대 바이트 수

_PC_SYMLINK_MA

심볼릭 링크의 최대 바이트 수

 

@ (f)pathconf 인수인 pathnamefiledes 인수의 제약 사항. (제약 위반 시 결과는 정의되지 않음)

▶ _PC_MAX_CANON과 _PC_MAX_INPUT에 대해 지정된 파일은 반드시 터미널 파일이어야 함.

▶ _PC_LINK_MAX에 대해 지정된 파일이 디렉터리이면 반환 값은 그 디렉터리 안의 파일이름 항목들이

아니라 디렉터리 자체에 대한 것이다.

▶ _PC_FILESIZEBITS와 _PC_NAME_MAX에 대해 지정된 파일은 반드시 디렉터리이어야 한다.

반환값은 그 디렉터리 안의 파일이름들에 대한 것이다.

▶ PC_PATH_MAX에 대해 지정된 파일은 반드시 디렉터리이어야 한다.

반환값은 지정된 디렉터리가 작업 디렉터리일 때의 상대 경로이름의 최대 길이이다.

(안타깝게도 이 값이 우리가 알고자 하는 절대 경로 이름의 실제 최대 길이는 아니다.)

▶ _PC_PIPE_BUF에 대해 지정된 파일은 반드시 파이프, FIFO, 디렉터리이어야 한다.

파이프나 FIFO의 경우 반환값은 지정된 파이프 또는 FIFO에 대한 한계이고, 디렉터리의 경우 반환값은

그 디렉터리안에 생성된 임의의 FIFO에 대한 한계이다.

▶ _PC_SYMLINK_MAX에 대해 지정된 파일은 반드시 디렉터리이어야 한다.

반환값은 그 디렉터리 안의 심볼릭 링크가 담을 수 있는 문자열의 최대 길이이다.

 

Posted by devanix
2011. 10. 23. 16:29

#include <sys/types.h>

#include <utime.h>

int utime(const char *filename, const struct utimbuf *times);

 

반환값: 성공 0, 실패 -1(errno 설정)

@filename: 변경할 파일 이름

@times :

- NULL이면 접근 시간과 수정 시간 모두 현재 시간으로 설정.

(유효 사용자 ID가 파일의 소유자 ID와 같거나, 프로세스가 파일에 대해 쓰기 권한 필요)

- NULL이 아니면 접근 시간과 수정 시간이 times가 가리키는 구조체에 있는 값들로 설정.

(유효 사용자 ID가 파일의 소유자 ID와 같거나, 프로세스가 슈퍼 사용자 프로세스여야 함)

 

utimbuf 구조체:

struct utimbuf {

    time_t actime;

    time_t modtime;

}

 

/* access time */

/* modification time */

※ 구조체에 상태 변경 시간(st_ctime, i노드가 마지막으로 변경된 시간)에 대한 필드가 없는 것은

utime 함수가 호출되면 어차피 자동으로 갱신되기 때문이다.

 

[ Example ]

/data/workspace/linux-src/example/file/zap.c.html
 
/* zap.c 
 * 
 * O_TRUNC를 지정한 open을 이용해서 주어진 파일들의 
 * 크기를 0으로 줄이되, 파일들의 접근 시간이나 수정 
 * 시간은 변경하지 않는다. 이를 위해 프로그램은 우선 
 * stat 함수로 시간들을 얻고, 파일을 크기 0으로 자르고, 
 * utime 함수로 시간들을 복원한다. 
 */ 
#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <utime.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <errno.h> 
 
int main(int argc, char *argv[]) {
    int	i, fd;
    struct stat	    statbuf;
    struct utimbuf  timebuf;
 
    if (argc < 2) {
	fprintf(stderr, "Usage: %s <files>...\n", argv[0]);
	return 0;
    }
 
    for (i=1; i<argc; i++) {
	/* 현재 시간을 얻는다 */ 
	if (stat(argv[i], &statbuf) < 0) {
	    fprintf(stderr, "%s: state error: %s\n",
		    argv[i], strerror(errno));
	    continue;
	}
	/* 크기를 0으로 자른다 */ 
	if ((fd = open(argv[i], O_RDWR | O_TRUNC)) < 0) {
	    fprintf(stderr, "%s: open error: %s\n",
		    argv[i], strerror(errno));
	    continue;
	}
	close(fd);
	/* 시간들을 복원한다 */ 
	timebuf.actime	= statbuf.st_atime;
	timebuf.modtime	= statbuf.st_mtime;
	if (utime(argv[1], &timebuf) < 0) {
	    fprintf(stderr, "%s: utime error: %s\n",
		    argv[i], strerror(errno));
	    continue;
	}
    }
 
    return 0;
}

[실행 ]

$ ls -l changemod times           크기와 최종 수정 시간 확인

     -rwxrwxr-x 1 sar   15019   Nov  18  18:53  changemod

     -rwxrwxr-x 1 sar   16172   Nov  19  20:05  times

$ ls -lu changemod times           최종 접근 시간 확인

     -rwxrwxr-x 1 sar   15019   Nov  18  18:53  changemod

     -rwxrwxr-x 1 sar   16172   Nov  19  20:05  times

 

$ date                            print today's date

     Thu Jan 22 06:55:17 EST 2004

 

$ ./zap changemod times         예제 실행

$ ls -l changemod times           and check the results

     -rwxrwxr-x 1 sar        0  Nov  18  18:53  changemod

     -rwxrwxr-x 1 sar        0  Nov  19  20:05  times

$ ls -lu changemod times          최종 접근 시간 확인

     -rwxrwxr-x 1 sar        0  Nov  18  18:53  changemod

     -rwxrwxr-x 1 sar        0  Nov  19  20:05  times

$ ls -lc changemod times          상태 변경 시간을 확인

     -rwxrwxr-x 1 sar        0  Jan  22  06:55  changemod

     -rwxrwxr-x 1 sar        0  Jan  22  06:55  times

최종 수정 시간과 최종 접근 시간이 변경되지 않았다.

그러나 상태 변경 시간은 프로그램을 실행한 시간으로 바뀌었다.

Posted by devanix
2011. 10. 23. 16:29

각 파일마다 세 개의 시간 필드들이 커널에 의해 관리 된다.

 

[각 파일에 연관된 세 가지 시간 값들]

Field

Description

Example

ls(1) option

st_atime

last-access time of file data

read, exec

-u

st_mtime

last-modification time of file data

write, truncate

default

st_ctime

last-change time of i-node status

chmod, chown

-c

 

@ 파일수정시간과 상태 변경 시간의 차이를 주의:

• 파일 수정 시간(st_mtime) : 파일의 내용이 마지막으로 수정된 시간.

• 상태 변경 시간(st_ctime) : 파일의 i노드가 마지막으로 수정된 시간.

i노드의 모든 정보는 파일의 실제 내용과는 개별적으로 저장되기 때문에,

파일 수정 시간뿐만 아니라 상태 변경 시간(changed-status time)도 따로

유지할 필요가 있다. (내용이 변경된 파일 또는 i노드가 수정된 파일들만 따로 보관할 때 유용)

 

[여러 함수들의 파일 접근 시간, 수정 시간, 상태 변경 시간 갱신 여부]

Function

참조된 파일 or

디렉터리

참조된 파일 or

디렉터리의

부모 디렉터리

Note

a

m

c

a

m

c

chmod, fchmod

   

     

  

chown, fchown

   

     

  

creat

 

O_CREAT new file

creat

 

     

O_TRUNC existing file

exec

         

  

lchown

   

     

  

link

   

 

둘째 인수의 부모

mkdir

 

  

mkfifo

 

  

open

 

O_CREAT new file

open

 

     

O_TRUNC existing file

pipe

     

  

read

         

  

remove

   

 

파일 제거 = unlink

remove

       

디렉토리 제거 = rmdir

rename

   

 

for both arguments

rmdir

       

  

truncate, ftruncate

 

     

  

unlink

   

 

  

utime

     

  

write

 

     

  

touch(1)

 

새로운 파일 생성

touch(1)

     

기존 파일 업데이트

※ 디렉터리에 연관된 그 부모 디렉터리에 연관된 세 시간 값들까지 나와 있는 것은

디렉터리 항목들을 추가, 삭제, 수정하면 그 디렉터리에 연관된 세 시간 값들이 변할 수 있다.

디렉터리라는 것은 단지 디렉터리 항목(파일이름과 해당 i노드 번호)들을 담은 파일 뿐이다.

 

Posted by devanix
2011. 10. 23. 16:22

[ Summary of File Access Permission Bits ]

상수

설명

정규 파일에 대한 효과

디렉터리에 대한 효과

S_ISUID

SUID

실행 시 유효 사용자 ID를 설정

(not used)

S_ISGID

SGID

그룹 실행 비트가 설정되어 있으면

실행 시 유효 그룹 ID를 설정.

그렇지 않으면 필수 레코드 잠금을

활성화(지원되는 경우)

디렉터리 안에서 생성된 새 파일들의

그룹 ID를 디렉터리의 그룹ID로 설정

S_ISVTX

sticky bit

파일 내용의 캐싱을 제어

(지원되는 경우)

디렉터리 안의 파일들의 제거

및 이름 변경을 제한

S_IRUSR

사용자 읽기

사용자가 파일을 읽을 수 있음

사용자가 디렉터리 항목들을

읽을 수 있음

S_IWUSR

사용자 쓰기

사용자가 파일을 기록할 수 있음

사용자가 디렉터리 안에서 파일

을 제거하거나 생성할 수 있음

S_IXUSR

사용자 실행

사용자가 파일을 실행할 수 있음

사용자가 주어진 경로이름을

디렉터리 안에서 검색할 수 있음

S_IRGRP

그룹 읽기

그룹이 파일을 읽을 수 있음

그룹이 디렉터리 항목들을 읽을 수 있음

S_IWGRP

그룹 쓰기

그룹이 파일을 기록할 수 있음

그룹이 디렉터리 안에서 파일을

제거하거나 생성할 수 있음

S_IXGRP

그룹 실행

그룹이 파일을 실행할 수 있음

그룹이 주어진 경로이름을

디렉터리 안에서 검색할 수 있음

S_IROTH

기타 읽기

other permission to read file

other permission to

read directory entries

S_IWOTH

기타 쓰기

other permission to write file

other permission to remove

and create files in directory

S_IXOTH

기타 실행

other permission to execute file

other permission to search for

given pathname in directory

※ stat.h <보기>

 

@ 마지막 아홉 상수들을 세 범주로 묶는 것도 가능하다. 다음과 같은 관계가 성립하기 때문.

S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR

S_IRWXG = S_IRGRP | S_IWGRP | S_IXGRP

S_IRWXO = S_IROTH | S_IWOTH | S_IXOTH

 

파일(어떤 종류이든)을 이름으로 열려면 그 이름이 언급된 디렉터리들 각각에 대해 실행 권한이 있어야 한다.

디렉터리의 실행 권한 비트를 종종 '검색 비트(search bit)'라고 부르는 것도 이 때문이다.

 

예를 들어 '/usr/include/stdio.h'라는 파일을 열기 위해서는 '/' 디렉터리에 대한 실행 권한,

'/usr' 디렉터리에 대한 실행 권한, '/usr/include' 디렉터리에 대한 실행 권한이 필요하다.

그런 후에는 파일 자체에 대해 적절한(읽기, 쓰기, 읽기-쓰기 등의 파일 열기 모드에 따른)권한이 있어야 한다.

$ ls -ld /

drwxr-xr-x 24 root root 4096 2011-10-16 01:59 /

$ ls -ld /usr

drwxr-xr-x 10 root root 4096 2011-10-13 00:46 /usr

$ ls -ld /usr/include

drwxr-xr-x 39 root root 4096 2011-10-18 06:49 /usr/include

$ ls -l /usr/include/stdio.h

-rw-r--r-- 1 root root 31525 2011-10-05 06:55 /usr/include/stdio.h

 

디렉터리에 대한 읽기 권한과 실행 권한은 다른 의미를 가짐을 주의하자.

어떤 디렉터리를 읽어서 그 디렉터리에 담긴 모든 파일 이름을 얻는 데에는 읽기 권한으로 충분하다.

그러나 접근하고자 하는 경로이름 안의 한 디렉터리를 거쳐 가기 위해서는 그 디렉터리에 대한 실행 권한이 필요하다

(특정한 파일이름을 찾기 위해서는 디렉터리를 검색해야 한다.)

 

또 다른 예로, PATH 환경 변수에 실행이 허용되지 않는 어떤 디렉터리가 지정되어 있는 경우,

셸은 그 디렉터리 안에 있는 실행파일을 찾지 못한다.

 

파일에 대한 읽기 권한은 프로세스가 해당 파일을 읽기용으로 열 수 있는지의 여부,

O_RDONLYO_RDWR를 지정한 open() 호출의 성공 여부를 결정.

파일에 대한 쓰기 권한은 프로세스가 해당 파일을 쓰기용으로 열 수 있는지의 여부,

O_WRONLYO_RDWR를 지정한 open() 호출의 성공 여부를 결정.

open 함수에서 O_TRUNC 플래그를 사용하려면 파일에 대한 쓰기 권한이 필요하다.

디렉터리에 새 파일을 생성하려면 그 디렉터리에 대한 쓰기 권한 + 실행 권한이 필요.

기존 파일을 삭제하려면 그 파일이 있는 디렉터리에 대한 쓰기 권한 + 실행 권한이 필요

(파일 자체에 대한 읽기 권한이나 쓰기 권한은 필요하지 않다.)

▶ 여섯 가지 exec류 함수들 중 하나로 파일을 실행하기 위해서는 그 파일에 대한 실행 권한이 필요.

또한 해당 파일이 정규 파일이어야 한다.

Posted by devanix
2011. 10. 23. 13:53

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>

 

int stat(const char *pathname, struct stat *buf);

int fstat(int *fd, struct stat *buf);

int lstat(const char *pathname, struct stat *buf);

 

 

return: 성공 0, 실패 -1(errno 설정)

stat - pathname으로 주어진 경로이름에 해당하는 파일에 대한 정보를 둘째 인수인 buf 구조체를 통해 얻는다.

fstat - 파일 디스크립터 filedes에 대해 이미 열려 있는 파일에 대한 정보를 조회한다.

lstat – 지정된 파일이 심볼릭 링크(Symbolic link)이면 그 링크가 가리키는 파일이 아니라

             그 링크 자체에 대한 정보를 돌려준다.

 

struct stat 구조체: <sys/stat.h>

struct stat {

        mode_t    st_mode;

        ino_t       st_ino;

        dev_t      st_dev;

        dev_t      st_rdev;

        nlink_t    st_nlink;

        uid_t      st_uid;

        gid_t      st_gid;

        off_t       st_size;

        blksize_t  st_blksize;

        blkcnt_t   st_blocks;

        time_t     st_atime;

        time_t     st_mtime;

        time_t     st_ctime;

};

 

/* 파일 종류 및 모드(접근 권한) */

/* i노드 번호(일련 번호) */

/* 장치 번호(파일 시스템) */

/* 특수 파일들에 대한 장치 번호 */

/* 링크 개수 */

/* 소유자의 사용자 ID */

/* 소유자의 그룹 ID */

/* 바이트 단위 크기(정규 파일의 경우) */

/* 최적의 I/O 블록 크기 */

/* 할당된 디스크 블록 개수 */

/* 마지막으로 접근된 시간 */

/* 마지막으로 수정된 시간 */

/* 파일 상태가 마지막으로 변경된 시간 */

 

[ stat.h에 정의되어 있는 mode_t에 대한 플래그들 ]

mode

Octal

Description

파일 형식 비트 필드

S_IFMT

00170000

bit mask for the file type bit fields

S_IFSOCK

0140000

Socket

S_IFLNK

0120000

Symbolic link

S_IFREG

0100000

Regular file

S_IFBLK

0060000

Block device

S_IFDIR

0040000

Directory

S_IFCHR

0020000

Character device

S_IFIFO

0010000

pipe or FIFO

파일 접근 권한 비트 필드

S_ISUID

0004000

실행에 대한 SUID(set-user-ID)

S_ISGID

0002000

실행에 대한 SGID(set-group-ID)

S_ISVTX

0001000

저장된 텍스트(saved-text, (sticky bit))

S_IRWXU

00700

파일 소유자 권한 마스크

S_IRUSR

00400

read by user (owner)

S_IWUSR

00200

write by user (owner)

S_IXUSR

00100

execute by user (owner)

S_IRWXG

00070

그룹 권한 마스크

S_IRGRP

00040

read by group

S_IWGRP

00020

write by group

S_IXGRP

00010

execute by group

S_IRWXO

00007

Other에 대한 권한 마스크

S_IROTH

00004

read by other (world)

S_IWOTH

00002

write by other (world)

S_IXOTH

00001

execute by other (world)

 

@st_mode와 S_IFMT의 비트 AND 연산

위의 비트 AND 연산 결과를 16진수로 표현하면 0X8000, 8진수로0100000이 되는데,

이는 위의 표에서 S_IFREG와 같으므로 정규 파일(Regular file)을 의미 한다.

if ((st.st_mode & S_IFMT) == S_IFREG)로 표현.

 

 

[ 파일 형식을 좀더 쉽게 알아내는 POSIX 매크로]

Macro

Type of file

#define S_ISREG(m)   (((m) & S_IFMT) == S_IFREG)

regular file

#define S_ISDIR(m)    (((m) & S_IFMT) == S_IFDIR)

directory file

#define S_ISCHR(m)   (((m) & S_IFMT) == S_IFCHR)

character special file

#define S_ISLNK(m)   (((m) & S_IFMT) == S_IFLNK)

block special file

#define S_ISFIFO(m)   (((m) & S_IFMT) == S_IFIFO)

pipe or FIFO

#define S_ISBLK(m)    (((m) & S_IFMT) == S_IFBLK)

symbolic link

#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)

socket

IPC 객체 종류 Macro

Type of object

S_TYPEISMQ(buf)

message queue

S_TYPEISSEM(buf)

semaphore

S_TYPEISSHM(buf)

shared memory object

@ m = mode_t, buf = struct stat 구조체 포인터

 

Posted by devanix