summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Stevenson <kai@kaistevenson.com>2023-03-19 23:20:53 -0700
committerKai Stevenson <kai@kaistevenson.com>2023-03-19 23:20:53 -0700
commite33dc4755fb08ed08f30b5e1af65457556d5bcb7 (patch)
treec075e9c4f076a7772eb5c0665fbd137e2fd6c3ab
parent26321477ae47bbf5d89b651842d8295e9ea9ea5d (diff)
fscomch--communication between multiple chess processes
-rw-r--r--Makefile2
-rw-r--r--src/chess.c (renamed from chess.c)22
-rw-r--r--src/chess.h (renamed from chess.h)0
-rw-r--r--src/chesshelpers.c (renamed from chesshelpers.c)0
-rw-r--r--src/chesshelpers.h (renamed from chesshelpers.h)0
-rw-r--r--src/console.c (renamed from console.c)0
-rw-r--r--src/console.h (renamed from console.h)0
-rw-r--r--src/fscomch.c97
-rw-r--r--src/fscomch.h24
-rw-r--r--src/vector.c (renamed from vector.c)0
-rw-r--r--src/vector.h (renamed from vector.h)0
11 files changed, 144 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 9aa92fd..64b3196 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ CC=gcc
CFLAGS=-I.
generate:
- $(CC) -o chess chess.c vector.c chesshelpers.c console.c $(CFLAGS)
+ $(CC) -o chess src/chess.c src/vector.c src/chesshelpers.c src/console.c src/fscomch.c $(CFLAGS)
install:
cp chess /usr/local/bin/
diff --git a/chess.c b/src/chess.c
index f5881fe..530bc79 100644
--- a/chess.c
+++ b/src/chess.c
@@ -4,6 +4,7 @@
#include "vector.h"
#include "console.h"
#include "chesshelpers.h"
+#include "fscomch.h"
#include "chess.h"
int main(int argc, char **argv) {
@@ -33,6 +34,27 @@ int main(int argc, char **argv) {
}
}
board_t board = init_board(pieces);
+ /* try to acquire a lock on the local matchfile */
+ FILE* matchFile = try_lock_match();
+ match_t match;
+ if (matchFile != NULL) {
+ /* we are acting as the host--await a connection */
+ printf("awaiting connection\n");
+ match = await_match(matchFile, NULL);
+ printf("connection completed. match is %s\n", match.uuid);
+ }
+ else {
+ /* we are joining an existing match */
+ printf("attempting to join existing match\n");
+ match = join_match();
+ if (match.uuid != NULL) {
+ printf("joined match %s\n", match.uuid);
+ }
+ else {
+ printf("error joining match. reload the program\n");
+ }
+ }
+ exit(0);
int turn = 0;
while(1) {
//draw the board, write some info
diff --git a/chess.h b/src/chess.h
index 1d88a6e..1d88a6e 100644
--- a/chess.h
+++ b/src/chess.h
diff --git a/chesshelpers.c b/src/chesshelpers.c
index b64a0f4..b64a0f4 100644
--- a/chesshelpers.c
+++ b/src/chesshelpers.c
diff --git a/chesshelpers.h b/src/chesshelpers.h
index b3a3d21..b3a3d21 100644
--- a/chesshelpers.h
+++ b/src/chesshelpers.h
diff --git a/console.c b/src/console.c
index e675ba2..e675ba2 100644
--- a/console.c
+++ b/src/console.c
diff --git a/console.h b/src/console.h
index c0ca9f7..c0ca9f7 100644
--- a/console.h
+++ b/src/console.h
diff --git a/src/fscomch.c b/src/fscomch.c
new file mode 100644
index 0000000..a9fc27b
--- /dev/null
+++ b/src/fscomch.c
@@ -0,0 +1,97 @@
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/stat.h>
+#include "fscomch.h"
+
+match_t init_match(char* uuid, FILE* streamIn, FILE* streamOut) {
+ match_t match;
+ match.uuid = uuid;
+ match.streamIn = streamIn;
+ match.streamOut = streamOut;
+ return match;
+}
+void destroy_match(match_t match) {
+ free(match.uuid);
+ fclose(match.streamIn);
+ fclose(match.streamOut);
+}
+FILE* try_lock_match() {
+ mkdir("/tmp/chess/", 0777);
+ mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+ int fd = open("/tmp/chess/match", O_RDONLY | O_CREAT | O_EXCL, mode);
+ if (fd == -1) {
+ return NULL;
+ }
+ return fdopen(fd, "r");
+}
+match_t await_match(FILE* matchFile, char* cancelToken) {
+ /* await match UUID */
+ char* uuid = calloc(37, sizeof(char));
+ while (cancelToken == NULL || *cancelToken) {
+ if (fgets(uuid, 37, matchFile) != NULL) {
+ break;
+ }
+ fseek(matchFile, 0, SEEK_SET);
+ struct timespec req;
+ req.tv_sec = 0;
+ req.tv_nsec = awaitMatchNs;
+ printf("sleeping\n");
+ nanosleep(&req, NULL);
+ }
+ /* connect to files created by joining player */
+ char aName[256];
+ char bName[256];
+ snprintf(aName, 256, "/tmp/chess/%s.a", uuid);
+ snprintf(bName, 256, "/tmp/chess/%s.b", uuid);
+ FILE* streamIn = fopen(aName, "r");
+ FILE* streamOut = fopen(bName, "w");
+ /* connection complete, delete the match file and the join lock */
+ remove("/tmp/chess/match");
+ remove("/tmp/chess/matchjoin");
+ return init_match(uuid, streamIn, streamOut);
+}
+match_t join_match() {
+ /* create a join lock so that no one else can join this match */
+ mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+ int fd = open("/tmp/chess/matchjoin", O_WRONLY | O_CREAT | O_EXCL, mode);
+ if (fd == -1) {
+ /* another process is in the process of joining this game */
+ match_t match;
+ return match;
+ }
+ /* this is definitely the only process joining the game
+ proceed to generate a uuid */
+ char* uuid = make_uuid();
+ /* make the .a and .b files based on the uuid */
+ char aName[256];
+ char bName[256];
+ snprintf(aName, 256, "/tmp/chess/%s.a", uuid);
+ snprintf(bName, 256, "/tmp/chess/%s.b", uuid);
+ FILE* streamIn = fopen(bName, "w+");
+ FILE* streamOut = fopen(aName, "w");
+ match_t match = init_match(uuid, streamIn, streamOut);
+ /* send uuid to the host */
+ FILE* matchFile = fopen("/tmp/chess/match", "a");
+ fputs(uuid, matchFile);
+ /* joining match complete, close the descriptor */
+ close(fd);
+ return match;
+}
+char* make_uuid() {
+ char sym[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f'};
+ char* out = calloc(37, sizeof(char));
+ srand(time(NULL));
+ for (int i = 0; i < 36; i++) {
+ if (i == 8 || i == 13 || i == 18 || i == 23) {
+ out[i] = '-';
+ }
+ else {
+ out[i] = sym[rand() % 16];
+ }
+ }
+ out[37] = '\0';
+ return out;
+}
diff --git a/src/fscomch.h b/src/fscomch.h
new file mode 100644
index 0000000..b7900e3
--- /dev/null
+++ b/src/fscomch.h
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#ifndef FSCOMCH
+#define FSCOMCH
+
+/* 1/2 second */
+static const unsigned long int awaitMatchNs = 500000000L;
+/* 1/4 second */
+static const unsigned long int awaitMoveNs = 250000000L;
+
+typedef struct Match {
+ char* uuid;
+ FILE* streamIn;
+ FILE* streamOut;
+} match_t;
+match_t init_match(char* uuid, FILE* streamIn, FILE* streamOut);
+void destroy_match(match_t match);
+/* returns null if the matchfile is already extant */
+FILE* try_lock_match();
+/* creates a new match, waits for it to be joined by another player */
+match_t await_match(FILE* matchFile, char* cancelToken);
+/* joins an existing match */
+match_t join_match();
+char* make_uuid();
+#endif
diff --git a/vector.c b/src/vector.c
index 6ab3bf2..6ab3bf2 100644
--- a/vector.c
+++ b/src/vector.c
diff --git a/vector.h b/src/vector.h
index ea2ddcd..ea2ddcd 100644
--- a/vector.h
+++ b/src/vector.h