Not permitted to create named pipe

Hello everybody, i have a question. Recently i was writing the simplest program in C to create a named pipe, just to check its functionality. When i was running the open() funtion i constantly got -1 as a return code and observed that the error code was different than EEXIST(which i knew, that i did not have a FIFO in my working directory). Then trying to find the reason and by typing the "mkfifo [fifo_name]" command directly in the working directory, i got the response that i do not have permissions to create a mkfifo in the particular directory(i guess). I failed to find a source to change the permissions and make it possible to create a FIFO, so i am asking you guys. If you can also mention anything theoreticaly-wise, that would be awesome.
Thanks in advance.

Welcome!

What is the file system type?
cd to the directory and run

df -hT .

A Unix might have only

df -k . 

and on the listed /dev/... device run

fstyp /dev/...

(a) Can you create a regular file in that directory (e.g. touch myRandomName)? I don't believe there is anything special as regards permissions with pipes versus files.

(b) Can you create a pipe under /tmp. which should have all the necessary permissions anyway?

(c) Why do you say "different than EEXIST" rather than give the numeric value, or use perror() to have the process report the actual message, or look up the error message by running errno -l, which reports all known error codes in your system by name and number, like:

ENFILE 23 Too many open files in system

(d) You could also post your "simplest program in C" so we can test it ourselves on our various systems.

(e) It would be helpful to know your OS and version: possibly with cat /etc/os-release.

1 Like

Why are you calling open(), and what args do you invoke to create a pipe with it?

The correct system call to open a named pipe (aka FIFO) is mkfifo().

If the external command mkfifo is also failing, the problem is not just your code. Please show the ls -l for the directory you are creating the file in (so we see permissions and ownerships), and echo $? immediately after trying the mkfifo command so we see the exit code. mkfifo also reports an error in text if it fails -- what does yours say ?

mkfifo: cannot create fifo '/bin/myFifo': Permission denied

Changing the permissions of a directory so you can create a FIFO or other file in it would be risky for overall security. Far better to choose a directory that is appropriate for your specific use.

A FIFO can have side effects: for example, if you cat * in a directory containing a fifo, two bad things can happen:

(a) If no process has the fifo open for writing, has it open but is not writing to it, your cat will wait forever for something to be written to it.

(b) If a process does have it open and writes to it, that data is randomly stolen from the process that ought to have read it, and you break something.

A fifo is best placed somewhere out of sight (/tmp or /home/myUsername/.FIFO), and with a name unlikely to be re-used accidentally.

@gopnik13 , post your code please, and the command line(s) used to compile and run the program.

by typing this:
df -hT .

i get this:
Filesystem Type Size Used Avail Use% Mounted on
C:\ drvfs 232G 224G 7.8G 97% /mnt/c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>

int main(int argc, char** argv)
{
    int fifoReturn;
    char* myfifoname = NULL;
    myfifoname = "/myFifoOne";
    fifoReturn = mkfifo(myfifoname, 0666);
    printf("returned from fifo: %d\n", fifoReturn);
    if (fifoReturn == -1)
    {
        printf("returned from fifo: %d\n", fifoReturn);
        printf("ERRNO code from fifo: %d\n", fifoReturn);
        if (errno != EEXIST)
        {
            printf("Could not create FIFO file!\n");
            return 1;
        }   
    }

    printf("Opening...\n");
    int fd = open("myfifo1", O_WRONLY);
    printf("Opened\n");
    int x = 97;
    if (write(fd, &x, sizeof(x)) == -1)
    {
        printf("Failed to write\n");
        return 2;
    }
    printf("Written successfully\n");
    close(fd);
     printf("Closed\n");

    return 0;
}

@gopnik13

Are you working on WINDOWS (version details please ) or *NIX (name and version details please)

I am working on windows 10 and have wsl. The program is written using visual studio code and running it by compiling it in the working directory

yes i am able to create a file and a pipe
i mentioned error code different than EEXIST because i think mkfifo function would return -1 also in case of a FIFO exists

fifoReturn variable holds the success/failure status of the mkfifo call (0 or -1), errno holds the actual error condition, so a call to perror function is appropriate to see the actual text associated with errno

is /myFifoOne even a valid Windows10 filename ? (have no access to a windows OS)

change that block code to something like ....

    if (fifoReturn != 0 )
    {
        printf("mkfifo failure %s, errno: %d\n", myfifoname, errno );
        perror(" reason: ");
        return 1;
    }

show your compiled code running please - copy/paste (no screenshots)

I guess the "drvfs" (NTFS?) does not support special Unix files...

Ubuntu$ ./Fifos
mkfifo failure /myFifoOne, errno: 13
 reason: : Permission denied

having done a quick search online, '/' is not a valid filename character under Windows10 , try another filename myfile.fifo for example

I was reasonably sure that Win10 (probably even Win7) recognised either / or \ as part of the pathname (not part of a filename, but as a directory divider). One everlasting problem is that C strings need all \ to be escaped, so the C string "C:\\myDir\\Foo.txt" corresponds to a file actually called C:\myDir\Foo.txt.

The obvious problem in the OP's code is that /myFifoOne is in the root directory, which will not be writeable by normal users. myFifoOne would work, and I believe ./myFifoOne also would.

I checked that my Linux Mint will use a named FIFO on NTFS just fine (NTFS-3g installed). But what issues come on the back of WSL and DrvFs are (mercifully) beyond my pay scale.

1 Like

My (Linux) man page for mkfifo lists eight different values of errno.

EEXIST does not specifically mean that the FIFO already exists: it means that the name supplied already exists, but it can be any of a directory, symbolic link, fifo, regular file, socket, block device, character device, or the supremely helpful "some other file type".

The EACCES error can happen because any one of the directories in the pathname has incorrect permissions for your user, or is not even a directory.

In you case, I suspect the "/myFifoOne" is being taken to refer to the root directory. You probably intended "./myFifoOne".

1 Like

@gopnik13 , as per @Paul_Pedant ... a filename of ./myFifoOne should do the trick (under WSL), whereas /myFifoOne requires privileges to write to the / directory.