Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between O_CLOEXEC and TIOCEXCL

Tags:

c

linux

I use a device on serial port /dev/ttyUSB0 (uses FTDI) and I don't want to leak any file descriptors to other spawned processes so I set the close-on-exec flag on the descriptor. Could you tell me what is the difference between setting O_CLOEXEC while opening:

#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
    int fd, rc;
    fd = open("/dev/ttyUSB1", O_RDWR | O_NOCTTY | O_CLOEXEC);
    if(fd < 0)
    {
        perror("error open:");
        exit(-1);
    }
    rc = close(fd);     
    if(rc != 0)
    {
        perror("error close:");
        exit(-1);
    }

    return 0;
}

And setting close-on-exec with ioctl(fd, TIOCEXCL):

#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
    int fd, rc;

    fd = open("/dev/ttyUSB1", O_RDWR | O_NOCTTY);
    if(fd < 0)
    {
        perror("error open:");
        exit(-1);
    }

    rc = ioctl(fd, TIOCEXCL);
    if(rc != 0)
    {
        perror("error ioctl:");
        exit(-1);
    }

    rc = close(fd);     
    if(rc != 0)
    {
        perror("error close:");
        exit(-1);
    }

    return 0;
}
like image 551
pbn Avatar asked Oct 04 '16 09:10

pbn


1 Answers

The TIOCEXCL does not set the close-on-exec flag (that would be FIOCLEX, or, equivalently, fcntl(fd, F_SETFD, FD_CLOEXEC)).

To answer the question you thought you were asking:

Specifying O_CLOEXEC when you open() a file will set the close-on-exec flag before it returns, saving you another call and, importantly, ensuring that there is no race condition where another thread might call exec() after open() but before the subsequent fcntl().

If you really need to set or unset the flag at any other time (I've never needed to), you can do so with fcntl F_SETFD, passing FD_CLOEXEC or 0 respectively.

like image 163
Toby Speight Avatar answered Nov 19 '22 21:11

Toby Speight