#define _GNU_SOURCE

#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mman.h>

#include <pthread.h>
#include <signal.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int sockets[2];

void *write_thr(void *arg) {
	// Write blocks until setsockopt(SO_SNDBUF).
	write(sockets[1], "\x5c", 1);
}

int main() {
	void *addr;
	int rv;
	uint32_t sndbuf;

	rv = socketpair(AF_LOCAL, SOCK_STREAM, 0, &sockets[0]);
	if (rv != 0) {
		perror("socketpair()");
		exit(EXIT_FAILURE);
	}

	sndbuf = 0xffffff00;
	rv = setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUFFORCE,
			&sndbuf, sizeof(sndbuf));
	if (rv != 0) {
		perror("setsockopt()");
		exit(EXIT_FAILURE);
	}

	pthread_t write_th;
	rv = pthread_create(&write_th, 0, write_thr, NULL);
	if (rv != 0) {
		perror("pthread_create()");
		exit(EXIT_FAILURE);
	}
	usleep(10000);

	// Wake up blocked write.
	rv = setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF,
			&sndbuf, sizeof(sndbuf));
	if (rv != 0) {
		perror("setsockopt()");
		exit(EXIT_FAILURE);
	}
	usleep(10000);

	close(sockets[0]);
	close(sockets[1]);

	return 0;
}
