FCNTL(2)

명칭
fcntl - 파일 제어

프로그램 라이브러리
libc

서식
<fcntl.h> int fcntl(int fd, int cmd, ...)

해설
fcntl() (은)는, 기술자의 제어 기능을 제공합니다. 인수 fd (은)는, 후술 한다 cmd 에 의해 조작되는 기술자입니다. cmd 의 값에 따라서는, fcntl (은)는 3 개째의 인수 int arg (을)를 취할 수가 있습니다.

F_DUPFD
    다음과 같은 새로운 기술자를 돌려줍니다.

    •   arg 이상으로 최소 번호를 가지는 이용 가능한 기술자
    •   오리지날의 기술자와 같은 오브젝트를 참조
    •   오브젝트가 파일이었던 경우, 같은 파일 오프셋(offset)를 공유
    •   같은 액세스 모드 (읽기, 기록, 또는 읽기와 기록)
    •   같은 file status 플래그 (즉, 양쪽 모두의 파일 기술자가 같은 file status 플래그를 공유)
    •   close-on-exec 플래그는, execve(2) 시스템 콜의 다음에도 기술자를 오픈한채로 있도록(듯이) 설정

F_GETFD
    파일 기술자 fd 에 연결시킬 수 있었던 close-on-exec 플래그를, FD_CLOEXEC (으)로서 취득합니다. 돌려주어진 값과 FD_CLOEXEC 의 논리적이 0 의 경우, 파일은 exec() (을)를 실행해도 오픈된 채로 있습니다. 그렇지 않은 경우, 파일은 exec() 의 실행으로 클로우즈 됩니다. (arg (은)는 무시됩니다).

F_SETFD
    fd 에 연결시킬 수 있었던 close-on-exec 플래그를 arg (으)로 설정합니다. arg (은)는 0 또는 전술의 FD_CLOEXEC 입니다.

F_GETFL
    후술 하도록(듯이) 기술자의 스테이터스 플래그를 취득합니다 (arg (은)는 무시됩니다).

F_SETFL
    기술자 스테이터스 플래그를 arg 그리고 지정되는 값으로 설정합니다.

F_GETOWN
    현시점에서 SIGIO 시그널과 SIGURG 시그널을 수신하고 있는 프로세스 ID 또는 프로세스 그룹을 취득 합니다. 프로세스 그룹은 부의 값으로 해서 돌려주어집니다 (arg (은)는 무시됩니다).

F_SETOWN
    프로세스 또는 프로세스 그룹이 SIGIO 시그널 및 SIGURG 시그널을 수신하도록(듯이) 설정합니다. 프로세스 그룹은 arg (을)를 음수로 해 주는 것에 의해 지정됩니다. 그렇지 않은 경우, arg (은)는 프로세스 ID 로서 해석됩니다.

F_GETFL 및 F_SETFL 용무의 플래그는 다음과 같습니다.

O_NONBLOCK
    비블로킹 입출력. read(2) 호출로 읽어내야 할 데이터가 없는 경우, 또는 write(2) 조작이 블록 할 경우에, 읽기 호출해 또는 기록 호출은 에러 EAGAIN 그리고 -1 를 돌려줍니다.

O_APPEND
    각 기록이 파일의 말미에 추가되도록(듯이) 합니다. open(2) 의 O_APPEND 플래그에 대응합니다.

O_DIRECT
    읽고 쓰기에 있어서의 캐쉬 효과를 최소화 또는 없게 합니다. 시스템은, 읽고 쓰기하는 데이터의 캐싱을 피하려고 합니다. 데이터의 캐싱을 피할 수 없는 경우, 데이터의 캐쉬에 대한 영향을 최소화합니다. 주의하지 않고 사용하면(자), 본플래그는 극적으로 성능을 열화 시킵니다.

O_ASYNC
    예를 들어, 읽어내야 할 데이터를 준비할 수 있었을 때 등, 입출력이 가능하게 되었을 때에 SIGIO 시그널이 프로세스 그룹에 송신되도록(듯이) 합니다.

