APUE筆記三

1. 文件類型

    文件包含以下幾種類型:1)普通文件 2)目錄文件 3)塊特殊文件(帶緩衝的訪問文件,每次訪問以固定長度爲單位進行)4)字符特殊文件(不帶緩衝的訪問文件,訪問長度可變)5) FIFO 6)套接字(socket) 7) 符號鏈接。

S_ISREG()--->普通文件 S_ISDIR()-->目錄文件  S_ISCHR-->字符特殊文件 S_ISBLK()-->塊特殊文件 S_ISFIFO-->管道或FIFO S_ISLNK()-->符號鏈接 S_ISSOCK-->套接字。

#include <stdio.h>
#include <sys/stat.h>

int main( int argc, char *argv[] )
{
        int     i;
        struct stat buf;
        char    *ptr;
        for ( i = 1; i < argc; i++ ){
                printf("%s: ", argv[ i ] );
                if ( lstat( argv[ i ], &buf ) < 0 ){
                        printf("lstat error");
                        continue;
                }
                if ( S_ISREG( buf.st_mode ) )
                        ptr = "regular";
                else if ( S_ISDIR( buf.st_mode ) )
                        ptr = "directory";
                else if ( S_ISCHR( buf.st_mode ) )
                        ptr = "character special";
                else if ( S_ISBLK( buf.st_mode ) )
                        ptr = "block special";
                else if ( S_ISFIFO( buf.st_mode ) )
                        ptr = "fifo";
                else if ( S_ISLNK( buf.st_mode ) )
                        ptr = "symbolic link";
                else if ( S_ISSOCK( buf.st_mode ) )
                        ptr = "socket";
                else
                        ptr = "** unknown mode ** ";
                printf("%s\n", ptr );
        }
        return 0;
}
程序輸出:


2. 文件權限

    通過access函數來查看文件的訪問權限。

#include <stdio.h>
#include <fcntl.h>

int main( int argc, char *argv[] )
{
        if ( argc != 2 )
                printf("usage:a.out <pathname>");
        if ( access( argv[ 1 ], R_OK ) < 0 )
                printf( "access error for %s\n", argv[ 1 ] );
        else
                printf("read access OK\n");
        if ( open(argv[ 1 ], O_RDONLY ) < 0 )
                printf("open error for %s\n", argv[ 1 ] );
        else
                printf("open for reading OK\n");

        return 0;
}
程序輸出:



3. 創建屏蔽字

    umask函數爲進程設置文件模式創建屏蔽字。

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>

#define RWRWRW (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)

int main( void )
{
        umask( 0 );
        if ( creat("foo", RWRWRW ) < 0 )
                printf("creat error for foo\n");
        umask( S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
        if ( creat("bar", RWRWRW ) < 0 )
                printf("creat error for bar\n");
        return 0;
}
程序輸出:



4. 修改文件的訪問權限

#include <stdio.h>
#include <sys/stat.h>

int main( void )
{
        struct stat statbuf;

        if ( stat( "foo", &statbuf ) < 0 )
                printf("stat error for foo\n" );
        if ( chmod("foo", ( statbuf.st_mode & ~S_IXGRP ) | S_ISGID ) < 0 )
                printf("chmod error for foo\n");
        if ( chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ) < 0 )
                printf("chmod error for bar\n" );
        return 0;
}

程序輸出:


5. 更改文件的用戶ID和組ID

    只有超級用戶才能進行修改,或者擁有此文件的用戶才能進行修改(這種情況下只能修改到你所屬於的組裏面的用戶ID)

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
int main( void )
{
        struct stat buf;
        if ( stat( "foo", &buf ) < 0 ){
                printf("stat error\n");
                return 1;
        }
        printf( "uid is:%d, gid is:%d\n", buf.st_uid, buf.st_gid );
        if ( chown( "foo", 0, 0 ) < 0 ){
                printf("chown error\n");
                return 1;
        }
        if ( stat( "foo", &buf ) < 0 ){
                printf("stat error\n" );
                return 1;
        }
        printf("now uid is:%d, gid is:%d\n", buf.st_uid, buf.st_gid );

        return 0;
}

通過root用戶執行,則程序輸出:



6. 刪除鏈接文件

#include <stdio.h>
#include <fcntl.h>

int main( void )
{
        if ( open("tempfile", O_RDWR ) < 0 )
                printf("open error\n");
        if ( unlink( "tempfile") < 0 )
                printf("unlink error\n" );
        printf("file unlinked\n");
        sleep( 30 );
        printf("done\n");
        return 0;
}

只有當進程完全退出的時候,才能徹底刪除文件。請比較進程退出後/home的大小和進程退出前/home的大小(多了8字節):



7. 符號鏈接

    符號鏈接是指向一個文件的間接指針,而link的硬鏈接直接指向文件的i節點。引入符號鏈接的原因是爲了避開硬鏈接的一些限制:

1) 硬鏈接通常要求鏈接和文件位於同一文件系統中

2) 只有超級用戶才能創建指向目錄的硬鏈接

    以下命令可學習符號鏈接的基本知識:



8. 遍歷一個目錄

#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;

void myftw( char *, char * );

int main( int argc, char *argv[] )
{
	if ( argc != 2 ){
		printf("input error\n");
		return 1;
	}
	myftw( "", argv[ 1 ] );
	ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;
	if ( 0 == ntot ){
		ntot = 1;
	}
	printf("regular files=%7ld, %5.2f%%\n", nreg, nreg * 100.0 / ntot );
	printf("directory=%7ld, %5.2f%%\n", ndir, ndir * 100.0 / ntot );
	printf("block special=%7ld, %5.2f%%\n", nblk, nblk * 100.0 / ntot );
	printf("char special=%7ld, %5.2f%%\n", nchr, nchr * 100.0 / ntot );
	printf("FIFOs=%7ld, %5.2f%%\n", nfifo, nfifo * 100.0 / ntot );
	printf("symbolic links=%7ld, %5.2f%%\n", nslink, nslink * 100.0 / ntot );
	printf("sockets=%7ld, %5.2f%%\n", nsock, nsock * 100.0 / ntot );

	return 0;
}

void myftw( char *curPath, char *path )
{
	struct stat statbuf;
	DIR	*dp;
	struct dirent *dirp;
	char	fullPath[ 256 ];
	
	if ( strcmp( curPath, "" ) != 0 ){
		strncpy( fullPath, curPath, strlen( curPath ) );
		fullPath[ strlen( curPath ) ] = '/';
		strncpy( fullPath + strlen( curPath ) + 1, path, strlen( path ) );
		fullPath[ strlen( curPath ) + strlen( path ) + 1 ] = '\0';
	}
	else{
		strncpy( fullPath, path, strlen( path ) );
		fullPath[ strlen( path ) ] = '\0';
	}
	if ( lstat( fullPath, &statbuf ) < 0 ){
		printf("lstat error:%s\n", fullPath);
		return;
	}
	if ( S_ISREG( statbuf.st_mode ) )
		nreg++;
	else if ( S_ISDIR( statbuf.st_mode ) ){
		ndir++;
		if ( ( dp = opendir( fullPath ) ) == NULL ){
			printf("can't open %s\n", fullPath );
			return;
		}
		while ( ( dirp = readdir( dp ) ) != NULL ){
			if ( strcmp( dirp->d_name, "." ) == 0 ||
			     strcmp( dirp->d_name, ".." ) == 0 ){
				continue;
			}
			myftw( fullPath, dirp->d_name );
		}
	}
	else if ( S_ISCHR( statbuf.st_mode ) )
		nchr++;
	else if ( S_ISBLK( statbuf.st_mode ) )
		nblk++;
	else if ( S_ISFIFO( statbuf.st_mode ) )
		nfifo++;
	else if ( S_ISLNK( statbuf.st_mode ) )
		nslink++;
	else if ( S_ISSOCK( statbuf.st_mode ) )
		nsock++;
	else
		printf("file error\n");
}

程序輸出:



9. 設備特殊文件

#include <stdio.h>
#include <sys/stat.h>
#ifdef SOLARIS
#include <sys/mkdev.h>
#endif
#include <sys/sysmacros.h>

int main( int argc, char *argv[] )
{
        int     i;
        struct stat buf;
        for ( i = 1; i < argc; i++ ){
                printf("%s: ", argv[ i ] );
                if ( stat( argv[ i ], &buf ) < 0 ){
                        printf("stat error\n");
                        continue;
                }
                printf("dev=%d/%d", major( buf.st_dev), minor( buf.st_dev));
                if ( S_ISCHR( buf.st_mode ) || S_ISBLK(buf.st_mode)){
                        printf("(%s) rdev = %d/%d",
                                ( S_ISCHR( buf.st_mode)) ? "character" : "block", major( buf.st_rdev), minor( buf.st_rdev));
                }
                printf("\n");
        }

        return 0;
}

程序輸出:




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章