unix系统编程小结(二)------文件和目录

一.对linux的安全机制的一点感悟

         各种权限,read,write,execute,set-user-ID,set-group-ID,sticky bit,对目录的权限,对文件的权限,用于保证系统安全的各种组合技,各种经典。比如,如果我们想unlink一个文件,就必须拥有该文件所在目录的write与execute的权限。

二.两个小例子

         1.当文件有hole时,cp命令会同时拷贝这些hole为'\0'。这里是一个实现了拷贝时跳过文件hole的程序。ps:我用的buffer是一个字节的,效率很低,但如果用大的buffer就会使得hole被移除,使得原先分开的字符被连上。我没想好如何解决这个问题。如果您知道,请您告诉小弟我,非常感谢!

#include <apue.h>
#include <my_error.h>
#include <fcntl.h>

int main()
{
    char buf[1];
    int fd,fd_to;
    int n;
    if( (fd=open("temp_in_hole",O_RDWR) )<0)
        err_sys("error open");
    if( (fd_to=open("temp_OUT_hole",O_WRONLY))<0 )
        err_sys("error open for ");
    while( (n=read(fd,buf,1))!=0 )
    {
        if(buf[0]!='\0') 
            if(write(fd_to,buf,1)!=n)
                err_sys("error write");
    }
    close(fd);
    close(fd_to);
    return 0;
}

         2.遍历目录。这里只贴出主要代码:   ps:有一个技巧就是每遇到一个目录时,就用chdir将该目录设置为当前的工作目录,可以提高程序运行的效率。

static int dopath(Myfunc * func)
{
    struct stat    statbuf;
    struct dirent  *dirp;
    DIR            *dp;
    int            ret;
    char           *ptr;

    if(lstat(fullpath,&statbuf)<0)
        return (func(fullpath,&statbuf,FTW_NS));
    if(S_ISDIR(statbuf.st_mode)==0)
        return (func(fullpath,&statbuf,FTW_F));

    if( (ret=func(fullpath,&statbuf,FTW_D))!=0 )
        return ret;

    ptr=fullpath+strlen(fullpath);
    *ptr++='/';
    *ptr=0;

    if(chdir(fullpath)<0)
        err_ret("chdir for %s failed!",fullpath);
    if((dp=opendir("./"))==NULL)
        return (func(fullpath,&statbuf,FTW_DNR));
    while((dirp=readdir(dp))!=NULL)
    {
        if(strcmp(dirp->d_name,".")==0 || strcmp(dirp->d_name,"..")==0) 
            continue;
        strcpy(ptr,dirp->d_name);
        if(ret=dopath(func)!=0)
            return ret;
    }
    ptr[-1]=0;
    if(closedir(dp)<0)
        err_ret("can't close directory %s",fullpath);
    if(chdir("../")<0)
        err_ret("chdir for ../ failed!");
    return ret;
}