문의형 파일 락을 행하기 위해서(때문에) 몇개의 명령을 이용할 수 있습니다. 이러한 명령은 모두 다음의 구조체로 조작합니다.

    struct flock {
    	off_t	l_start;	/* 개시 위치의 오프셋(offset) */
    	off_t	l_len;		/* len = 0 은 파일 말미까지라고 하는 의미 */
    	pid_t	l_pid;		/* 락 소유자 */
    	short	l_type;		/* 락 타입: 읽기/기록 등 */
    	short	l_whence;	/* l_start 의 타입 */
    };

문의형 레코드 락에 이용할 수 있는 명령은 다음과 같습니다.

F_GETLK
    3 번째의 인수 arg (을)를 struct flock (전기를 참조)에의 포인터라고 해석해, 거기에 따라 지정된다 락 기술을 블록 하는 최초의 락을 취득합니다. 꺼내진 정보는, fcntl() 에게 건네졌다 flock 구조 체내의 정보에 덧쓰기됩니다. 이 락이 작성되는 것을 방해하는 락이 발견되지 않는 경우는, 구조체는 이 함수 호출에 의해도 변경되지 않습니다. 다만, 락 타입이 F_UNLCK (으)로 설정되어 있는 경우는 제외합니다.

F_SETLK
    3 번째의 인수 arg (을)를 struct flock (전기를 참조)에의 포인터라고 해석해, 거기에 따라 지정된다 락 기술에 따라 파일 세그먼트(segment) 락을 설정 또는 클리어 합니다. F_SETLK (은)는, 공유 (또는 읽기) 락 (F_RDLCK) 또는 배타적 (또는 기록) 락 (F_WRLCK) (을)를 확립, 및 몇개의 타입의 락을 해제 (F_UNLCK) 하는데 사용됩니다. 공유 락 또는 배타적 락을 설정할 수 없는 경우, fcntl() 하 EAGAIN 그리고 즉시 돌아옵니다.

F_SETLKW
    이 명령은 F_SETLK (와)과 같습니다만, 공유 락 또는 배타적 락이 다른 락에 의해 블록 되는 경우에, 요구가 채워질 때까지 프로세스가 대기하는 점이 다릅니다. fcntl() (이)가 있는 area를 확보하기 위해서 대기하고 있는 동안에 포착되어야 할 시그널을 수신해, 시그널 핸들러가 SA_RESTART (sigaction(2) (을)를 참조)를 지정하고 있지 않는 경우, fcntl() (은)는 중단됩니다.

공유 락이 파일이 있는 세그먼트(segment)로 설정되어 있는 경우, 다른 프로세스는 그 세그먼트(segment) 또는 그 일부에 공유 락을 설정할 수 있습니다. 공유 락은, 보호하고 있다 어느 area에도, 다른 프로세스가 배타적 락을 설정하는 것을 방지합니다. 파일 기술자가 읽기 액세스로 열리지 않은 경우, 공유 락의 요구는 처리를 실패합니다.

배타적 락은, 보호하고 있는 area에 다른 프로세스가 공유 락 또는 배타적 락을 설정하는 것을 방지합니다. 파일이 기록 액세스로 열리지 않은 경우, 배타적 락의 요구는 실패합니다.

l_whence 의 값은 SEEK_SET, SEEK_CUR, 또는 SEEK_END 그리고, 이것들은 상대 오프셋(offset) l_start 바이트가, 각각 파일의 선두, 현재 위치, 또는 파일의 말미로부터 측정되는 것을 지시합니다. l_len 의 값은 락 되는 연속 area의 바이트수입니다. l_len 하지만 부의 경우의 결과는 미정도리입니다. l_pid 필드는, 블록 하는 락을 보관 유지하고 있는 프로세스의 프로세스 ID 를 돌려주기 위해서(때문에) F_GETLK 에서만 사용됩니다. F_GETLK 요구가 정상적으로 완료하면(자) l_whence 의 값은 SEEK_SET (이)가 됩니다.

락은 현재의 파일 말미 이후에 개시하거나 파일 말미를 넘어 연장할 수 있습니다만, 파일의 선두보다 전으로 개시하거나 파일의 선두를 넘어 연장할 수 없습니다. l_len 하지만 0 으로 설정되어 있는 경우, 락은 그 파일의 파일 오프셋(offset)의 가능한 최대의 값까지 연장됩니다. l_whence (와)과 l_start 하지만 파일의 선두를 가리키고 있어 게다가 l_len 하지만 0 의 경우는 파일 전체가 락 됩니다. 어플리케이션이 파일 전체를 잠그려 하고 있을 뿐(만큼)이라면, flock(2) 시스템 콜이 아득하게 효율적입니다.

