A Web Server in a Single printf() Call
A Web Server in a Single printf() Call
Back in 2014, someone posted a challenge: implement a web server using only a single printf() statement. The solution is both horrifying and educational. Let’s break down why it works and what it teaches us.
The Code
#include <stdio.h>
#include <netinet/in.h>
int main() {
int s = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in a = {AF_INET, htons(8080), 0};
bind(s, (struct sockaddr*)&a, sizeof(a));
listen(s, 1);
for(;;) {
int c = accept(s, 0, 0);
printf("\x00" + (
read(c, a, sizeof(a)), // Read request (ignored)
write(c,
"HTTP/1.0 200 OK\r\n"
"Content-Type: text/html\r\n\r\n"
"<h1>Hello from printf()!</h1>",
100),
close(c),
0)); // Returns 0, which prints nothing
}
}
Why This Works
The Comma Operator
In C, the comma operator evaluates all expressions left to right and returns the value of the rightmost expression:
int x = (1, 2, 3, 4); // x = 4
So this monstrosity:
printf("\x00" + (read(...), write(...), close(...), 0));
Actually does:
- Read from socket (ignored)
- Write HTTP response
- Close connection
- Return 0
- Add 0 to address of “\x00”
- Printf a string that’s effectively empty
The printf() technically prints nothing, but we’ve executed all our server logic in its argument expression!
What This Teaches
1. Everything Is an Expression
C allows wild things in expressions. Function calls are expressions. Assignments are expressions. This is powerful and dangerous.
2. System Calls Are Just Functions
// These are just function calls
socket(AF_INET, SOCK_STREAM, 0)
bind(fd, addr, len)
accept(fd, NULL, NULL)
Nothing magical about networking—it’s all function calls to the kernel.
3. HTTP Is Text
The simplest HTTP response:
HTTP/1.0 200 OK
Content-Type: text/html
<h1>Hello!</h1>
That’s it. Just write that string to a socket and you’ve implemented HTTP.
The Real Implementation
For actual code, you’d obviously write:
int main() {
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in address = {
.sin_family = AF_INET,
.sin_addr.s_addr = INADDR_ANY,
.sin_port = htons(8080)
};
bind(server_fd, (struct sockaddr*)&address, sizeof(address));
listen(server_fd, 10);
while (1) {
int client_fd = accept(server_fd, NULL, NULL);
// Read request
char buffer[1024] = {0};
read(client_fd, buffer, sizeof(buffer));
// Send response
const char *response =
"HTTP/1.0 200 OK\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<h1>Hello World</h1>\n";
write(client_fd, response, strlen(response));
close(client_fd);
}
return 0;
}
But where’s the fun in that?
Try It Yourself
Compile and run:
gcc -o server server.c
./server
# Visit http://localhost:8080
Why We Do This
Code golf like this serves a purpose:
- Deepens understanding of how expressions work
- Reveals abstractions: HTTP is just text, sockets are just file descriptors
- Questions assumptions: What actually needs to be complex?
The real lesson: Understanding fundamentals lets you break the rules creatively. Just don’t do this in production.
Unless it’s funny.