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;
}

程序输出:




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值