管道
   
    ==================================================================
    
    
     pipe (建立管道)
    
   
    
     头文件:
    
   
 #include <unistd.h>
    
     定义函数:
    
   
int pipe(int filedes[2]);
    
     函数说明 :
    
   
- 
     pipe()会建立管道, 并将文件描述词由参数 filedes 数组返回. filedes[0]为管道里的读取端,
 
 filedes[1]则为管道的写入端.
    
     返回值:
    
   
- 
     若成功则返回零, 否则返回-1, 错误原因存于 errno 中.
 
 错误代码 EMFILE 进程已用完文件描述词最大量.
 
 ENFILE 系统已无文件描述词可用.
 
 EFAULT 参数 filedes 数组地址不合法.
    
     DEMO:
    
   
#include <stdio.h> 
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
//函数声明
void func(void);
int main(int argc, char const *argv[])
{
    //创建一个无名管道 filedes[0]读取端 filedes[1]写入端
    int filedes[2];
    int ret = pipe(filedes);
    if(-1 == ret)
    {
        perror("pipe error\n");
        return -1;
    }
    //创建一个子进程
    pid_t x = fork();
    
    //子进程
    if(x == 0)
    {
        printf("[%d]this is child process\n", (int)getpid());
        
        //往无名管道写入端写
        char *buf = malloc(25);
        printf("child:");
        //从键盘输入
        bzero(buf, 25);
        fgets(buf, 25, stdin);
        write(filedes[1], buf, strlen(buf));
        
    }
    //父进程
    if(x > 0)
    {
        printf("[%d]this is father process\n", (int)getpid());
        
        //等待子进程退出
        wait(NULL);
        //从无名管道读取端读
        char *buf = malloc(25);
        bzero(buf, 25);
        read(filedes[0], buf, 25);
        printf("[%d]从无名管道子进程中读到的内容:%s",
                        (int)getpid(), buf);
        
    }
    ret = atexit(func);
    if(-1 == ret)
    {
        perror("atexit error\n");
    }
    
    #ifdef _EXIT
        _exit(0); //直接退出
    #else
        exit(0);  //正常退出
    #endif
}
void func(void)
{
    printf("[%d]eixt succeed\n", (int)getpid());
}
    ==================================================================
    
    
     mkfifo ( 建立具名管道 )
    
   
    
     头文件:
    
    
    #include <sys/types.h>
    
    #include <sys/stat.h>
   
    
     定义函数 :
    
   
int mkfifo(const char * pathname, mode_t mode);
    
     函数说明 :
    
   
- mkfifo()会依参数 pathname 建立特殊的 FIFO 文件, 该文件必须不存在, 而参数 mode 为该文件的权限 (mode%~umask), 因此 umask 值也会影响到 FIFO 文件的权限. Mkfifo()建立的 FIFO 文件其他进程都可以用读写一般文件的方式存取. 当使用 open()来打开 FIFO 文件时, O_NONBLOCK 旗标会有影响
- 
     当使用 O_NONBLOCK 旗标时, 打开 FIFO 文件来读取的操作会立刻返回, 但是若还没有其他进
 
 程打开 FIFO 文件来读取, 则写入的操作会返回 ENXIO 错误代码.
- 没有使用 O_NONBLOCK 旗标时, 打开 FIFO 来读取的操作会等到其他进程打开 FIFO 文件来写入才正常返回. 同样地, 打开 FIFO 文件来写入的操作会等到其他进程打开 FIFO 文件来读取后才正常返回.
    
     返回值 :
    
   
- 
     若成功则返回 0, 否则返回-1, 错误原因存于 errno 中.
 
 错误代码 EACCESS 参数 pathname 所指定的目录路径无可执行的权限
 
 EEXIST 参数 pathname 所指定的文件已存在.
 
 ENAMETOOLONG 参数 pathname 的路径名称太长.
 
 ENOENT 参数 pathname 包含的目录不存在
 
 ENOSPC 文件系统的剩余空间不足
 
 ENOTDIR 参数 pathname 路径中的目录存在但却非真正的目录.
 
 EROFS 参数 pathname 指定的文件存在于只读文件系统内.
    ==================================================================
    
    
     access ( 判断是否具有存取文件的权限 )
    
   
    
     头文件 :
    
    
    #include <unistd.h>
   
    
     定义函数 :
    
   
int access(const char * pathname, int mode);
    
     函数说明 :
    
   
- access()会检查是否可以读/写某一已存在的文件. 参数 mode 有几种情况组合, R_OK, W_OK, X_OK和 F_OK. R_OK, W_OK 与 X_OK 用来检查文件是否具有读娶写入和执行的权限. F_OK 则是用来判断该文件是否存在. 由于 access()只作权限的核查, 并不理会文件形态或文件内容, 因此, 如果一目录表示为”可写入”, 表示可以在该目录中建立新文件等操作, 而非意味此目录可以被当做文件处理. 例如, 你会发现 DOS 的文件都具有”可执行”权限, 但用 execve()执行时则会失败.
    
     返回值:
    
   
- 若所有欲查核的权限都通过了检查则返回 0 值, 表示成功, 只要有一权限被禁止则返回-1.
    以下两个demo都得运行
    
    
     DEMO1:
    
   
#include <stdio.h>  
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define FIFO_PATH "/tmp/xxno/mkfifo" 
#define BUF_SIZE 30
int main(int argc, char const *argv[])
{
    //创建有名管道文件:
    if(access(FIFO_PATH, F_OK | W_OK))
    {
        int ret = mkfifo(FIFO_PATH, 0666);
        if(-1 == ret)
        {
            perror("mkfifo error\n");
            return -1;
        }
    }
    //打开管道文件:
    int fd_fifo = open(FIFO_PATH, O_WRONLY);
    if(-1 == fd_fifo)
    {
        perror("open error\n");
        return -1;
    }
    while(1)
    {
        //往管道文件里写内容:
        char *buf = malloc(BUF_SIZE);
        printf("写入管道中:\n");
        fgets(buf, BUF_SIZE, stdin);
        write(fd_fifo, buf, strlen(buf));
    }
    
    //关闭管道文件:
    close(fd_fifo);
    return 0 ;
}
    
     DEMO2:
    
   
#include <stdio.h>  
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define FIFO_PATH "/tmp/xxno/mkfifo" 
#define BUF_SIZE 30
int main(int argc, char const *argv[])
{
    //创建有名管道文件:
    if(access(FIFO_PATH, F_OK | R_OK))
    {
        int ret = mkfifo(FIFO_PATH, 0666);
        if(-1 == ret)
        {
            perror("mkfifo error\n");
            return -1;
        }
    }
    //打开管道文件:
    int fd_fifo = open(FIFO_PATH, O_RDONLY);
    if(-1 == fd_fifo)
    {
        perror("open error\n");
        return -1;
    }
    //往管道文件里写内容:
    while(1)
    {
        char *buf = malloc(BUF_SIZE);
        int ret = read(fd_fifo, buf, BUF_SIZE);
        if(0 == ret)
        {
            break;
        }
        printf("%s\n", buf);
    }
    
    //关闭管道文件:
    close(fd_fifo);
    return 0 ;
}
 
