본문 바로가기
Programming

check if file is used or not using c on linux

by 단창 2012. 4. 14.

어떤 파일이 현재 다른 프로세스에 의해 사용중인지 아닌지 알아내려면 어떻게 해야 할까. 

단순히 fopen해보고 NULL을 반환하지 않으면 된다고 생각했지만 

그게 아니었다. -_- 상당한 삽질을 필요로 했는데, 


다른 프로세스에서 작업 중인 파일이라도, fopen이나, fstream.open, 은 모두 가능하다. 


이런경우는 c/c++ 언어 자체에서 지원하지는 않고, 사용하고 있는 OS의 라이브러리 또는 api의 힘을 빌려야 한다. 

구글세상에 나와있는 정보중 window의 정보는 많지만, (게다가 친절하게 ms에서 관련 msdn까지 제공해준다..특히 C# ㅠㅠ) 

리눅스에서 어찌해야할지 삽질을 상당히 해야 했다. ㅠㅠ 


결국 찾은 system call을 찾았는데 

바로

open(), fcntl() 이다. 


linux man page를 보면 알겠지만 이것의 헤더들은 

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <errno.h>

#include <unistd.h>


이고 


open()으로 file descriptor을 얻어준후, 

fcntl 을 이용해 현재 파일의 Locking상태를 알 수 있다 .


fcntl은 이 자세히 설명된 싸이트 

http://linux.about.com/library/cmd/blcmdl2_fcntl.htm 

에 보면 나와있다 .


fcntl은 이미 열려있는 파일의 파일 특성 제어를 위해 사용되는데 원형을 보면 

int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);

이다. 

fd는 앞서 생한한 descriptor, cmd는 1차 옵션, flock * lock는 2차 옵션인데 

각각 command의 목록 을 보려면 man page들을 찾아보면 된다.. 


간단한 코드를 보면, 



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

using namespace std;


int main(int argc, char ** argv)
{
    int fd = open(argv[1], O_RDONLY);
    if (fd < 0) {
        perror("open");
        return 1;
    }

    if (fcntl(fd, F_SETLEASE, F_WRLCK) && EAGAIN == errno) {
        puts("file is used. ");
    }
    else {
        fcntl(fd, F_SETLEASE, F_UNLCK);
        puts("file is free. ");
    }

    close(fd);
    return 0;
}





이렇게 할 수 있다. 

fcntl의 2번째 인자, F_SETLEASE는 

File을 Write or Read 할 수 있는 권한을 lease해 오는 것을 의미하는것 같다(?) 

lock 로 F_WRLCK는 쓰는 권한을 가져 오는데 이 방법으로 이 파일이 다른 프로세스에 의해 작업중인지 알 있다. 


이것 알아두면 꽤나 유용할 듯 하다. 



*cf)

물론 C코드가 아니라 Shell상에서 알아보려면 

root> fuser filename 

하면 된다.



반응형