Producer-consumer code
Robust code does not assume the first char in buf is not '\0'.

This is a pedantic point, but user IO is a hacker paradise - best to code defensively.

Instead of:

size_t str_len;
while (fgets(buf, sizeof(buf), fp) != NULL) {
  str_len = strlen(buf);
  if(buf[str_len - 1] != '\n')
    printf("Didn't read whole line!\n");
  else {
    buf[str_len - 1] = '\0';


use to prevent undefined behavior (UB) with buf[str_len - 1].

while (fgets(buf, sizeof(buf), fp) != NULL) {
  size_t str_len = strlen(buf);
  if (str_len == 0 || buf[str_len - 1] != '\n') {
    printf("Didn't read whole line or embedded null character detected!\n");
  } else {
    buf[str_len - 1] = '\0';