Programming/Linux Programming

리눅스 하위디렉토리, 파일포함 디렉토리 삭제하기

랜달프 2009. 3. 10. 15:07
파일의 상태 얻기
#include 
#include 
#include 

int stat(const char *file_name, struct stat *buf);
int fstat(int filedes, struct stat *buf);
int lstat(const char *file_name, struct stat *buf);

파일의 상태는 다음과 같은 구조체에 저장
struct stat
{
	dev_t         st_dev;      /* device */
	ino_t         st_ino;      /* inode */
	mode_t        st_mode;     /* protection */
	nlink_t       st_nlink;    /* number of hard links */
	uid_t         st_uid;      /* user ID of owner */
	gid_t         st_gid;      /* group ID of owner */
	dev_t         st_rdev;     /* device type (if inode device) */
	off_t         st_size;     /* total size, in bytes */
	unsigned long st_blksize;  /* blocksize for filesystem I/O */
	unsigned long st_blocks;   /* number of blocks allocated */
	time_t        st_atime;    /* time of last access */
	time_t        st_mtime;    /* time of last modification */
	time_t        st_ctime;    /* time of last change */
};

아래 POSIX 매크로는 파일 타입을 확인하는 것이다:
S_ISLNK(m)  is it a symbolic link?
S_ISREG(m)  regular file?
S_ISDIR(m)  directory?
S_ISCHR(m)  character device?
S_ISBLK(m)  block device?
S_ISFIFO(m) fifo?
S_ISSOCK(m) socket?

디렉토리 정보를 저장할 구조체 ( entry = readdir(dp) )
#include 
struct dirent
{
	long d_ino;                 /* inode number */
	off_t d_off;                /* offset to this dirent */
	unsigned short d_reclen;    /* length of this d_name */
	char d_name[NAME_MAX+1];   /* file name (null-terminated) */
}

실수하기 쉬운 부분(주의사항)
chdir() 함수를 이용하여 현재 작업 디렉토리를 유지해줘야 한다.
그렇지 않으면 원하지 않은 결과(디렉토리를 파일로, 파일을 디렉토리로 인식)가 나올수도 있으니 유의하자.
int remove_dir(std::string path)
{
	DIR* dp = NULL;
	struct dirent* entry = NULL;
	struct stat buf;
	
	if( ( dp = opendir(path.c_str())) == NULL  )
	{
		return -1;
	}
	
	while( (entry = readdir(dp)) != NULL )
	{
		chdir(path.c_str());
		lstat(entry->d_name, &buf);
		
		if( S_ISDIR(buf.st_mode) )
		{
			if( 0 == strcmp( entry->d_name , ".") || 0 == strcmp( entry->d_name, "..") )
			continue;
		
			remove_dir(entry->d_name);
		}
		else if( S_ISREG(buf.st_mode) )
		{
			if(0 != remove(entry->d_name))
			{
				return -1;
			}
		}
	}
	
	chdir("..");
	
	if(0 != remove(path.c_str()))
	{
		return -1;
	}
	
	closedir(dp);
	
	return 0;
}