How to atomically create "close-on-exec" socket on Mac?
Asked Answered
C

1

9

When I create socket on Linux, it's possible to specify the flag O_CLOEXEC on creation time:

auto fd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, 0);

So there is no way, that some other thread will do fork()+exec() with this socket remaining open.

But on Mac, according to the manual, I can't do the same trick:

The socket has the indicated type, which specifies the semantics of communication. Currently defined types are: SOCK_STREAM SOCK_DGRAM SOCK_RAW SOCK_SEQPACKET SOCK_RDM

The flag O_CLOEXEC can only be set with a call to fcntl(). And it's not an atomic way - some thread may do exec() between calls to socket() and fcntl().

How to resolve this issue?

Coverdale answered 19/10, 2013 at 6:30 Comment(0)
P
2

Assuming that you code is using pthreads, consider using the 'pthread_atfork', which make it possible to specify callback for forking. Extending the idea from Alk's post, but implementing the wait in the fork callback.

From the OP, looks like it is possible to control the code that create the sockets (where in Linux it will use SOCK_CLOEXEC), but not possible to control or modify the forking calls.


mutex_t socket_lock ;

main()
{
    ...
    // establish atfork, before starting any thread.
    mutex_t socket_lock = mutex_init(...);
    pthread_atfork(set_socket_lock, release_sock_lock, release_sock_lock) ;
    pthread_create(...) ;
    .. rest of the code ...
}
int socket_wrapper(...)
{
  set_socket_lock() ;

  int sd = socket(..);
  fcntl(sd, O_CLOEXEC);

  release_socket_lock();

  return sd;
}

void set_socket_lock(void)
{
    lock(socket_lock ) ;
}

void release_socket_lock(void)
    unlock(socket_lock ) ;    
}

As an added bonus, the above logic mutex will also cover the case that a fork is called, and while the fork is executing, one of the thread in the parent/child will attempt to create a socket. Not sure if this is even possible, as the kernel might first suspend all threads before starting any of the fork activity.

Disclaimer: I did not try to run the code, as I do not have access to Mac machines.

Posology answered 25/6, 2022 at 12:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.