2011: Day 33

RIP Dennis Ritchie, Who helped give us *nix, C, and ergo PHP and a miriad of other languages and wonders. Todays creativity has been a bit of old school programming.

Type: Programming

Format: C

Info: In Memory of Dennis Ritchie who gave us so much.

#include “config.h”

#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/ioctl.h>

main(int argc,char *argv[])
{
int status;
int length,alive_fd,sock_fd,dieing;
struct sockaddr_un sa;
char dummy;
fd_set fds;
struct timeval timeout;

stack_start=(char *)malloc(1000);
stack=stack_start;

if (strcmp(angel_name,argv[0])) {
if (!argv[1]) {
sprintf(stack,”%d”,DEFAULT_PORT);
execlp(“bin/angel”,angel_name,stack,0);
}
else {
argv[0]=angel_name;
execvp(“bin/angel”,argv);
}
error(“exec failed”);
}

if (nice(5)<0) error(“Failed to renice”);

t=time(0);
time_out=t+60;

signal(SIGPIPE,sigpipe);
signal(SIGHUP,sighup);
signal(SIGQUIT,sigquit);
signal(SIGILL,sigill);
signal(SIGFPE,sigfpe);
signal(SIGBUS,sigbus);
signal(SIGSEGV,sigsegv);
signal(SIGTERM,sigterm);
signal(SIGXFSZ,sigxfsz);
signal(SIGCHLD,sigchld);

while(!die) {
t=time(0);
if (crashes>=4 && time_out>=t) {
log(“error”,”Total barf.. crashing lots… Giving up”);
exit(-1);
}
else if (time_out<t) {
time_out=t+45;
crashes=0;
}
crashes++;
log(“angel”,”Forking to boot server”);
dieing=0;
ewtoo=fork();
switch(sysmon) {
case 0:
argv[0]=server_name;
execvp(“bin/sysmon”,argv);
error(“failed to exec server”);
break;
case -1:
error(“Failed to fork()”);
break;
default:

unlink(SOCKET_PATH);

sock_fd=socket(PF_UNIX,SOCK_STREAM,0);
if (sock_fd<0) error(“failed to create socket”);

sa.sun_family=AF_UNIX;
strcpy(sa.sun_path,SOCKET_PATH);

if (bind(sock_fd,(struct sockaddr *)&sa,sizeof(sa))<0)
error(“failed to bind”);

if (listen(sock_fd,1)<0) error(“failed to listen”);

timeout.tv_sec=120;
timeout.tv_usec=0;
FD_ZERO(&fds);
FD_SET(sock_fd,&fds);
if (select(FD_SETSIZE,&fds,0,0,&timeout)<=0) {
kill(sysmon,SIGKILL);
log(“angel”,”Killed server before connect”);
wait(&status);

}
else {

length=sizeof(sa);
alive_fd=accept(sock_fd,(struct sockaddr *)&sa,&length);
if (alive_fd<0) error(“bad accept”);
close(sock_fd);
while(wait3(&status,WNOHANG,0)<=0) {
timeout.tv_sec=300;
timeout.tv_usec=0;
FD_ZERO(&fds);
FD_SET(alive_fd,&fds);

if (select(FD_SETSIZE,&fds,0,0,&timeout)<=0) {
if (errno!=EINTR) {
if (dieing) {
kill(sysmon,SIGKILL);
log(“angel”,”Server KILLED”);
}
else {
kill(sysmon,SIGTERM);
log(“angel”,”Server TERMINATED”);
dieing=1;
}
}
}
else {
if (ioctl(alive_fd,FIONREAD,&length)<0)
error(“bad FIONREAD”);
if (!length) {
kill(sysmon,SIGKILL);
log(“angel”,”Server disconnected”);
dieing=1;
}
else for(;length;length–) read(alive_fd,&dummy,1);

}
}
}

close(alive_fd);
switch((status&255)) {
case 0:
log(“angel”,”Server exited safely”);
break;
case 127:
sprintf(stack,”Server stopped due to signal %d.”,(status>>8)&255);
while(*stack) stack++;
stack++;
log(“angel”,stack_start);
stack=stack_start;
break;
default:
sprintf(stack,”Server terminated due to signal %d.”,status&127);
while(*stack) stack++;
stack++;
log(“angel”,stack_start);
stack=stack_start;
if (status&128) log(“angel”,”Core dump produced”);
break;
}
break;
}
}
}