三.一些笔记

         相关的system call很多,具体的用法我就不列出来了,只列出一些我在看书过程中的笔记(有些是摘自apue)。

         1.there is no distinction to the UNIX kernel whether this data is text or binary.

    2.FIFO is a type of file used for communication between processed.It's sometimes called a named pipe.

         3.if we used the stat function,we would never see symbolic links.用lstat才能处理symbolic links.

    4. set-user-ID:这个概念要特别注意。比如说,当一个文件被设置了set-user-ID后,而这个文件的owner是root,然后用一个非root的进程执行这个文件,那么该文件所执行的进程也将拥有root权限。比如说passwd命令就是一个set-user-ID程序。任何用户都可以修改密码,但/etc/passwd只能是root才有write的权利,所以这时set-usr_ID就可以发挥作用,让所有执行passwd的进程都可以向/etc/passwd中write。

         5.whenever we want to open any type of file by name ,we must have execute permission in each directory mentioned in the name,including the current directory,if it is implied.This is why the execute permission bit for a directory is often called the search bit.这个比较好理解,对于一个目录来说,自然不可能去执行目录,所以目录的可执行性就是为了执行该目录下的文件作基础。

    6.目录的read权限仅仅是获得a list of all the filenames in the directory.目录的read权限与执行权限是很不相同的。

    7.we cannot create a new file in a directory unless we have write permission and execute permission in the directory.

    8.To delete an existing file,we need write permission and execute permission in the directory containing the file.We do not need read permission or write permission for the file itself.以前没有注意目录与文件之间的这样的权限的联系。

    9.当用gcc编译生成一个二进制文件后,用chmod u+s来设置set-user-ID。 当再用gcc更新该二进制文件后,set-user-ID就会消失

    10.read系统调用读的内容是不会自动加上'\0'的,所以在使用printf输出该内容的时候要手动加上'\0'

    11.open(filename,O_TRunC).就可以清空文件filename

    12.The i-nodes are fixed-length entries that contain most of the information about a file.Most of the information in the stat structure is obtained from the i-node.

    13.对目录做硬链接有可能使得文件系统出现循环,而这个循环是处理文件系统的很多工具都无法解决的。所以非常多的UNIX实现版本都不允许对目录做硬链接。apue上4.16有出现循环的例子

    14.We've mentioned before that to unlink a file,we must have write permission and execute permission in the directory containing the directory entry,as it is the directory entry that we will be removing.Also,we mentioned in Section 4.10(in apue)that if the sticky bit is set in this directory we must have write permission for the directory and one of the following:Own the file;Own the directory;Have superuser privileges.

    15.A symbolic link is an indirect pointer to a file,unlike the hard links,which pointed directly to the i-node of the file.

    16.

?
ln -s ../foo link_file   这里的../foo可以是不存在的文件,然后就像绝对路径一样,link_file 直接指向../foo。
例子:foo是一个目录。
ln -s ../foo foo/testdir
再ll  foo会显示
drwxr-xr-x 2 root root 4096 2012-12-06 22:37 ./
drwxr-xr-x 3 root root 4096 2012-12-06 22:37 ../
lrwxrwxrwx 1 root root    6 2012-12-06 22:37 testdir -> ../foo/

    17.All the information in the i-node is stored separately from the actual contents of the file.

    18.A directory is simply a file containing directory entries:filenames and associated i-node numbers.

    19.

?
typedef 的一个用法:  
  typedef  int  Func( int  a, int  b);  //这声明了一个新的函数类型,Func,这种函数类型有两个int类型的参数,返回值也是int类型
  static  Func  my_func1;   //my_func1的函数原型,完整的写法是static int my_func1(int a ,int b);  在这里使用typedef,会使得代码更加简洁,清晰,对代码的可读性有好处

    20.

?
char  *p;   *p++= '0' ;  是将*p赋值为 '0' 后,p指针再加1个单位的地址
                  *++p= '0' ;  是先将p执行加一个单位的地址后,再将*p赋值为 '0' ;   这是一个比较容易混淆和容易记错的地方

    21.char *ptr;  ptr[-1]是指是的ptr指向位置的上一个元素。

    22.The current working directory is an attribute of a process .

    23. If we try,using either open or creat,to create a file that alredy exists,the file's access permission bits are not changed but the files were truncated(被清空).  

    24.The size of a directory should never be 0,since there should always be entries for dot and dot-dot.The size of a symbolic link is the number of characters in the pathname contained in the symbolic link,and this pathname must always contain at least one character.

    25.time ./pro1 计算整个pro1程序执行的时间

    26.The kernel has no inherent limit on the depth of a directory tree.But many commands will fail on pathnames that exceed PATH_MAX,比如getcwd.

   参考资料:apue

    如果您觉得我的文章对您有帮助,请顶一下,非常感谢!


你可能感兴趣的:(unix系统编程小结(二)------文件和目录)