💾 Archived View for thrig.me › blog › 2023 › 08 › 01 › append.c captured on 2024-05-10 at 12:22:39.

View Raw

More Information

⬅️ Previous capture (2023-09-08)

-=-=-=-=-=-=-

// append - can fprintf corrupt an "out" file with multiple writes
// happening at the same time? TL;DR yes if the writes are larger than
// the write(2) buffer size
//
//   CFLAGS=-lpthread make append && ./append

#include <err.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

// NOTE only 26 threads are supported due to the 'a' + i thing, if you
// need more than the code will need to be made more complicated to
// write unique characters for each string
#define THREADCOUNT 3U
// NOTE this is (probably) too small to surface the corruption issue
#define STRINGSIZE 99U
// maybe you need more of these to see a problem?
#define TRIALS 10U

void *
writer(void *arg)
{
	char *s              = (char *) arg;
	unsigned long repeat = TRIALS;
	while (repeat--) {
		FILE *fh = fopen("out", "a");
		if (!fh) err(1, "fopen");
		fprintf(fh, "%s", s);
		fclose(fh);
	}
	return NULL;
}

int
main(void)
{
	pthread_t threadid[THREADCOUNT];
	unlink("out"); // nuke previous results
	for (int i = 0; i < THREADCOUNT; i++) {
		char *s = malloc(STRINGSIZE);
		if (!s) err(1, "malloc");
		memset(s, 'a' + i, STRINGSIZE);
		if (pthread_create(&threadid[i], NULL, writer, s) != 0)
			err(1, "pthread_create");
	}
	for (int i = 0; i < THREADCOUNT; i++)
		pthread_join(threadid[i], NULL);
}