`
灵动的水
  • 浏览: 191059 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

文件操作经典概括

阅读更多
OS.h  分类: C++ 2009-07-19 12:31

#ifndef ICE_PATCH2_OS_H
#define ICE_PATCH2_OS_H

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

#ifndef ICE_PATCH2_API
#   ifdef ICE_PATCH2_API_EXPORTS
#       define ICE_PATCH2_API ICE_DECLSPEC_EXPORT
#   else
#       define ICE_PATCH2_API ICE_DECLSPEC_IMPORT
#   endif
#endif

namespace OS
{

#ifdef _WIN32

typedef struct _stat structstat;
#ifdef _MSC_VER
#   define O_RDONLY _O_RDONLY
#   define O_BINARY _O_BINARY

#   define S_ISDIR(mode) ((mode) & _S_IFDIR)
#   define S_ISREG(mode) ((mode) & _S_IFREG)
#endif

#else

// linux  则定义 stat 结构 为structstat 类型,  O_BINARY为0

typedef struct stat structstat;

#   define O_BINARY 0

#endif

// BUGFIX: aCC errors if this is stat.

ICE_PATCH2_API int osstat( const std::string&, structstat* );

ICE_PATCH2_API int remove( const std::string& );

ICE_PATCH2_API int rename( const std::string&, const std::string& );

ICE_PATCH2_API int rmdir( const std::string& );

ICE_PATCH2_API int mkdir( const std::string&, int );

ICE_PATCH2_API FILE* fopen( const std::string&, const std::string& );

ICE_PATCH2_API int open( const std::string&, int );

ICE_PATCH2_API int getcwd( std::string& ) ;

}

#endif




#include <IceUtil/DisableWarnings.h>
#include <OS.h>
#include <IceUtil/Unicode.h>

#ifdef __BCPLUSPLUS__
#  include <dir.h>
#  include <io.h>
#endif

using namespace std;
using namespace OS;

#ifdef _WIN32


#else


//linux 调用stat函数将path指定的文件结构信息,保存到buf中

/*


表头文件:    #include <sys/stat.h>
#include <unistd.h>
定义函数:    int stat(const char *file_name, struct stat *buf);
函数说明:    通过文件名filename获取文件信息,并保存在buf所指的结构体stat中
返回值:     执行成功则返回0,失败返回-1,错误代码存于errno

错误代码:
ENOENT         参数file_name指定的文件不存在
ENOTDIR        路径中的目录存在但却非真正的目录
ELOOP          欲打开的文件有过多符号连接问题,上限为16符号连接
EFAULT         参数buf为无效指针,指向无法存在的内存空间
EACCESS        存取文件时被拒绝
ENOMEM         核心内存不足
ENAMETOOLONG   参数file_name的路径名称太长


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

int main() {
struct stat buf;
stat("/etc/hosts", &buf);
printf("/etc/hosts file size = %d\n", buf.st_size);
}


-----------------------------------------------------
struct stat {
dev_t         st_dev;       //文件的设备编号
ino_t         st_ino;       //节点
mode_t        st_mode;      //文件的类型和存取的权限
nlink_t       st_nlink;     //连到该文件的硬连接数目,刚建立的文件值为1
uid_t         st_uid;       //用户ID
gid_t         st_gid;       //组ID
dev_t         st_rdev;      //(设备类型)若此文件为设备文件,则为其设备编号
off_t         st_size;      //文件字节数(文件大小)
unsigned long st_blksize;   //块大小(文件系统的I/O 缓冲区大小)
unsigned long st_blocks;    //块数
time_t        st_atime;     //最后一次访问时间
time_t        st_mtime;     //最后一次修改时间
time_t        st_ctime;     //最后一次改变时间(指属性)
};

先前所描述的st_mode 则定义了下列数种情况:
S_IFMT   0170000    文件类型的位遮罩
S_IFSOCK 0140000    scoket
S_IFLNK 0120000     符号连接
S_IFREG 0100000     一般文件
S_IFBLK 0060000     区块装置
S_IFDIR 0040000     目录
S_IFCHR 0020000     字符装置
S_IFIFO 0010000     先进先出

S_ISUID 04000     文件的(set user-id on execution)位
S_ISGID 02000     文件的(set group-id on execution)位
S_ISVTX 01000     文件的sticky位

S_IRUSR(S_IREAD) 00400     文件所有者具可读取权限
S_IWUSR(S_IWRITE)00200     文件所有者具可写入权限
S_IXUSR(S_IEXEC) 00100     文件所有者具可执行权限

S_IRGRP 00040             用户组具可读取权限
S_IWGRP 00020             用户组具可写入权限
S_IXGRP 00010             用户组具可执行权限

S_IROTH 00004             其他用户具可读取权限
S_IWOTH 00002             其他用户具可写入权限
S_IXOTH 00001             其他用户具可执行权限

上述的文件类型在POSIX中定义了检查这些类型的宏定义:
S_ISLNK (st_mode)    判断是否为符号连接
S_ISREG (st_mode)    是否为一般文件
S_ISDIR (st_mode)    是否为目录
S_ISCHR (st_mode)    是否为字符装置文件
S_ISBLK (s3e)        是否为先进先出
S_ISSOCK (st_mode)   是否为socket


若一目录具有sticky位(S_ISVTX),则表示在此目录下的文件只能被该文件所有者、
此目录所有者或root来删除或改名。

-----------------------------------------------------
struct statfs {
long    f_type;          //文件系统类型
long    f_bsize;         //块大小
long    f_blocks;        //块多少
long    f_bfree;         //空闲的块
long    f_bavail;        //可用块
long    f_files;         //总文件节点
long    f_ffree;         //空闲文件节点
fsid_t f_fsid;           //文件系统id
long    f_namelen;       //文件名的最大长度
long    f_spare[6];      //spare for later
};



stat、fstat和lstat函数(UNIX)


#include<sys/types.h>
#include<sys/stat.h>
int stat(const char *restrict pathname, struct stat *restrict buf);
提供文件名字,获取文件对应属性。感觉一般是文件没有打开的时候这样操作。
int fstat(int filedes, struct stat *buf);
通过文件描述符获取文件对应的属性。文件打开后这样操作
int lstat(const char *restrict pathname, struct stat *restrict buf);
连接文件

三个函数的返回:若成功则为0,若出错则为-1
给定一个pathname,stat函数返回一个与此命名文件有关的信息结构,
fstat函数获得已在描述符filedes上打开的文件的有关信息。lstat函数类似于stat,
但是当命名的文件是一个符号连接时,lstat返回该符号连接的有关信息,
而不是由该符号连接引用的文件的信息。

第二个参数是个指针,它指向一个我们应提供的结构。这些函数填写由buf指向的结构。
该结构的实际定义可能随实现而有所不同,但其基本形式是:

struct stat{
mode_t st_mode;   /*file tpye &mode (permissions)
ino_t st_ino;     /*i=node number (serial number)
dev_t st_rdev;   /*device number for special files
nlink_t st_nlink; /*number of links
uid_t    st_uid; /*user id of owner
gid_t    st_gid; /*group ID of owner
off_t   st_size; /*size in bytes for regular files
time_t st_atime; /*time of last access
time_t st_mtime; /*time of last modification
time_t st_ctime; /*time of last file status change
long st_blksize; /*best I/O block size 
long st_blocks; /*number of 512-byte blocks allocated
};
注意,除最后两个以外,其他各成员都为基本系统数据类型。
我们将说明此结构的每个成员以了解文件属性。

使用stat函数最多的可能是ls-l命令,用其可以获得有关一个文件的所有信息。



1 函数都是获取文件(普通文件,目录,管道,socket,字符,块()的属性。
函数原型#include <sys/stat.h>

int stat(const char *restrict pathname, struct stat *restrict buf);提供文件名字,
获取文件对应属性。
int fstat(int filedes, struct stat *buf);通过文件描述符获取文件对应的属性。
int lstat(const char *restrict pathname, struct stat *restrict buf);连接文件描述命,
获取文件属性。2 文件对应的属性struct stat {
mode_t     st_mode;       //文件对应的模式,文件,目录等
ino_t      st_ino;       //inode节点号
dev_t      st_dev;        //设备号码
dev_t      st_rdev;       //特殊设备号码
nlink_t    st_nlink;      //文件的连接数
uid_t      st_uid;        //文件所有者
gid_t      st_gid;        //文件所有者对应的组
off_t      st_size;       //普通文件,对应的文件字节数
time_t     st_atime;      //文件最后被访问的时间
time_t     st_mtime;      //文件内容最后被修改的时间
time_t     st_ctime;      //文件状态改变时间
blksize_t st_blksize;    //文件内容对应的块大小
blkcnt_t   st_blocks;     //伟建内容对应的块数量
};可以通过上面提供的函数,返回一个结构体,保存着文件的信息。


*/

int
OS::osstat( const string& path, structstat* buf )
{
return ::stat( path.c_str(), buf );
}

/*

remove函数的功能是删除一个文件。它的一般格式为:
remove(const char * filename);
remove函数也是一个宏,可以删除filename(文件名)指定的文件。
如果文件已经打开,则必须将该文件关闭才能够删除。如果调用成功,
返回0,否则返回-1,并置全局变量errno为ENOENT(没有此文件或目录)
或EACCES(无此权限)。

NAME
       rename - change the name or location of a file

SYNOPSIS
       #include <stdio.h>

       int rename(const char *oldpath, const char *newpath);

DESCRIPTION
       rename() renames a file, moving it between directories if required.

       Any other hard links to the file (as created using link(2)) are unaffected.

       If newpath already exists it will be atomically replaced (subject
    to a few conditions; see ERRORS below),
       so that there is no point at which another process attempting to
    access newpath will find it missing.

The rename function causes the file whose name is the string pointed to by old to be
henceforth known by the name given by the string pointed to by new. The file named
old is no longer accessible by that name.
If a file named by the string pointed to by new exists prior to the call to
the rename function, the behavior is implementation-defined.



ISO C99 p267
man 2 rename
oldpath and newpath are not on the same mounted filesystem. 
(Linux permits  a  filesystem  to  be
              mounted at multiple points, but rename(2) does not work
     across different mount points, even if the
              same filesystem is mounted on both.)


rename(更改文件名称或位置) 
相关函数  link,unlink,symlink
表头文件  #include<stdio.h>
定义函数  int rename(const char * oldpath,const char * newpath);
函数说明  rename()会将参数oldpath 所指定的文件名称改为参数newpath所指的文件名称。
若newpath所指定的文件已存在,则会被删除。
返回值  执行成功则返回0,失败返回-1,错误原因存于errno

范例  设计一个DOS下的rename指令rename 旧文件名新文件名


mkdir和rmdir函数.
    int mkdir(const char*pathname,mode_t mode);//创建一个空目录
    int rmdir(const char *pathname);           //删除一个空目录,不能删除有文件目录
  

读目录
    对于某个目录具有访问权限的任一用户都可以读该目录,但是,为了防止文件系统
产生混乱,只有内核才能写目录.这里又有一个新头文件出现<dirent.h>
    DIR* opendir(const char *pathname);//成功返回指针,出错返回NULL
    struct dirent *readdir(DIR *dp);
    void rewinddir(DIR *dp);
    int closedir(DIR *dp);
    long telldir(DIR *dp);
    void seekdir(DIR *dp,long loc);

    struct dirent        //来自/usr/include/bits/dirent.h
    {
#ifndef __USE_FILE_OFFSET64
        __ino_t d_ino;
        __off_t d_off;
#else
        __ino64_t d_ino;              //i_node节点号
        __off64_t d_off;
#endif
        unsigned short int d_reclen;
        unsigned char d_type;
        char d_name[256];         /*We must not include limits.h //目录名
    }

   DIR结构是内核用的,对用户不公开使用.


一、获取当前工作目录函数-getcwd
头文件:<unistd.h>
函数形式:char* getcwd(char *buffer,size_t size)
返回值:成功返回当前工作目录的字符串指针
              失败返回NULL
              设置errno


错误信息:
EINVAL:size参数为0或者buff不是空指针;
ERANGE:size参数小于当前工作目录的长度,需要分配更大的内存
EACCES:权限不足,没有读或者搜索文件名称的权限
          
二、获得系统目录最大长度-pathconf
头文件:unistd.h
函数形式:long pathconf(char *path,int name)
返回值:成功返回目录长度的极限值
              失败返回-1
              设置errno

//name:pathconf_exam.cxx
#include<unistd.h>
#include<iostream.h>

int main(void)
{
    long cur_work_len;
    char*  cur_work_dir;

//获得目录最大长度
if((cur_work_len=pathconf(".",_PC_PATH_MAX))==-1)
{
    perror("Could not get current working directory length!");
    return 1;
}
std::cout<<"Current work length is "<<cur_work_len<<std::endl;

//根据获得的目录的最大长度,分配内存
if((cur_work_dir=(char*)malloc(cur_work_len))==NULL)
{
    perror("Could not allocate memory for the directory!");
    return 1;
}

//获得当前的工作目录
if (getcwd(cur_work_dir,cur_work_len)==NULL)
{
    perror("Could not get current working directory!");
    return 1;
}

std::cout<<"Current working directory is "<<cur_work_dir<<std::endl;
return 0;
}
程序执行结果:
guocheng@guocheng-desktop:~/test/dir_exam/pathconf$ g++ -o pathconf_exam pathconf_exam.cxx
guocheng@guocheng-desktop:~/test/dir_exam/pathconf$ ./pathconf_exam
Current work length is 4096
Current working directory is /home/guocheng/test/dir_exam/pathconf

三、更改当前工作目录-chdir和fchdir

头文件:unisd.h
函数形式:int chdir(const char* path)
                 int fchdir(fd)
返回值:成功0
              失败-1
              设置errno
说明:chdir函数的参数是指向目录的字符串指针,成功的前提是程序有所搜整个目录的权限,fchdir调用的参数是目录的文件描述符,其他与chdir相同。

按照上面的例子进行修改。
//name:chdir_exam.cxx
#include<unistd.h>
#include<iostream.h>

int main(void)
{
    long cur_work_len;
    char*  cur_work_dir;

//获得目录最大长度
if((cur_work_len=pathconf(".",_PC_PATH_MAX))==-1)
{
    perror("Could not get current working directory length!");
    return 1;
}
std::cout<<"Current work length is "<<cur_work_len<<std::endl;

//根据获得的目录的最大长度,分配内存
if((cur_work_dir=(char*)malloc(cur_work_len))==NULL)
{
    perror("Could not allocate memory for the directory!");
    return 1;
}

//获得当前的工作目录
if (getcwd(cur_work_dir,cur_work_len)==NULL)
{
    perror("Could not get current working directory!");
    return 1;
}

std::cout<<"Current working directory is "<<cur_work_dir<<std::endl;

//修改当前目录至上级目录
if(chdir("..")==-1)
{
    perror("Could not get current working directory!");
    return 1;
}

//获得当前的工作目录
if (getcwd(cur_work_dir,cur_work_len)==NULL)
{
    perror("Could not get current working directory!");
    return 1;
}

std::cout<<"Current working directory is "<<cur_work_dir<<std::endl;
return 0;
}
执行结果
guocheng@guocheng-desktop:~/test/dir_exam/chdir$ ./chdir_exam
Current work length is 4096
Current working directory is /home/guocheng/test/dir_exam/chdir
Current working directory is /home/guocheng/test/dir_exam


四、创建和删除工作目录-mkdir和rmdir
头文件:sys/stat.h    sys/types.h
函数形式:int mkdir(const char* pathname,mode_t mode);
返回值:成功0,失败-1,设置errno
说明:创建的目录的权限由mode、-umask和0777的与值来决定。
下面是实力,在/tmp/guocheng/的目录下创建目录yu,具体代码实现如下:
//mkdir_exam.cxx
#include <sys/stat.h>
#include <sys/types.h>
#include <iostream.h>
int main(void)
{
char* pathname="/tmp/guocheng/yu";
if(mkdir(pathname,0700)==-1)
{
    perror("Could not create the direcotry!");
    return 1;
}
return 0;
}
函数:int rmdir(const char* pathname);
返回值:成功0,失败-1,设置errno。


1、linux文件的实现
索引结点结构(inode)在linxu系统中实现文件的存储和相关信息的保存,每个inode中存储有文件的属性、访问权限以及文件数据块的存储位置。对linux系统而言,inode是文件系统定位文件的基本途径。
左图描述了inode的结构:图中前四项统称为文件的描述信息,其他的信息均为定位文件数据的指针。
文件描述信息主要包括:
Mode:包含有inode的描述内容和用户访问权限;
Owner Infomation:文件或目录所有者的信息,包括所属组信息;
Size:用于记录文件的大小,以字节为单位;
Timesstamps:时间戳,用于记录inode的创建时间及最后的修改时间;
定位文件数据的指针主要包括以下几种:
直接块指针:前12个,直接指向数据块
间接块指针:第13个,指向含有块指针的数据块
双重间接块指针:第14个
三重间接块指针:第15个
inode共有15个块指针的数组,前12为直接指向数据快的指针,第13个是间接数据块指针,指向含有数据块指针的数据块,14和15一次类推。
假设每个指向的数据块的大小是1024字节,每个指针是32位(4字节),下面进行计算文件容量。
直接块指针:12个X1024字节=12K;
间接块指针:1个X(1024字节/4字节)X1024字节=246K;
双重间接块指针:1个X(1024字节/4字节)X(1024字节/4字节)X1024字节=65536K
三重间接块指针:1个X(1024字节/4字节)X(1024字节/4字节)X(1024字节/4字节)1024字节=16777216K,即16G;

2、文件描述符与文件指针
在linux系统中,统一了文件和设备的操作,提供了open、read、close等函数,使用文件描述符来对文件进行操作。文件描述符是一个int类型的数值,在使用open函数操作文件时返回的。
如果某个进程使用open函数打开了一个文件,通过fork函数创建当前进程的子进程,则子进程会继承父进程的环境和上下文的大部分内容,包括已经打开的文件的描述符信息,父进程和子进程将共享相同的文件偏移量。
例程:
#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>



int main(void)

{

//定义字符类型名字为test的字符变量

char test;



//fd用于保存打开文件的文件描述符

int fd;

//使用open函数以只读方式打开名称为test.dat的文件

//如果打开失败则给出相关的失败信息,程序返回

if((fd=open("test.dat",O_RDONLY))==-1)

{

    perror("Can not open the test.dat file!");

    return 1;

}



//使用fork函数产生子进程,如果产生失败给出失败信息,程序返回

if(fork()==-1)

{

    perror("Can not create the child process!");

    return 1;

}



//读取test.dat文件中的一个字符,将其保存在名称为test的字符变量中

read(fd,&test,1);



//输出运行结果,函数getpid会获得进程的进程号

printf("Process ID:%ld read the chatacter :%c\n",(long)getpid(),test);



//关闭文件,注意这里实际会关闭两次

//父子进程将分别执行一次关闭动作

close(fd);

return 0;

}

程序执行结果如下:
guocheng@guocheng-desktop:~/test/fd_exam$ cat test.dat

abcdefgh

guocheng@guocheng-desktop:~/test/fd_exam$ gcc -o fd_exam fd_exam.c

guocheng@guocheng-desktop:~/test/fd_exam$ ./fd_exam

Process ID:7673 read the chatacter :a

Process ID:7672 read the chatacter :b

父进程和子进程分别读取了一个字符,父子进程共享相同的文件描述符,因此父子进程读取的字符是不相同的。

3、文件的访问权限
文件的权限在文件inode的Mode字段的0-8来描述,统称用三位八进制表示。

4、获取文件信息函数
头文件:<sys/types.h>   <sys/stat.h>    <unistd.h>
函数形式:int stat(const char *path,strct stat *buf);
       int fstat(int filedes,struct stat *buf);
       int lstat(const chat *path,strct stat *buf);
返回值:成功0,失败-1,设置errno;
参数:结构体stat说明文件信息,具体含有不做解释。
struct stat
{
dev_t     st_dev     ID of device containing file
ino_t     st_ino     file serial number
mode_t    st_mode    mode of file (see below)
nlink_t   st_nlink   number of links to the file
uid_t     st_uid     user ID of file
gid_t     st_gid     group ID of file
dev_t     st_rdev    device ID (if file is character or block special)
off_t     st_size    file size in bytes (if file is a regular file)
blksize_t st_blksize    a filesystem-specific preferred I/O block size for
                        this object.  In some filesystem types, this may
                        vary from file to file
blkcnt_t  st_blocks  number of blocks allocated for this object

time_t    st_atime   time of last access
time_t    st_mtime   time of last data modification
time_t    st_ctime   time of last status change
}
区别:stat和lstat的区别是当目标是符号连接时,lstat返回的是符号连接的inode信息而不是符号连接指向的文件信息,fstat和stat的区别是第一个参数不同,fstat使用文件描述符做参数。
函数例程:
#include <stdio.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <unistd.h>



int main(int argc,char* argv[1])

{

//定义类型为stat的机构体file_stat,用于保存获得的文件信息

struct stat file_stat;



//main带参数运行,程序名称是一个参数

//判断程序是否带有一个参数执行,共两个参数,如果不是给出提示

//程序结束运行

if(argc!=2)

{

    printf("Usage :%s filename!\n",argv[0]);

    return 1;

}



//调用stat函数,如果出现错误给出错误信息,程序退出

if(stat(argv[1],&file_stat)==-1)

{

    perror("Can not get the information of the file!\n");

    return 1;

}



//使用POSIX中定义的宏判断是否是常规文件

if(S_ISREG(file_stat.st_mode))

    printf("%s is Regular file,Judeged by S_ISREG\n",argv[1]);



//通过st_mode与S_IFREG的位运算判断是否是目录

if(file_stat.st_mode & S_IFREG)

    printf("%s is a Regular File,Judeged by bits calculate  S_IFREG\n",argv[1]);



//通过S_ISDIR宏判断是否是目录

if(S_ISDIR(file_stat.st_mode))

    printf("%s is a Directory,Judeged by S_ISDIR\n",argv[1]);



//通过st_mode与S_IFDIR的位运算判断是否是目录

if(file_stat.st_mode & S_IFDIR)

    printf("%s is a Directory,Judeged by bits calculate  S_IFDIR\n",argv[1]);



//输出file_stat中的其他文件信息

printf("Ower ID:%d,Group ID:%d\n",file_stat.st_uid,file_stat.st_gid);

printf("Permission:%o\n",file_stat.st_mode & 0x1ff);

printf("Last Access Time:%15s\n",ctime(&file_stat.st_atime));

printf("Last Modification Time:%15s\n",ctime(&file_stat.st_mtime));

printf("Last Status Change Time:%15s\n",ctime(&file_stat.st_ctime));



return 0;

}
程序运行结果:
guocheng@guocheng-desktop:~/test/stat_exam$ ls

a.out  stat_exam.c  stat_exam.c~  test

guocheng@guocheng-desktop:~/test/stat_exam$ ./a.out stat_exam.c

stat_exam.c is Regular file,Judeged by S_ISREG

stat_exam.c is a Regular File,Judeged by bits calculate  S_IFREG

Ower ID:1000,Group ID:1000

Permission:644

Last Access Time:Sun Mar  1 00:32:05 2009


Last Modification Time:Sun Mar  1 00:30:51 2009


Last Status Change Time:Sun Mar  1 00:30:51 2009

guocheng@guocheng-desktop:~/test/stat_exam$ ./a.out test/

test/ is a Directory,Judeged by S_ISDIR

test/ is a Directory,Judeged by bits calculate  S_IFDIR

Ower ID:1000,Group ID:1000

Permission:755

Last Access Time:Sun Mar  1 00:25:37 2009


Last Modification Time:Sun Mar  1 00:25:36 2009


Last Status Change Time:Sun Mar  1 00:25:36 2009




5、修改文件权限函数
头文件:    <sys/stat.h>    <sys/types.h>
函数形式:int chmod(const char *path,mode_t mode);
       int fchmod(int filedes,mode_t mode);
返回值:成功0,失败-1,设置errno;
两个函数的区别在第一个参数,使用宏定义组合设置文件的权限。
例程:
#include <sys/types.h>

#include <sys/stat.h>

#include <stdio.h>



int main(int argc,char* argv[])

{

if(argc!=2)

{

    printf("Error!");

    return 1;

}



//修改文件权限至r--r--r-x

if(chmod(argv[1],S_IRUSR | S_IRGRP | S_IROTH | S_IXOTH)<0)

{

    perror("Can not modify the permission of the file !");

    return 1;

}



return 0;

}
执行结果:
guocheng@guocheng-desktop:~/test/chmod_exam$ ls -al test

---------- 1 guocheng guocheng 0 2009-03-01 00:50 test

guocheng@guocheng-desktop:~/test/chmod_exam$ ./a.out test

guocheng@guocheng-desktop:~/test/chmod_exam$ ls -al test

-r--r--r-x 1 guocheng guocheng 0 2009-03-01 00:50 test

6、修改文件拥有者函数
头文件:    <sys/stat.h>    <sys/types.h>
函数形式:int chown(const char *path,uid_t owner,gid_t,group);
       int fchown(int fd,uid_t owner,gid_t,group);
       int lchown(const char *path,uid_t owner,gid_t,group);
返回值:成功0,失败-1,设置errno;

7、Umask函数
头文件:    <sys/stat.h>    <sys/types.h>
函数形式:mode_t umask(mode_t mask);
返回值:总是执行成功返回修改前的umask值

#include <sys/stat.h>

#include <sys/types.h>

#include <fcntl.h>

#include <stdio.h>



int main(void)

{

int fd1,fd2;

struct stat file_stat;



fd1=open("test",O_CREAT | O_RDWR,0777);

if(fd1<0)

{

    perror("Can not create the test file!");

    return 1;

}

close(fd1);

if(stat("test",&file_stat)==-1)

{

    perror("Can not get the information fo the test file!");

    return 1;

}

printf("Permission is %o\n",file_stat.st_mode & 0x1ff);



//修改umask值077

umask(S_IWGRP | S_IRGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);



fd2=open("test1",O_CREAT | O_RDWR,0777);

if(fd2<0)

{

    perror("Can not create the test1 file!");

    return 1;

}

close(fd2);

if(stat("test1",&file_stat)==-1)

{

    perror("Can not get the information fo the test1 file!");

    return 1;

}

printf("Permission is %o\n",file_stat.st_mode & 0x1ff);



return 0;

}
执行结果:
guocheng@guocheng-desktop:~/test/umask_exam$ vi umask_exam.c

guocheng@guocheng-desktop:~/test/umask_exam$ gcc umask_exam.c

guocheng@guocheng-desktop:~/test/umask_exam$ ./a.out

Permission is 755

Permission is 700



分享到:
评论

相关推荐

    意天文件恢复大师

    ‘意天文件恢复大师’是一款Windows操作系统下的文件恢复软件 【基本介绍】  数据恢复。‘意天文件恢复大师’是一款Windows操作系统下的文件恢复软件,其软件精小而功能强大。 【软件特色】 1、当您不小心删除...

    C语言-文件-知识要点.pdf

    "C语言文件处理知识要点"是一份关于C语言文件处理的详细知识资源,涵盖了C语言中与文件操作相关的重要概念、技巧和用法。文件处理在编程中是一个基础且关键的部分,能够帮助开发者读取、写入和操作各种类型的文件,...

    操作系统课件(操作系统详细讲解)

    该资源为操作系统的课件,概括了操作系统一书的内容,是同学们学习的好资料

    文件控制程序(43).doc

    5.1.1.2程序文件:即二级文件,对管理体系过程所涉及的活动进行概括性描述,规定这 些活动的途径。 5.1.1.3支持性文件:即三级文件,明确具体的工作规范和标准,规范作业性的管理活动 ,具体规定相关作业的指导与...

    公司文件控制程序.docx

    质量手册阐明了公司质量方针和质量目标,并对公司质量体系进行纲领和概括性的描述。 程序文件,主要描述为实施过程所涉及各职能部门的活动,是为完成某项活动而规定途径的文件。 公司文件控制程序全文共5页,当前为...

    文件管理控制程序.doc

    3.3.5作业指导书:它从程序文件中引申出来,详细叙述各部门运作过程及操作规程,它 是程序文件的支持性内容。 4 职责 4.1 总经理或董事长:批准工厂的质量方针/目标、质量手册、程序文件。 4.2 管理者代表:负责...

    文件管理控制程序06949.doc

    作业指导书:它从程序文件中引申出来,详细叙述各部门运作过程及操作规程,它是程 序文件的支持性内容。 4 职责 总经理或董事长:批准工厂的质量方针/目标、质量手册、程序文件。 管理者代表:负责制定质量手册及...

    最新文件管理控制程序.pdf

    3.3.5作业指导书:它从程序文件中引申出来,详细叙述各部门运作过程及 操作规程,它是程序文件的支持性内容。 4 职责 4.1 总经理或董事长:批准工厂的质量方针/目标、质量手册、程序文 件。 4.2 管理者代表:负责...

    验厂汇编--文件管理控制程序.doc

    " "3.3.5作业指导书:它从程序文件中引申出来,详细叙述各部门运作过程及操作规程,它 " "是程序文件的支持性内容。 " "4 职责 " "4.1 总经理或董事长:批准工厂的质量方针/目标、质量手册、程序文件。 " "4.2 ...

    文件管理控制程序(7).doc

    3.3.5作业指导书:它从程序文件中引申出来,详细叙述各部门运作过程及操作规程,它 是程序文件的支持性容。 4 职责 4.1 总经理或董事长:批准工厂的质量方针/目标、质量手册、程序文件。 4.2 管理者代表:负责...

    Linux字符设备驱动(转载)

    可以使用与普通文件相同的文件操作命令对字符设备文件进行操作,例如打开、关闭、读、写等 字符设备是最基本、最常用的设备。概括的说,字符设备驱动主要要做三件事:1、定义一个结构体static struct file_...

    文件管理控制程序(1).doc

    3.3.5作业指导书:它从程序文件中引申出来,详细叙述各部门运作过程及操作规程,它 是程序文件的支持性内容。 4 职责 4.1 总经理或董事长:批准工厂的质量方针/目标、质量手册、程序文件。 4.2 管理者代表:负责...

    文件管理控制程序(5).doc

    3.3.5作业指导书:它从程序文件中引申出来,详细叙述各部门运作过程及操作规程,它 是程序文件的支持性内容。 4 职责 4.1 总经理或董事长:批准工厂的质量方针/目标、质量手册、程序文件。 4.2 管理者代表:负责...

    文件管理控制程序(2).doc

    3.3.5作业指导书:它从程序文件中引申出来,详细叙述各部门运作过程及操作规程,它 是程序文件的支持性内容。 4 职责 4.1 总经理或董事长:批准工厂的质量方针/目标、质量手册、程序文件。 4.2 管理者代表:负责...

    文件控制程序(42).doc

    3.3.2 三级文件(即操作规范、检验规范等),由体系框架内管理者代表以下之各部门最 高负责人审核。 3.4 文件的批准: 3.4.1 质量环境手册、程序文件由总经理批准。 3.4.2 三级文件(作业指导书即操作规范、检验规范等)...

    文件管理控制程序(4).doc

    3.2.3质量手册:质量管理体系的纲领性文件,它概括了本工厂质量管理体系的构成及 要素(过程)。 3.2.4程序文件:直接支撑质量手册的主要体系文件,是对各部门运作过程及质量体系 要求的具体说明。 3.2.5作业指导书...

    公司文件控制程序(1).doc

    4.1.2质量手册阐明了公司质量方针和质量目标,并对公司质量体系进行纲领和概括性的 描述。 4.1.3程序文件,主要描述为实施过程所涉及各职能部门的活动,是为完成某项活动而规 定途径的文件。 4.1.4作业指导书和各类...

    文件控制程序(12).doc

    3.3.5工作指示文件(三阶文件):它从程序文件中引申出来,详细叙述各部门运作过 程及操作规程,它是程序文件的支持性内容,如(规范、作业指导书、QC工程图等)。 3.3.6技术文件:属于三阶文件,包括工艺图纸、QC...

    文件控制程序(37).doc

    4.4质量手册:对质量体系作概括表述、阐述及指导质量体系实践的主要文件,是企业质 量管理和质量保证 活动应长期遵循的纲领性文件; 4.5程序文件:是为进行某项活动或过程而规定的途径形成的文件,是各职能部门为...

    JSP上课课件--文件操作

    老师上课用的课件.对JSP知识点的概括.很棒

Global site tag (gtag.js) - Google Analytics