While standard sockets (like TCP) require a setup dance involving socket(), bind(), listen(), accept(), and connect() to establish a connection, Unix Domain sockets provide a shortcut when you want to connect two processes that are related (like a parent and a child).

This shortcut is socketpair().

1. Function Prototype

The function creates two sockets that are already connected to each other.

#include <sys/socket.h>
 
int socketpair(int family, int type, int protocol, int sockfd[2]);
// Returns: 0 if OK, -1 on error

Key Arguments:

  • family: Must be AF_LOCAL (or AF_UNIX). This function does not work for AF_INET (TCP/IP).
  • type: Usually SOCK_STREAM (for a TCP-like byte stream) or SOCK_DGRAM.
  • protocol: Must be 0.
  • sockfd: An integer array where the kernel will return the two new file descriptors.
2. How it Works (The “Stream Pipe”)

When you call socketpair, the system returns two descriptors, sockfd[0] and sockfd[1].

  • Everything you write to sockfd[0] can be read from sockfd[1].
  • Everything you write to sockfd[1] can be read from sockfd[0].

This creates a full-duplex channel (data flows in both directions), which the text refers to as a Stream Pipe.

Comparison to pipe():

  • A standard Unix pipe() is historically half-duplex (data flows only one way).
  • socketpair() is full-duplex.
  • Unlike pipe(), socketpair() creates sockets, meaning you can use socket-specific operations like sendmsg() (which is crucial for passing file descriptors, a topic coming up later).
3. Typical Usage Pattern

Since the sockets are unnamed (they don’t have a path like /tmp/socket), they are typically used with fork():

  1. Parent calls socketpair().
  2. Parent calls fork().
  3. Child closes sockfd[0] and uses sockfd[1].
  4. Parent closes sockfd[1] and uses sockfd[0].

Now the parent and child have a private, high-speed, two-way communication channel.

This function is the foundation for passing file descriptors between processes, which is one of the “superpowers” of Unix Domain sockets.