파일내의 각 바이트에 대해 최대로 1 개의 타입의 락이 설정됩니다. 호출 프로세스가 F_SETLK 요구, 또는 F_SETLKW 요구로 지정한 영역내에 기존의 락을 보관 유지하고 있을 때, 요구로부터 정상적으로 돌아오기 전에, 지정의 영역내의 각 바이트에 대해 이전의 락 타입이 새로운 락 타입으로 옮겨놓을 수 있습니다. 공유 락과 배타적 락의 곳에서 전술한 것처럼, 다른 프로세스가 지정의 영역내에 락을 보관 유지하고 있어, 게다가 그러한 락 의 타입이 요구로 지정된 타입과 경합 할 때, F_SETLK 요구는 실패해, F_SETLKW 요구는 블록 합니다.

이 인터페이스는, System V 와 p1003.1-88 하지만 요구하는 성과가 없는 시멘틱스에 완전하게 따라서 있습니다. 즉, 어느 프로세스가 보관 유지하고 있는, 어느 파일과 연결시킬 수 있던 모든 락은, 그 파일의 기술자의 언젠가 하지만 그 프로세스에 의해 클로우즈 되었을 때에 해제됩니다. 이것은, 써브루틴 프로그램 라이브러리가 액세스 할 가능성이 있는 파일 모두를 어플리케이션이 인식하고 있을 필요가 있다 일을 의미합니다. 예를 들어, 패스워드 파일을 갱신한다 어플리케이션이, 갱신을 행하기 위해서(때문에) 패스워드 파일 데이타베이스를 잠그어, 레코드를 꺼내기 위해서(때문에) getpwnam(3) (을)를 호출했다고 합시다. getpwnam(3) (은)는 패스워드 데이타베이스를 오픈해, 읽어내, 그리고 클로우즈 하므로, 락은 없어집니다. 데이타베이스를 클로우즈 하면(자), 프로그램 라이브러리 routine 하지만 데이타베이스에의 락을 요구했던 적이 없는 경우조차, 프로세스가 데이타베이스에 연결시킨 모든 락이 해방되어 버립니다. 이 인터페이스의 다른 그다지 중요하지 않은 시멘틱스상의 문제는, 락이 fork(2) 함수를 사용해 작성된 child process에 의해 계승되지 않는 것입니다. flock(2) 인터페이스는, 아득하게 합리적인 last close 시멘틱스를 채용해, 락이 child process에 의해 계승되게 되어 있습니다. 프로그램 라이브러리를 사용할 경우에 락의 정합성을 확실히 하는, 또는 락을 child process에 건네주고 싶은 어플리케이션에 대해서는 flock(2) (을)를 추천합니다. flock(2) (와)과 fcntl(2) 락은 동시에 안전하게 사용할 수 있습니다. 블록 하는 락을 보관 유지하고 있는 프로세스가 파일 기술자를 이전에 flock(2) 그리고 잠그고 있었을 경우, fcntl(F_GETLK) 하 l_pid 에 -1 를 넣어 돌아옵니다.

프로세스의, 어느 파일에 연결시킬 수 있던 모든 락은 그 프로세스가 종료할 경우에 해제됩니다.

execve(2) 의 호출전에 취득된 모든 락은, 신규 프로그램이 그것들을 해방할 때까지 유효한 그대로입니다. 신규 프로그램이 락에 대해 모른다면, 프로그램 종료까지 해방되지 않습니다.

있는 잠근 area를 제어하고 있는 프로세스가, 다른 프로세스가 잠근 area를 잠그려고 휴면 상태로 되는 경우에, 데드 록이 발생할 가능성이 있습니다. 이 실장에서는, 락 된 area가 언로크 될 때까지의 휴면이 데드 록을 일으킬 가능성을 검출하면(자), EDEADLK 에러로 실패합니다.

