about summary refs log tree commit diff
path: root/collect.c
diff options
context:
space:
mode:
Diffstat (limited to 'collect.c')
-rw-r--r--collect.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/collect.c b/collect.c
index cf32283..a092555 100644
--- a/collect.c
+++ b/collect.c
@@ -20,39 +20,55 @@
 
 #include "stdlib.c"
 
-static uint64_t stack_size;
+static uint32_t stack_size;
 static int output_file = -1;
 
 /*
  * Get an environment variable and parse as a number.
  * Return 0 on error.
  */
-uint64_t getenvull(const char *name)
+uint32_t getenvul(const char *name)
 {
-	const char *const s = getenv(name);
-	if (s == NULL)
+	const char *const str = getenv(name);
+	if (str == NULL)
 		return 0ULL;
 	errno = 0;
-	const uint64_t u = strtoull(s, NULL, 0);
+	const uint32_t ul = strtoul(str, NULL, 0);
 	if (errno)
 		return 0ULL;
-	return u;
+	return ul;
 }
 
 void init(int argc, const char *const *argv, char **envp)
 {
 	environ = envp;
-	stack_size = getenvull("TAOSC_STACK_SIZE");
+	stack_size = getenvul("TAOSC_STACK_SIZE");
 	const char *const path = getenv("TAOSC_OUTPUT");
 	if (path != NULL)
 		output_file = open(path, O_WRONLY | O_CREAT, 0644);
-	if (output_file == -1)
-		output_file = 2; /* stderr */
+	if (output_file == -1) {
+		const char *msg = "cannot open $TAOSC_OUTPUT for writing\n";
+		write(2, msg, strlen(msg));
+		fsync(2);
+		exit(128);
+	}
 }
 
 void log(const struct STATE *state)
 {
+
+	static mutex_t mutex = MUTEX_INITIALIZER;
+	while (mutex_lock(&mutex) < 0);
 	write(output_file, (const char *)state, sizeof(struct STATE));
+	/*
+	 * struct STATE starts with a 16-bit member flags,
+	 * followed by 64-bit registers, leaving 6 bytes in between.
+	 */
+	const int offset = (int) sizeof(uint32_t) - (int) sizeof(struct STATE);
+	lseek(output_file, offset, SEEK_END);
+	write(output_file, (const char *)&stack_size, sizeof(uint32_t));
+	lseek(output_file, 0, SEEK_END);
 	write(output_file, (const char *)state->rsp, stack_size);
 	fsync(output_file);
+	mutex_unlock(&mutex);
 }