Linux c编程fifo没有理由失败

时间:2015-01-29 19:04:23

标签: c linux

我有两个不同的程序,我想通过FIFO连接,由于某种原因,它不能正常工作。对mkfifo的调用会返回-1,这意味着某些内容无法正确执行。为什么mkfifo会失败?

这是我的代码:

int main(){

    pid_t pid;
    int rv;
    int fd;

    int fifonum;
    char *fifoName = "toServer2";
    fifonum = mkfifo(fifoName, 0666);

    if (fifonum<0){
        printf("\n unable to create a fifo\n");
        exit(-1);
    }

    fd = open(fifoName, O_WRONLY);

    if( (pid=fork()) == -1 )
    {
        printf("fork error, exiting\n");
        exit(1);
    }

    if(pid){

        printf("this is the parent\n");
        write(fd, "1", sizeof(int));
        close(fd);
        wait(&rv);
        printf("child exited with this status %d\n", rv);

    }else{
        printf("this is the child");
        if(execl("child", "child", NULL)==-1){
            printf("execl error");
            exit(1);
        }   
    } 
    return 0;
}

3 个答案:

答案 0 :(得分:1)

如果文件已存在,mkfifo函数将失败。避免此问题的一种方法是在调用mkfifo之前删除该文件。这样,每次运行程序时,都会从一个全新的空FIFO开始。

一般的想法是调用stat来查看FIFO文件是否存在,如果文件存在则删除unlink文件,然后调用mkfifo创建一个新的FIFO。 / p>

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

int createNewFifo( const char *fifoName )
{
    struct stat stats;
    if ( stat( fifoName, &stats ) < 0 )
    {
        if ( errno != ENOENT )          // ENOENT is ok, since we intend to delete the file anyways
        {
            perror( "stat failed" );    // any other error is a problem
            return( -1 );
        }
    }
    else                                // stat succeeded, so the file exists
    {
        if ( unlink( fifoName ) < 0 )   // attempt to delete the file
        {
            perror( "unlink failed" );  // the most likely error is EBUSY, indicating that some other process is using the file
            return( -1 );
        }
    }

    if ( mkfifo( fifoName, 0666 ) < 0 ) // attempt to create a brand new FIFO
    {
        perror( "mkfifo failed" );
        return( -1 );
    }

    return( 0 );
}

int main( void )
{
    if ( createNewFifo( "toServer2" ) < 0 )
        exit( 1 );

    // do something with the fifo ...
}

答案 1 :(得分:0)

我不认为fifonum = mkfifo(fifoName, 0666);会覆盖FIFO特殊文件(如果它阻塞),检查名为toServer2的文件是否全部存在。 (我不知道你的子程序做了什么,或者它是否清理了FIFO文件。)

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>




int main(){

    pid_t pid;
    int rv;
    FILE *  fd;
    FILE *  od;

    int fifonum;
    char *fifoName = "toServer2";
    fifonum = mkfifo(fifoName, 0666);

    if (fifonum<0){
        printf("%d\n", fifonum );
        printf("\n unable to create a fifo\n");
        exit(-1);
    }

    if( (pid=fork()) == -1 )
    {
        printf("fork error, exiting\n");
        exit(1);
    }


    if(pid == 0 ){
        int status;

        fd = fopen(fifoName, "w");
        printf("this is the parent\n");
        fprintf(fd, "3");
        fclose(fd);
        wait(&rv);

        status = remove(fifoName);

        if( status == 0 )
             printf("%s file deleted successfully.\n",fifoName);
        else
        {
        printf("Unable to delete the file\n");
        perror("Error");
        }

    }
    else{

        int c;
        od = fopen(fifoName, "r");
        //fgetc("%d", s);
        c =fgetc(od);
        printf("------%c-------", c );
        fclose(od);



    } 

    return 0;
}

稍微修改程序以将父进程中的3传递给子进程,然后清理特殊的FIFO文件。

答案 2 :(得分:0)

&#34;为什么mkfifo会失败?&#34;直接来自man 3 mkfifo

   EACCES One of the directories in pathname did not allow search (execute) permission.

   EEXIST pathname already exists.  This includes the case where pathname is a symbolic link, dangling or not.

   ENAMETOOLONG
          Either the total length of pathname is greater than PATH_MAX, or an individual filename  component  has  a  length
          greater  than  NAME_MAX.   In  the GNU system, there is no imposed limit on overall filename length, but some file
          systems may place limits on the length of a component.

   ENOENT A directory component in pathname does not exist or is a dangling symbolic link.

   ENOSPC The directory or file system has no room for the new file.

   ENOTDIR
          A component used as a directory in pathname is not, in fact, a directory.

   EROFS  pathname refers to a read-only file system.

您必须检查errno以了解您的情况中的哪些情况(或者,如其他地方所建议的那样,使用perror(),这将咨询errno为您,并根据值选择合适的文本字符串。