first commit
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
build/
|
||||||
6
build.bat
Normal file
6
build.bat
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cl ../src/main.cpp -Fe:server.exe -FC -WX -W3 -wd4200 -diagnostics:column -nologo -Zi -D_CRT_SECURE_NO_WARNINGS
|
||||||
|
cd ..
|
||||||
2
project.te
Normal file
2
project.te
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
:OpenCode
|
||||||
|
:Set BinaryUnderDebug "C:/handmade_http/build/server.exe"
|
||||||
22
src/basic.cpp
Normal file
22
src/basic.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#define panicf(...) (fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n"), exit(1))
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct DEFER_ExitScope {
|
||||||
|
T lambda;
|
||||||
|
DEFER_ExitScope(T lambda) : lambda(lambda) {}
|
||||||
|
~DEFER_ExitScope() { lambda(); }
|
||||||
|
DEFER_ExitScope(const DEFER_ExitScope &i) : lambda(i.lambda){};
|
||||||
|
|
||||||
|
private:
|
||||||
|
DEFER_ExitScope &operator=(const DEFER_ExitScope &);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DEFER_ExitScopeHelp {
|
||||||
|
public:
|
||||||
|
template <typename T>
|
||||||
|
DEFER_ExitScope<T> operator+(T t) { return t; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEFER_CONCAT_INTERNAL(x, y) x##y
|
||||||
|
#define DEFER_CONCAT(x, y) DEFER_CONCAT_INTERNAL(x, y)
|
||||||
|
#define defer const auto DEFER_CONCAT(defer__, __LINE__) = DEFER_ExitScopeHelp() + [&]()
|
||||||
108
src/main.cpp
Normal file
108
src/main.cpp
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_NO_MIN_MAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "basic.cpp"
|
||||||
|
|
||||||
|
#pragma comment(lib, "ws2_32")
|
||||||
|
|
||||||
|
char *win32_alloc_error_string(DWORD errorCode) {
|
||||||
|
char* message = NULL;
|
||||||
|
|
||||||
|
size_t size = FormatMessageA(
|
||||||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL,
|
||||||
|
errorCode,
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
(LPSTR)&message,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (size > 0) {
|
||||||
|
char* newline = strchr(message, '\r');
|
||||||
|
if (newline) *newline = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return message; // Remember to LocalFree() this later!
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialize_addrinfo(struct addrinfo *in) {
|
||||||
|
for (struct addrinfo *p = in; p != NULL; p = p->ai_next) {
|
||||||
|
const char *ipkind = "";
|
||||||
|
void *addr = NULL;
|
||||||
|
if (p->ai_family == AF_INET) {
|
||||||
|
sockaddr_in *ipv4 = (sockaddr_in *)p->ai_addr;
|
||||||
|
addr = &(ipv4->sin_addr);
|
||||||
|
ipkind = "IPv4";
|
||||||
|
} else {
|
||||||
|
sockaddr_in6 *ipv6 = (sockaddr_in6 *)p->ai_addr;
|
||||||
|
addr = &(ipv6->sin6_addr);
|
||||||
|
ipkind = "IPv6";
|
||||||
|
}
|
||||||
|
|
||||||
|
char ipstr[INET6_ADDRSTRLEN];
|
||||||
|
inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
|
||||||
|
printf(" %s: %s\n", ipkind, ipstr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
WSADATA wsaData;
|
||||||
|
|
||||||
|
int err_wsa_startup = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||||
|
if (err_wsa_startup != 0) {
|
||||||
|
panicf("WSAStartup failed, error code: %d\n", err_wsa_startup);
|
||||||
|
}
|
||||||
|
defer { WSACleanup(); };
|
||||||
|
|
||||||
|
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
|
||||||
|
panicf("Version 2.2 of Winsock not available.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct addrinfo *servinfo = {};
|
||||||
|
struct addrinfo hints = {};
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
INT err = getaddrinfo(NULL, "8000", &hints, &servinfo);
|
||||||
|
if (err != 0) {
|
||||||
|
panicf("getaddrinfo failed, error code: %s\n", gai_strerrorA(err));
|
||||||
|
}
|
||||||
|
defer { freeaddrinfo(servinfo); };
|
||||||
|
serialize_addrinfo(servinfo);
|
||||||
|
|
||||||
|
|
||||||
|
printf("exiting...\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
int getaddrinfo(const char *node, // e.g. "www.example.com" or IP
|
||||||
|
const char *service, // e.g. "http" or port number
|
||||||
|
const struct addrinfo *hints,
|
||||||
|
struct addrinfo **res);
|
||||||
|
|
||||||
|
struct addrinfo {
|
||||||
|
int ai_flags; // AI_PASSIVE, AI_CANONNAME, etc.
|
||||||
|
int ai_family; // AF_INET, AF_INET6, AF_UNSPEC
|
||||||
|
int ai_socktype; // SOCK_STREAM, SOCK_DGRAM
|
||||||
|
int ai_protocol; // use 0 for "any"
|
||||||
|
size_t ai_addrlen; // size of ai_addr in bytes
|
||||||
|
struct sockaddr *ai_addr; // struct sockaddr_in or _in6
|
||||||
|
char *ai_canonname; // full canonical hostname
|
||||||
|
|
||||||
|
struct addrinfo *ai_next; // linked list, next node
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sockaddr {
|
||||||
|
unsigned short sa_family; // address family, AF_xxx
|
||||||
|
char sa_data[14]; // 14 bytes of protocol address
|
||||||
|
};
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user