#include <liba.h>
-#include <libnet.h>
#include <sys/poll.h>
char* Usage = "dial [OPTIONS] DIALSTR [CMD [ARG...]]";
#include <liba.h>
-#include <libnet.h>
#include <sys/types.h>
-#include <sys/wait.h>
char* Usage = "listen DIALSTR CMD [ARG...]";
+char** Command = NULL;
-void Serve(int cfd, char** argv)
+void OnNewClient(int cfd)
{
int pid = fork();
if (pid < 0)
dup2(cfd, 0);
dup2(cfd, 1);
dup2(cfd, 2);
- exit(execvp(argv[0], argv));
+ exit(execvp(Command[0], Command));
}
close(cfd);
}
return 1;
}
- int sfd = Net_Announce(argv[0]);
- if (sfd < 0)
- {
- fatal("Net_Announce():");
- }
-
- while (!Net_Listen(sfd, 5))
- {
- int cfd;
- if ((cfd = Net_Accept(sfd)) >= 0)
- {
- Serve(cfd, argv+1);
- }
- while (waitpid(-1, 0, WNOHANG) > 0);
- }
- perror("listen");
- close(sfd);
+ Command = argv+1;
+ Net_Serve(argv[0], OnNewClient);
return 0;
}
-$(BINDIR)/screenlock: LIBS += -lnet -lui -lX11 -lXft -lfontconfig
+$(BINDIR)/screenlock: LIBS += -lui -lX11 -lXft -lfontconfig
$(BINDIR)/winmgr: LIBS += -lX11 -lXft -lfontconfig -lXinerama
/*
Garbage Collector Interface
*/
-void* gc_alloc(size_t sz);
-void gc_addref(void* p);
-void gc_delref(void* p);
+void* GC_Allocate(size_t sz);
+void GC_AddRef(void* p);
+void GC_DelRef(void* p);
/*
Option Parsing
int Net_Listen(int fd, int backlog);
int Net_Accept(int fd);
int Net_Dial(char* dialstr);
-
+void Net_Serve(char* dialstr, void (*on_client)(int cfd));
/*
Basic Runtime Facilities
#include <netinet/in.h>
#include <sys/un.h>
#include <netdb.h>
+#include <sys/wait.h>
typedef struct {
char* network;
sock->addr.in.sin_port = htons(strtol(conn.service, NULL, 0));
sock->addr.in.sin_addr = ResolveAddress(conn.address);
sock->fd = socket(AF_INET, SOCK_STREAM, 0);
+ setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int));
}
else if (!strcmp("udp", conn.network))
{
sock->addr.in.sin_port = htons(strtol(conn.service, NULL, 0));
sock->addr.in.sin_addr = ResolveAddress(conn.address);
sock->fd = socket(AF_INET, SOCK_DGRAM, 0);
+ setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int));
}
else if (!strcmp("unix", conn.network))
{
}
return (rv == 0 ? sock.fd : rv);
}
+
+void Net_Serve(char* dialstr, void (*on_client)(int cfd))
+{
+ int sfd = Net_Announce(dialstr);
+ if (sfd >= 0)
+ {
+ while (!Net_Listen(sfd, 5))
+ {
+ int cfd;
+ if ((cfd = Net_Accept(sfd)) >= 0)
+ {
+ on_client(cfd);
+ }
+ while (waitpid(-1, 0, WNOHANG) > 0);
+ }
+ perror("Net_Listen():");
+ close(sfd);
+ }
+ else
+ {
+ fatal("Net_Announce():");
+ }
+}
/* Public Routines
***************************************/
-void* gc_alloc(size_t sz)
+void* GC_Allocate(size_t sz)
{
sz = (sz / sizeof(intptr_t)) + ((sz % sizeof(intptr_t)) ? 1 : 0);
object_t* obj = ecalloc(1, sizeof(object_t) + sz);
return obj->data;
}
-void gc_addref(void* p)
+void GC_AddRef(void* p)
{
log_add((object_t*)p-1, INCREMENT);
}
-void gc_delref(void* p)
+void GC_DelRef(void* p)
{
log_add((object_t*)p-1, DECREMENT);
}