linux unlink() access() mkfifo()使用实例

来源:互联网 发布:南风知我意七微书包网1 编辑:程序博客网 时间:2024/06/15 15:09
函数原型:int unlink( const char * pathname );
所属库:stdio.h
函数功能:删除一个文件的目录项并减少它的链接数,若成功则返回0,否则返回-1,错误原因存于errno。
如果想通过调用这个函数来成功删除文件,你就必须拥有这个文件的所属目录的写和执行权限。


函数原型:int access(const char *filenpath, int mode); 

头文件:unistd.h
功 能: 确定文件或文件夹的访问权限。即,检查某个文件的存取方式,比如说是只读方式、只写方式等。
如果指定的存取方式有效,则函数返回0,否则函数返回-1。
参数说明:
filenpath  文件或文件夹的路径,当前目录直接使用文件或文件夹名
备注:当该参数为文件的时候,access函数能使用mode参数所有的值,当该参数为文件夹的时候,access函数值能判断文件夹是否存在。
mode 要判断的模式
具体含义如下:
R_OK 只判断是否有读权限
W_OK 只判断是否有写权限
X_OK 判断是否有执行权限
F_OK 只判断是否存在

函数原型:int mkfifo(const char * pathname,mode_t mode);
mkfifo ()会依参数pathname建立特殊的FIFO文件,该文件必须不存在,而参数mode为该文件的权限(mode%~umask),
因此 umask值也会影响到FIFO文件的权限。Mkfifo()建立的FIFO文件其他进程都可以用读写一般文件的方式存取。
当使用open()来打开 FIFO文件时,如果设置了O_NONBLOCK标志,必须先有一个读FIFO的端口存在,否则直接报错。
重点注意:
1,unlink 只能删除文件,不能删除目录,当出错时错误代码返回在errno变量里。
2,access 既可以判断文件的权限也可以判断文件夹的权限。
3,mkfifo 生成的管道文件和umask有关,如果生成的文件权限不对可以考虑使用umask(0)开启所以权限的修改。
注意open()函数也是会引起阻塞的,一旦设置了阻塞标志,调用mkfifo建立好之后,那么管道的两端读写必须分别打开,
有任何一方未打开,则在调用open的时候就阻塞如果设置了非阻塞,当读不存在是,写FIFO会返回ENXIO错误。
读打开的阻塞标志只对本进程第一个读操作施加作用,如果本进程内有多个读操作序列,
则在第一个读操作被唤醒并完成读操作后,
其它将要执行的读操作将不再阻塞,即使在执行读操作时,FIFO中没有数据也一样,此时,读操作返回0。

以下是使用实例:
#include                 <stdio.h>   
#include                 <sys/types.h>   
#include                 <sys/stat.h>   
#include                 <string.h>   
#include                 <fcntl.h>   
#include                 <errno.h>   
#include                 <sys/time.h>   
#include                 <unistd.h>   
#include                 <stdlib.h>


#define   FIFO          "/tmp/fifo.temp1"   
#define   MAXLINE       1024   
    
int   main(void)   
{   
   int           fifo,   fd;   
   char         buf[MAXLINE] = {"hello fifo\n"};   
   int           len;   
   fd_set     set;   
   struct     timeval   tv;   
   int           i   =   0;   
   int err = -1;
   int pid = -1;
   int status = 0;


//两种处理文件已经存在的方法
#if 0
    unlink(FIFO);   //如果FIFO存在,就先删?
#else
   if (access(FIFO, F_OK) < 0)  //文件不存在,创建文件
#endif
   {
       umask(0);
       if   ((fifo   =   mkfifo(FIFO,   0666))   <   0)       //产生一个有名管道   
       {   
            printf("mkfifo   error:   %s\n",   strerror(errno));   
            return(0);   
       } 
   }


   if   ((fd   =   open(FIFO,   O_RDWR))   <   0)               //读写打开有名管道   
   {   
        printf("open   error:   %s\n",   strerror(errno));   
        return(0);   
   } 


   pid = fork();
   if (pid < 0)
   {
        perror("fork error");
        return -1;
   }
   else if(pid > 0)
   {
        printf ("[parent] read\n");
        FD_ZERO(&set);   
        FD_SET(fd,   &set);   
        tv.tv_sec   =   5;   
        tv.tv_usec   =   0;   //超时设置,超过5秒没有信息,就打印超时   
        while   (1)   
        {   
            FD_SET(fd,   &set);   
            if   ((i   =   select(fd   +   1,   &set,   NULL,   NULL,   &tv))   >   0)  //检测管道是否信息   
            {   
                printf("[parent] receive   data\n");   
                if   (FD_ISSET(fd,   &set))   
                {   
                    bzero(buf, MAXLINE);
                    len   =   read(fd,   buf,   MAXLINE);//读取信息   
                    buf[len]   =   '\0';   
                    printf("[parent] buf   =   %s\n",   buf);   
                    waitpid(pid, &status, 0);
                    printf ("[parent] status:%d\n", WEXITSTATUS(status));
                    exit(0);
                }   
            }   
            else   if   (i   ==   0)   
            {   
                 tv.tv_sec   =   5;   
                 tv.tv_usec   =   0;   
                 printf("time out\n");   
            }   
            else   
                 printf("error\n");   
        }   
    }
    else
    {
        printf ("[CHILD] child processs write\n");
        write(fd, buf, strlen(buf));


        sleep(1);
        exit(1);
    }
   return(0);   
}  




0 0