Skip to content

Instantly share code, notes, and snippets.

@strake
Last active December 24, 2015 17:39
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save strake/6836687 to your computer and use it in GitHub Desktop.
Save strake/6836687 to your computer and use it in GitHub Desktop.
TCP server: spawn arguments with each connection on fds 0, 1
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <err.h>
int setreuseaddr (int s, int v) {
return setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &v, sizeof (int));
}
int main (int argc, char *argu[]) {
struct sockaddr_in6 a = {
.sin6_family = AF_INET6,
.sin6_addr.s6_addr = { 0 },
.sin6_port = argc < 2 ? errx (1, "no port given"), 0
: htons (strtoul (argu[1], 0, 10)),
.sin6_scope_id = 0,
.sin6_flowinfo = 0,
};
int s;
size_t l = sizeof (struct sockaddr_in6);
if (argc < 2) errx (1, "no port given");
if ((s = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0 ||
setreuseaddr (s, 1) < 0 ||
bind (s, (struct sockaddr *)&a, l) < 0 ||
listen (s, SOMAXCONN) < 0) err (1, "failed");
for (;;) {
pid_t pid;
int c, t;
if ((t = accept (s, (struct sockaddr *)&a, &l)) < 0) err (1, "failed to accept");
pid = fork ();
if (pid < 0) err (1, "failed to fork");
if (pid > 0) {
close (t);
waitpid (pid, &c, 0);
continue;
}
{
char acs[40];
inet_ntop (AF_INET6, &a.sin6_addr, acs, 40);
for (int ii = 0; ii < 40; ii++) acs[ii] = toupper (acs[ii]);
setenv ("REMOTE_ADDR", acs, 1);
}
dup2 (t, 0);
dup2 (t, 1);
pid = fork ();
if (pid < 0) err (1, "failed to fork");
if (pid > 0) return 0;
return (execvp (argu[2], argu + 2));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment