ref: 7330e1b9caab783e434e6336dede10d92a34e2e4
parent: 42d06e8de474fe7b0eccb34700dea696faef9eca
author: zamfofex <zamfofex@twdb.moe>
date: Wed Oct 9 02:06:43 EDT 2024
simplify various things
--- a/.build.yml
+++ b/.build.yml
@@ -2,29 +2,25 @@
# copyright 2023, 2024 zamfofex
image: alpine/latest
+
secrets:
- 72a028fc-f8df-43d3-a315-305d80720e45
+
packages:
- build-base
- libressl-dev
- - xz
- - mingw-w64-gcc
- curl
- cjson-dev
- - wasi-sdk
- - clang
- - lld
- - binaryen
+
tasks:
- build: |
cd moonfish
make LDFLAGS=-static
- make LDFLAGS=-static CC=x86_64-w64-mingw32-gcc moonfish.exe
- make LDFLAGS=-static CC='clang --target=wasm32-wasi' CPPFLAGS='-Dmoonfish_no_threads' moonfish.wasm
+
- strip: |
cd moonfish
strip --strip-all moonfish play lichess analyse chat
- wasm-opt -O4 -o moonfish.wasm moonfish.wasm
+
- deploy: |
set +x
@@ -44,6 +40,4 @@
-F "$root"/lichess=@lichess \
-F "$root"/analyse=@analyse \
-F "$root"/chat=@chat \
- -F "$root"/moonfish.exe=@moonfish.exe \
- -F "$root"/moonfish.wasm=@moonfish.wasm \
https://neocities.org/api/upload
--- a/.gitignore
+++ b/.gitignore
@@ -7,7 +7,6 @@
!/README.md
!/makefile
!/.build.yml
-!/check.sh
!/moonfish.vcxproj
!/moonfish.h
!/chess.c
--- a/check.sh
+++ /dev/null
@@ -1,53 +1,0 @@
-#!/usr/bin/env bash
-
-# moonfish is licensed under the AGPL (v3 or later)
-# copyright 2024 zamfofex
-
-set -e
-
-positions=("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -" "8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - -" "r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1" "r2q1rk1/pP1p2pp/Q4n2/bbp1p3/Np6/1B3NBn/pPPP1PPP/R3K2R b KQ - 0 1" "rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8" "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10")-
-diff - <(
- echo 'checking starting position' >&2
- for n in {1..5}- do ./perft -N"$n"
- done
-
- for f in "${positions[@]}"- do
- echo "checking '$f'" >&2
- for n in {1..4}- do ./perft -N"$n" -F"$f"
- done
- done
-) <<END
-perft 1: 20
-perft 2: 400
-perft 3: 8902
-perft 4: 197281
-perft 5: 4865609
-perft 1: 48
-perft 2: 2039
-perft 3: 97862
-perft 4: 4085603
-perft 1: 14
-perft 2: 191
-perft 3: 2812
-perft 4: 43238
-perft 1: 6
-perft 2: 264
-perft 3: 9467
-perft 4: 422333
-perft 1: 6
-perft 2: 264
-perft 3: 9467
-perft 4: 422333
-perft 1: 44
-perft 2: 1486
-perft 3: 62379
-perft 4: 2103487
-perft 1: 46
-perft 2: 2079
-perft 3: 89890
-perft 4: 3894594
-END
--- a/makefile
+++ b/makefile
@@ -4,39 +4,26 @@
CFLAGS ?= -ansi -O3 -Wall -Wextra -Wpedantic
PREFIX ?= /usr/local
BINDIR ?= $(PREFIX)/bin
+RM ?= rm -f
cc := $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
-moonfish_cc := $(cc) -pthread -D_POSIX_C_SOURCE=199309L
-tools_cc := $(cc) -pthread -D_POSIX_C_SOURCE=200809L
-wasm_cc := $(cc) -D_POSIX_C_SOURCE=199309L
+.PHONY: all clean install uninstall
-tools_src := moonfish.h tools/tools.h tools/utils.c chess.c
-
-.PHONY: all clean install uninstall check
-
all: moonfish play lichess analyse chat
-moonfish moonfish.exe: moonfish.h chess.c search.c main.c
- $(moonfish_cc) -o $@ $(filter %.c,$^)
+moonfish: moonfish.h chess.c search.c main.c
+ $(cc) $(filter %.c,$^) -o $@ -pthread -D_POSIX_C_SOURCE=199309L
-moonfish.wasm: moonfish.h chess.c search.c main.c
- $(wasm_cc) -o $@ $(filter %.c,$^)
+%: moonfish.h tools/tools.h tools/utils.c chess.c tools/%.c
+ $(cc) $(filter %.c,$^) -o $@ $(cflags) -D_POSIX_C_SOURCE=200809L
-%: $(tools_src) tools/%.c
- $(tools_cc) -o $@ $(filter %.c,$^)
-
-lichess: $(tools_src) tools/lichess.c tools/https.c
- $(tools_cc) -o $@ $(filter %.c,$^) -ltls -lssl -lcrypto -lcjson
-
-chat: $(tools_src) tools/chat.c tools/https.c
- $(tools_cc) -o $@ $(filter %.c,$^) -ltls -lssl -lcrypto
-
-learn: $(tools_src) search.c tools/learn.c
- $(tools_cc) -Dmoonfish_learn -o $@ $(filter %.c,$^)
-
-check: perft
- ./check.sh
+play analyse: cflags := -pthread
+lichess chat: tools/https.c
+lichess: cflags := -ltls -lssl -lcrypto -lcjson
+chat: cflags := -ltls -lssl -lcrypto
+learn: search.c
+learn: cflags := -Dmoonfish_no_threads -Dmoonfish_learn
clean:
git clean -fdx
--- a/tools/analyse.c
+++ b/tools/analyse.c
@@ -319,6 +319,7 @@
char *buffer;
unsigned int i, length;
int changed;
+ int pv;
fancy = data;
@@ -353,6 +354,8 @@
ply = fancy->plies[fancy->i];
ply.depth = 0;
+ pv = 0;
+
for (;;)
{arg = strtok_r(NULL, "\r\n\t ", &buffer);
@@ -376,11 +379,25 @@
continue;
}
+ if (!strcmp(arg, "multipv"))
+ {+ arg = strtok_r(NULL, "\r\n\t ", &buffer);
+ if (arg == NULL || moonfish_int(arg, &pv) != 0 || pv <= 0)
+ {+ fprintf(stderr, "%s: malformed 'multipv' in 'info' command\n", fancy->argv0);
+ exit(1);
+ }
+
+ continue;
+ }
+
if (!strcmp(arg, "pv"))
{changed = 1;
fancy->idle = 0;
+ if (pv < 1) pv = 1;
+
i = 0;
while (i < sizeof fancy->pv - 1)
{@@ -391,7 +408,16 @@
fprintf(stderr, "%s: invalid move: %s\n", fancy->argv0, arg);
exit(1);
}
- if (i == 0) strcpy(ply.best, arg);
+ if (i == 0 && pv == 1)
+ {+ strcpy(ply.best, arg);
+ }
+ if (pv > 1)
+ {+ ply.chess = move.chess;
+ i = 1;
+ continue;
+ }
moonfish_to_san(&ply.chess, &move, san);
length = strlen(san);
if (i + length > sizeof fancy->pv - 2) break;
@@ -635,8 +661,6 @@
char **options;
int i;
- moonfish_spawner(argv[0]);
-
/* handle command line arguments */
command = moonfish_args(args, format, argc, argv);
@@ -647,18 +671,7 @@
for (;;)
{value = strchr(*command, '=');
- if (value == NULL)
- {- if (!strcmp(*command, "--"))
- {- command_count--;
- command++;
-
- if (command_count <= 0) moonfish_usage(args, format, argv[0]);
- }
-
- break;
- }
+ if (value == NULL) break;
if (strchr(*command, '\n') != NULL || strchr(*command, '\r') != NULL) moonfish_usage(args, format, argv[0]);
@@ -668,6 +681,14 @@
if (command_count <= 0) moonfish_usage(args, format, argv[0]);
}
+ if (!strcmp(*command, "--"))
+ {+ command_count--;
+ command++;
+
+ if (command_count <= 0) moonfish_usage(args, format, argv[0]);
+ }
+
/* initialise data structures */
fancy = malloc(sizeof *fancy);
@@ -698,6 +719,7 @@
fancy->plies[0].checkmate = 0;
fancy->plies[0].depth = 0;
fancy->plies[0].score = 0;
+ fancy->plies[0].best[0] = 0;
moonfish_chess(&fancy->plies[0].chess);
if (args[0].value == NULL)
@@ -791,8 +813,15 @@
/* main UI loop */
- for (ch0 = 0 ; ch0 != EOF ; ch0 = getchar())
+ pthread_mutex_lock(fancy->mutex);
+ for (;;)
{+ pthread_mutex_unlock(fancy->mutex);
+ ch0 = getchar();
+ pthread_mutex_lock(fancy->mutex);
+
+ if (ch0 == EOF) break;
+
if (ch0 != 0x1B) continue;
ch0 = getchar();
if (ch0 == EOF) break;
@@ -805,11 +834,9 @@
if (ch0 == 'A')
{if (fancy->i == 0) continue;
- pthread_mutex_lock(fancy->mutex);
fancy->i = 0;
moonfish_scroll(fancy);
moonfish_go(fancy);
- pthread_mutex_unlock(fancy->mutex);
continue;
}
@@ -817,11 +844,9 @@
if (ch0 == 'B')
{if (fancy->i == fancy->count - 1) continue;
- pthread_mutex_lock(fancy->mutex);
fancy->i = fancy->count - 1;
moonfish_scroll(fancy);
moonfish_go(fancy);
- pthread_mutex_unlock(fancy->mutex);
continue;
}
@@ -829,11 +854,9 @@
if (ch0 == 'C')
{if (fancy->i == fancy->count - 1) continue;
- pthread_mutex_lock(fancy->mutex);
fancy->i++;
moonfish_scroll(fancy);
moonfish_go(fancy);
- pthread_mutex_unlock(fancy->mutex);
continue;
}
@@ -841,11 +864,9 @@
if (ch0 == 'D')
{if (fancy->i == 0) continue;
- pthread_mutex_lock(fancy->mutex);
fancy->i--;
moonfish_scroll(fancy);
moonfish_go(fancy);
- pthread_mutex_unlock(fancy->mutex);
continue;
}
@@ -870,13 +891,11 @@
/* handle scroll up */
if (ch0 == 0x60)
{- pthread_mutex_lock(fancy->mutex);
if (fancy->offset > 0)
{fancy->offset--;
moonfish_fancy(fancy);
}
- pthread_mutex_unlock(fancy->mutex);
continue;
}
@@ -883,13 +902,11 @@
/* handle scroll down */
if (ch0 == 0x61)
{- pthread_mutex_lock(fancy->mutex);
if (fancy->offset < fancy->count / 2 - 6)
{fancy->offset++;
moonfish_fancy(fancy);
}
- pthread_mutex_unlock(fancy->mutex);
continue;
}
@@ -896,9 +913,7 @@
/* "(+)" button clicked */
if (ch0 == 0x20 && y1 == 1 && x1 >= 21 && x1 <= 23)
{- pthread_mutex_lock(fancy->mutex);
moonfish_bump(fancy);
- pthread_mutex_unlock(fancy->mutex);
continue;
}
@@ -905,7 +920,6 @@
/* move name clicked (on scoresheet) */
if (ch0 == 0x20 && y1 >= 2 && y1 <= 7 && x1 >= 21 && x1 <= 40)
{- pthread_mutex_lock(fancy->mutex);
i = (fancy->offset + y1) * 2 - 4;
if (fancy->plies[0].chess.white) i++;
if (x1 > 30) i++;
@@ -914,7 +928,6 @@
fancy->i = i;
moonfish_go(fancy);
}
- pthread_mutex_unlock(fancy->mutex);
continue;
}
@@ -921,7 +934,6 @@
/* "best move" button clicked */
if (ch0 == 0x20 && y1 == 8 && x1 >= 21 && x1 <= 40)
{- pthread_mutex_lock(fancy->mutex);
if (fancy->plies[fancy->i].best[0] != 0)
{if (moonfish_from_uci(&fancy->plies[fancy->i].chess, &move, fancy->plies[fancy->i].best))
@@ -931,7 +943,6 @@
}
moonfish_play(fancy, &move);
}
- pthread_mutex_unlock(fancy->mutex);
continue;
}
@@ -939,8 +950,6 @@
if (x1 < 2 || x1 > 17 || y1 < 1 || y1 > 8) continue;
x1 /= 2;
- pthread_mutex_lock(fancy->mutex);
-
/* mouse down with no square selected: select the square under the mouse */
if (ch0 == 0x20 && fancy->x == 0)
{@@ -947,16 +956,11 @@
fancy->x = x1;
fancy->y = y1;
moonfish_fancy(fancy);
- pthread_mutex_unlock(fancy->mutex);
continue;
}
/* only handle cases where a square is selected henceforth */
- if (fancy->x == 0)
- {- pthread_mutex_unlock(fancy->mutex);
- continue;
- }
+ if (fancy->x == 0) continue;
/* handle mouse down: if the clicked square is the selected square, deselect it */
if (ch0 == 0x20 && x1 == fancy->x && y1 == fancy->y)
@@ -963,7 +967,6 @@
{fancy->x = 0;
moonfish_fancy(fancy);
- pthread_mutex_unlock(fancy->mutex);
continue;
}
@@ -972,7 +975,6 @@
if (moonfish_move_from(&fancy->plies[fancy->i].chess, &move, fancy->x, fancy->y, x1, y1) == 0)
{moonfish_play(fancy, &move);
- pthread_mutex_unlock(fancy->mutex);
continue;
}
@@ -982,11 +984,8 @@
fancy->x = x1;
fancy->y = y1;
moonfish_fancy(fancy);
- pthread_mutex_unlock(fancy->mutex);
continue;
}
-
- pthread_mutex_unlock(fancy->mutex);
}
return 0;
--- a/tools/chat.c
+++ b/tools/chat.c
@@ -341,7 +341,7 @@
int main(int argc, char **argv)
{- static char *format = "<UCI-options> <cmd> <args>...";
+ static char *format = "<UCI-options> [--] <cmd> <args>...";
static struct moonfish_arg args[] =
{ {"N", "host", "<name>", "irc.libera.chat", "network host name (default: 'irc.libera.chat')"},@@ -353,9 +353,7 @@
char **options, **command;
- moonfish_spawner(argv[0]);
-
- /* todo: validate nickname & channels*/
+ /* todo: validate nickname & channels */
options = moonfish_args(args, format, argc, argv);
command = options;
@@ -366,7 +364,9 @@
command++;
}
+ if (!strcmp(*command, "--")) command++;
+
moonfish_chat(argv[0], command, options, args[0].value, args[1].value, args[2].value, args[3].value);
- fprintf(stderr, "%s: Unreachable\n", argv[0]);
+ fprintf(stderr, "%s: unreachable\n", argv[0]);
return 1;
}
--- a/tools/lichess.c
+++ b/tools/lichess.c
@@ -506,8 +506,6 @@
struct tls *tls;
char *username;
- moonfish_spawner(argv[0]);
-
command = moonfish_args(args, format, argc, argv);
command_count = argc - (command - argv);
if (command_count < 1) moonfish_usage(args, format, argv[0]);
--- a/tools/perft.c
+++ b/tools/perft.c
@@ -33,11 +33,10 @@
int main(int argc, char **argv)
{- static char *format = "";
static struct moonfish_arg args[] =
{ {"F", "fen", "<FEN>", NULL, "starting position for the game"},- {"N", "depth", "<ply-count>", "2", "the number of plies to look (default: '2')"},+ {"N", "depth", "<plies>", "2", "the number of plies to search (default: '2')"}, {NULL, NULL, NULL, NULL, NULL},};
@@ -45,17 +44,17 @@
long int depth;
struct moonfish_chess chess;
- if (moonfish_args(args, format, argc, argv) - argv != argc)
- moonfish_usage(args, format, argv[0]);
+ if (moonfish_args(args, NULL, argc, argv) - argv != argc)
+ moonfish_usage(args, NULL, argv[0]);
errno = 0;
depth = strtol(args[1].value, &end, 10);
if (errno != 0 || *end != 0 || depth < 0 || depth >= 24)
- moonfish_usage(args, format, argv[0]);
+ moonfish_usage(args, NULL, argv[0]);
moonfish_chess(&chess);
if (args[0].value != NULL && moonfish_from_fen(&chess, args[0].value))
- moonfish_usage(args, format, argv[0]);
+ moonfish_usage(args, NULL, argv[0]);
printf("perft %ld: %ld\n", depth, moonfish_perft(&chess, depth));--- a/tools/play.c
+++ b/tools/play.c
@@ -3,7 +3,6 @@
#include <unistd.h>
#include <string.h>
-#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
@@ -318,8 +317,6 @@
int error;
char **command;
int command_count;
-
- moonfish_spawner(argv[0]);
command = moonfish_args(args, format, argc, argv);
command_count = argc - (command - argv);
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -15,7 +15,6 @@
char *description;
};
-void moonfish_spawner(char *argv0);
void moonfish_spawn(char **argv, FILE **in, FILE **out, char *directory);
char *moonfish_next(FILE *file);
--- a/tools/utils.c
+++ b/tools/utils.c
@@ -5,464 +5,102 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <pthread.h>
-#include <sys/un.h>
#include <limits.h>
#include "tools.h"
-static pid_t moonfish_spawner_pid;
-static char *moonfish_spawner_argv0;
-static int moonfish_spawner_fd;
-static char *moonfish_spawner_dir_name;
-static char *moonfish_spawner_socket_name;
-
-static void *moonfish_read_pipe(void *data)
+static void moonfish_fork(char **argv, int *in_fd, int *out_fd, char *directory)
{- char ch;
- int *fds;
- fds = data;
- while (read(fds[0], &ch, 1) > 0) { }- if (moonfish_spawner_socket_name != NULL)
- {- if (unlink(moonfish_spawner_socket_name) != 0)
- perror(moonfish_spawner_argv0);
- }
- if (moonfish_spawner_dir_name != NULL)
- {- if (rmdir(moonfish_spawner_dir_name) != 0)
- perror(moonfish_spawner_argv0);
- }
- exit(0);
-}
-
-void moonfish_spawner(char *argv0)
-{- int fd;
- FILE *in, *out;
- pid_t pid;
- int i, count, length;
- char **argv;
- char *directory;
- struct sigaction action;
- pthread_t thread;
- int fds[2], fds2[2];
- struct sockaddr_un address = {0};- char ch;
- ssize_t size;
+ int p1[2], p2[2];
+ int pid;
+ long int count, i;
- moonfish_spawner_argv0 = argv0;
-
- moonfish_spawner_fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (moonfish_spawner_fd < 0)
+ if (pipe(p1) < 0)
{- perror(argv0);
+ perror("pipe");exit(1);
}
-
- if (pipe(fds) != 0)
+ if (pipe(p2) < 0)
{- perror(argv0);
+ perror("pipe");exit(1);
}
- if (pipe(fds2) != 0)
+ pid = fork();
+ if (pid < 0)
{- perror(argv0);
+ perror("fork");exit(1);
}
- moonfish_spawner_pid = fork();
- if (moonfish_spawner_pid < 0)
+ if (pid != 0)
{- perror(argv0);
- exit(1);
- }
-
- if (moonfish_spawner_pid != 0)
- {- close(fds2[1]);
- for (;;)
- {- size = read(fds2[0], &ch, 1);
- if (size > 0) break;
- if (size < 0)
- {- perror(argv0);
- exit(1);
- }
- }
- close(fds2[0]);
+ *in_fd = p1[1];
+ *out_fd = p2[0];
+ close(p1[0]);
+ close(p2[1]);
return;
}
- close(fds2[0]);
- close(fds[1]);
-
- pthread_create(&thread, NULL, &moonfish_read_pipe, fds);
-
- action.sa_flags = SA_NOCLDWAIT;
- action.sa_handler = SIG_DFL;
- if (sigemptyset(&action.sa_mask))
+ if (directory != NULL && chdir(directory) != 0)
{- perror(argv0);
+ perror("chdir");exit(1);
}
- if (sigaction(SIGCHLD, &action, NULL))
- {- perror(argv0);
- exit(1);
- }
- address.sun_family = AF_UNIX;
- strcpy(address.sun_path, "/tmp/moon-XXXXXX");
-
- if (mkdtemp(address.sun_path) == NULL)
+ if (dup2(p1[0], 0) != 0 || dup2(p2[1], 1) != 1 || dup2(p2[1], 2) != 2)
{- perror(argv0);
+ perror("dup2");exit(1);
}
- moonfish_spawner_dir_name = strdup(address.sun_path);
- if (moonfish_spawner_dir_name == NULL)
- {- perror(argv0);
- exit(1);
- }
+ count = sysconf(_SC_OPEN_MAX);
+ for (i = 3 ; i < count ; i++) close(i);
- strcat(address.sun_path, "/socket");
-
- moonfish_spawner_socket_name = strdup(address.sun_path);
- if (moonfish_spawner_socket_name == NULL)
- {- perror(argv0);
- exit(1);
- }
-
- if (bind(moonfish_spawner_fd, (void *) &address, sizeof address) != 0)
- {- perror(argv0);
- exit(1);
- }
-
- if (listen(moonfish_spawner_fd, 8) < 0)
- {- perror(argv0);
- exit(1);
- }
-
- for (;;)
- {- size = write(fds2[1], &ch, 1);
- if (size > 0) break;
- if (size < 0)
- {- perror(argv0);
- exit(1);
- }
- }
- close(fds2[1]);
-
- for (;;)
- {- fd = accept(moonfish_spawner_fd, NULL, NULL);
- if (fd < 0)
- {- perror(argv0);
- exit(1);
- }
-
- pid = fork();
- if (pid < 0)
- {- perror(argv0);
- exit(1);
- }
-
- if (pid == 0) break;
- close(fd);
- }
-
- close(fds[0]);
- close(moonfish_spawner_fd);
-
- in = fdopen(fd, "r");
- if (in == NULL)
- {- perror(argv0);
- exit(1);
- }
-
- out = fdopen(fd, "w");
- if (out == NULL)
- {- perror(argv0);
- exit(1);
- }
-
- if (setvbuf(in, NULL, _IONBF, 0) != 0)
- {- perror(argv0);
- exit(1);
- }
-
- if (setvbuf(out, NULL, _IONBF, 0) != 0)
- {- perror(argv0);
- exit(1);
- }
-
- pid = getpid();
- if (fwrite(&pid, sizeof pid, 1, out) != 1)
- {- perror(argv0);
- exit(1);
- }
-
- if (fread(&length, sizeof length, 1, in) != 1)
- {- perror(argv0);
- exit(1);
- }
-
- if (length < 0)
- {- fprintf(stderr, "%s: invalid length\n", argv0);
- exit(1);
- }
-
- if (length > 0)
- {- directory = malloc(length + 1);
- if (directory == NULL)
- {- perror(argv0);
- exit(1);
- }
-
- directory[length] = 0;
-
- if (fread(directory, length, 1, in) != 1)
- {- perror(argv0);
- exit(1);
- }
-
- if (chdir(directory) != 0)
- {- perror(argv0);
- exit(1);
- }
- }
-
- if (fread(&count, sizeof count, 1, in) != 1)
- {- perror(argv0);
- exit(1);
- }
-
- if (count < 1)
- {- fprintf(stderr, "%s: too few arguments\n", argv0);
- exit(1);
- }
-
- argv = malloc(sizeof *argv * (count + 1));
- if (argv == NULL)
- {- perror(argv0);
- exit(1);
- }
-
- argv[count] = NULL;
-
- for (i = 0 ; i < count ; i++)
- {- if (fread(&length, sizeof length, 1, in) != 1)
- {- perror(argv0);
- exit(1);
- }
-
- argv[i] = malloc(length + 1);
- if (argv[i] == NULL)
- {- perror(argv0);
- exit(1);
- }
- argv[i][length] = 0;
-
- if (fread(argv[i], length, 1, in) != 1)
- {- perror(argv0);
- exit(1);
- }
- }
-
- if (dup2(fd, 0) < 0 || dup2(fd, 1) < 0)
- {- perror(argv0);
- exit(1);
- }
-
- close(fd);
-
- fd = open("/dev/null", O_WRONLY);- if (fd < 0)
- {- perror(argv0);
- exit(1);
- }
-
- if (dup2(fd, 2) < 0)
- {- perror(argv0);
- exit(1);
- }
-
execvp(argv[0], argv);
- fprintf(stderr, "%s: %s: %s\n", argv0, argv[0], strerror(errno));
+ perror("execvp");exit(1);
}
void moonfish_spawn(char **argv, FILE **in, FILE **out, char *directory)
{- pid_t pid;
- int fd;
- int i, count;
- struct sockaddr_un address;
- socklen_t length;
+ int in_fd, out_fd;
- pid = waitpid(moonfish_spawner_pid, NULL, WNOHANG);
- if (pid < 0)
- {- perror(moonfish_spawner_argv0);
- exit(1);
- }
- if (pid != 0)
- {- fprintf(stderr, "%s: spawner exited\n", moonfish_spawner_argv0);
- exit(1);
- }
+ moonfish_fork(argv, &in_fd, &out_fd, directory);
- length = sizeof address;
- if (getsockname(moonfish_spawner_fd, (void *) &address, &length) != 0)
- {- perror(moonfish_spawner_argv0);
- exit(1);
- }
-
- fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (fd < 0)
- {- perror(moonfish_spawner_argv0);
- exit(1);
- }
-
- if (connect(fd, (void *) &address, length) != 0)
- {- perror(moonfish_spawner_argv0);
- exit(1);
- }
-
- *in = fdopen(dup(fd), "w");
+ *in = fdopen(in_fd, "w");
if (*in == NULL)
{- perror(moonfish_spawner_argv0);
+ perror("fdopen");exit(1);
}
- *out = fdopen(dup(fd), "r");
+ *out = fdopen(out_fd, "r");
if (*out == NULL)
{- perror(moonfish_spawner_argv0);
+ perror("fdopen");exit(1);
}
- close(fd);
-
- if (setvbuf(*in, NULL, _IONBF, 0) != 0)
+ errno = 0;
+ if (setvbuf(*in, NULL, _IOLBF, 0))
{- perror(moonfish_spawner_argv0);
+ if (errno != 0) perror("setvbuf");exit(1);
}
- if (setvbuf(*out, NULL, _IONBF, 0) != 0)
+ errno = 0;
+ if (setvbuf(*out, NULL, _IOLBF, 0))
{- perror(moonfish_spawner_argv0);
+ if (errno != 0) perror("setvbuf");exit(1);
}
-
- if (directory == NULL) directory = "";
- count = strlen(directory);
- if (fwrite(&count, sizeof count, 1, *in) != 1)
- {- perror(moonfish_spawner_argv0);
- exit(1);
- }
-
- if (count > 0 && fwrite(directory, count, 1, *in) != 1)
- {- perror(moonfish_spawner_argv0);
- exit(1);
- }
-
- count = 0;
- while (argv[count] != NULL)
- count++;
-
- if (fwrite(&count, sizeof count, 1, *in) != 1)
- {- perror(moonfish_spawner_argv0);
- exit(1);
- }
-
- for (i = 0 ; argv[i] != NULL ; i++)
- {- count = strlen(argv[i]);
- if (fwrite(&count, sizeof count, 1, *in) != 1)
- {- perror(moonfish_spawner_argv0);
- exit(1);
- }
-
- if (fwrite(argv[i], count, 1, *in) != 1)
- {- perror(moonfish_spawner_argv0);
- exit(1);
- }
- }
-
- if (fread(&pid, sizeof pid, 1, *out) != 1)
- {- perror(moonfish_spawner_argv0);
- exit(1);
- }
-
- if (setvbuf(*in, NULL, _IOLBF, 0) != 0)
- {- perror(moonfish_spawner_argv0);
- exit(1);
- }
-
- if (setvbuf(*out, NULL, _IOLBF, 0) != 0)
- {- perror(moonfish_spawner_argv0);
- exit(1);
- }
}
char *moonfish_next(FILE *file)
{static char line[2048];
-
- if (fgets(line, sizeof line, file) == NULL)
- return NULL;
+ if (fgets(line, sizeof line, file) == NULL) return NULL;
return line;
}
@@ -477,8 +115,7 @@
arg = strtok_r(line, "\r\n\t ", &buffer);
if (arg == NULL) continue;
- if (!strcmp(line, name))
- return strtok_r(NULL, "\r\n\t ", &buffer);
+ if (!strcmp(line, name)) return strtok_r(NULL, "\r\n\t ", &buffer);
}
}
@@ -486,6 +123,7 @@
{char *end;
long int long_result;
+
errno = 0;
long_result = strtol(arg, &end, 10);
if (errno != 0 || *end != 0) return 1;
@@ -501,7 +139,6 @@
int col1, col2, n;
if (argv0 == NULL) argv0 = "<program>";
- if (rest_format == NULL) rest_format = "<args>...";
col1 = 0;
col2 = 0;
@@ -525,9 +162,13 @@
if (n > col2) col2 = n;
}
- fprintf(out, "usage: %s <options>... [--] %s\n", argv0, rest_format);
- fprintf(out, "options:\n");
+ if (args[0].letter == NULL && args[0].name == NULL) fprintf(out, "usage: %s", argv0);
+ else fprintf(out, "usage: %s <options>...", argv0);
+ if (rest_format != NULL) fprintf(out, " [--] %s", rest_format);
+ fprintf(out, "\noptions:\n");
+ if (args[0].letter == NULL && args[0].name == NULL) return;
+
for (i = 0 ; args[i].letter != NULL || args[i].name != NULL ; i++)
{fprintf(out, " ");
@@ -596,7 +237,11 @@
if (args[i].format == NULL)
{arg += length;
- if (arg[0] == 0) return 0;
+ if (arg[0] == 0)
+ {+ args[i].value = "";
+ return 0;
+ }
continue;
}
else
@@ -603,8 +248,7 @@
{args[i].value = arg + length;
- if (arg[length] == '=')
- args[i].value = arg + length + 1;
+ if (arg[length] == '=') args[i].value = arg + length + 1;
if (arg[length] == 0)
{@@ -636,8 +280,12 @@
if (args[i].format == NULL)
{- if (arg[length] == 0) return 0;
- if (arg[length] == '=') return 1;
+ if (arg[length] == 0)
+ {+ args[i].value = "";
+ return 0;
+ }
+ return 1;
}
else
{@@ -674,21 +322,27 @@
if (argc <= 0) return argv;
arg = *argv;
+
if (!strcmp(arg, "-")) return argv;
- if (arg[0] != '-') return argv;
- while (arg[0] == '-') arg++;
- if (arg[0] == 0) return argv + 1;
+ if (!strcmp(arg, "--") && rest_format != NULL) return argv + 1;
- if (!strcmp(arg, "help") || !strcmp(arg, "h") || !strcmp(arg, "H"))
+ if (!strcmp(arg, "--help") || !strcmp(arg, "-h") || !strcmp(arg, "-H"))
{moonfish_usage_to(args, rest_format, argv0, stdout);
exit(0);
}
- if (moonfish_letter_arg(args, arg, &argc, &argv) == 0) continue;
- if (moonfish_name_arg(args, arg, &argc, &argv) == 0) continue;
+ if (arg[0] != '-') return argv;
+ arg++;
- moonfish_usage(args, rest_format, argv0);
+ if (arg[0] == '-')
+ {+ arg++;
+ if (moonfish_name_arg(args, arg, &argc, &argv) != 0) moonfish_usage(args, rest_format, argv0);
+ continue;
+ }
+
+ if (moonfish_letter_arg(args, arg, &argc, &argv) != 0) moonfish_usage(args, rest_format, argv0);
}
}
--
⑨