반환값
처리가 정상적으로 완료했을 경우, 돌려주어지는 값은 cmd 에 응해 다음과 같이 됩니다.

F_DUPFD
    새로운 파일 기술자

F_GETFD
    플래그의 값 (하위 비트만이 정의됩니다)

F_GETFL
    플래그의 값

F_GETOWN
    파일 기술자 소유자의 값

그 외 -1 이외의 값

그렇지 않은 경우는 -1 이 돌려주어져 에러를 나타내기 위해서(때문에) errno 하지만 설정됩니다.

에러
fcntl() (은)는 다음의 경우에 실패합니다.

[EAGAIN]
    인수 cmd 하 F_SETLK (이어)여, 락의 타입 (l_type) (은)는 공유 락 (F_RDLCK) , 또는 배타적 락 (F_WRLCK) 그리고, 락 되어야할 파일의 세그먼트(segment)는 이미 다른 프로세스에 의해 배타적으로 락 되고 있습니다. 또는, 타입이 배타적인 락으로, 락 되는 파일의 세그먼트(segment)의 일부가 이미 다른 프로세스에 의해 공유 락 또는 배타적 락 되고 있습니다.

[EBADF]
    fd (은)는 유효한 오픈 파일 기술자가 아닙니다.

    인수 cmd 하지만 F_SETLK 또는 F_SETLKW 그리고, 한편 락 타입 (l_type) 하지만 공유 락 (F_RDLCK) 때, fd (은)는 읽기용으로 열린 유효한 파일 기술자가 아닙니다.

    인수 cmd 하지만 F_SETLK 또는 F_SETLKW 그리고, 한편 락 타입 (l_type) 하지만 배타적 락 (F_WRLCK) 때, fd (은)는 기록용으로 열린 유효한 파일 기술자가 아닙니다.

[EDEADLK]
    인수 cmd 하지만 F_SETLKW (이어)여, 데드 록 조건이 검출되었습니다.

[EINTR]
    인수 cmd 하지만 F_SETLKW (이어)여, 함수가 시그널에 의해 나누기 붐비어지고 했다.

[EINVAL]
    cmd 하지만 F_DUPFD 그리고, arg 하지만 부이든가 또는 허용 되는 최대치부터 커지고 있습니다 (getdtablesize(2) (을)를 참조).

    인수 cmd 하지만 F_GETLK, F_SETLK, 또는 F_SETLKW 그리고, arg 하지만 가리키는 데이터가 유효이지 않습니다. 또는 fd 하지만, 락을 서포트하지 않는 파일을 참조하고 있습니다.

[EMFILE]
    인수 cmd 하지만 F_DUPFD (이어)여, 프로세스에 대해 허용 되는 최대수까지 파일 기술자가 이미 사용되고 있습니다. arg 그리고 지정된 이상의 파일 기술자는 이용할 수 없습니다.

[ENOLCK]
    인수 cmd 하지만 F_SETLK 또는 F_SETLKW (이어)여, 락 요구 또는 언로크 요구를 채우는 것에 의해, 시스템이 부과한 한계를 넘는 수의 락 된 area가 시스템내에 가능하게 됩니다.

[EPERM]
    cmd (은)는, F_SETOWN (이어)여, 인수로서 지정된 프로세스 ID 또는 프로세스 그룹 (은)는, 호출측과 다른 세션내에 있습니다.

[ESRCH]
    cmd 하 F_SETOWN (이어)여, 인수로서 지정된 프로세스 ID 가 사용되고 있지 않습니다.

게다가 fd 하지만 (소켓상에서 열고 있는 기술자와는 반대로) 단말 디바이스상에서 열고 있는 기술자를 참조하는 경우, cmd 그리고 F_SETOWN (을)를 지정하면(자) tcsetpgrp(3) (와)과 같은 이유로 처리를 실패할 가능성이 있어, tcgetpgrp(3) 그리고 말한 것 같은 이유로 cmd 그리고 F_GETOWN (을)를 지정했을 경우에 처리에 실패할 가능성이 있습니다.

관련 항목
close(2), execve(2), flock(2), getdtablesize(2), open(2), sigvec(2), tcgetpgrp(3), tcsetpgrp(3)

역사
fcntl() 함수는 4.2BSD 그리고 등장했습니다.