diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2023-03-19 23:20:53 -0700 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2023-03-19 23:20:53 -0700 |
| commit | e33dc4755fb08ed08f30b5e1af65457556d5bcb7 (patch) | |
| tree | c075e9c4f076a7772eb5c0665fbd137e2fd6c3ab /src/fscomch.c | |
| parent | 26321477ae47bbf5d89b651842d8295e9ea9ea5d (diff) | |
fscomch--communication between multiple chess processes
Diffstat (limited to 'src/fscomch.c')
| -rw-r--r-- | src/fscomch.c | 97 |
1 files changed, 97 insertions, 0 deletions
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; +} |
