C: Shell tests work locally, but fail when pushed to remote

Hey Guys. I’m working on the shell challenge to learn C and I’m at the test where we implement for echo. When I run ./your-program.sh directly and input exit 0 , the shell promptly exits. However, when I run the test using codecrafters test , exit somehow fails to work properly.

CODECRAFTERS TEST OUTPUT

Here’s the code`

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "array_list.h"

char* EXIT_COMMAND = "exit";
char* ECHO_COMMAND = "echo";

typedef struct {
  char* command;
  ArrayList* inputs;
} Command;

void free_command(Command* cmd) {
  free(cmd->command);
  free_array_list(cmd->inputs);
  free(cmd);
}

Command* parse_command(char* command) {
  Command* cmd = malloc(sizeof(Command));
  cmd->inputs = new_array_list(10);

  char* token = strtok(command, " ");

  while (token != NULL) {
    int length = strlen(token);
    if (cmd->command == NULL) {
      cmd->command = malloc(sizeof(char) * length);
      strcpy(cmd->command, token);
    } else {
      add_array_list(cmd->inputs, token);
    }
    token = strtok(NULL, " ");
  }

  return cmd;
}

void perform_echo(Command* cmd) {
  if (cmd->inputs == NULL || cmd->inputs->size == 0) {
    return;
  }
  for (int i=0; i<cmd->inputs->size; i++) {
    printf("%s", get_element_from_list(cmd->inputs, i));
    if (i != cmd->inputs->size-1) {
      printf(" ");
    }
  }

  printf("\n");
}

// Captures the user's command in the "command" variable
char command[1024];

int main(int argc, char *argv[]) {
  // Flush after every printf
  setbuf(stdout, NULL);

  while (1)
  {
    printf("$ ");

    // Captures the user's command in the "command" variable
    char command[1024];
    fgets(command, sizeof(command), stdin);

    command[strcspn(command, "\n")] = '\0';

    Command* cmd = parse_command(command);
    if (cmd == NULL) {
      continue;
    }

    if (strcmp(cmd->command, EXIT_COMMAND) == 0) {
      return 0;
    }

    if (strcmp(cmd->command, ECHO_COMMAND) == 0) {
      perform_echo(cmd);
      continue;
    }

    printf("%s: command not found\n", command);

    free_command(cmd);
  }
  
  return 0;
}

array_list.c

#include <stdlib.h>
#include <string.h>
#include "array_list.h"

ArrayList* new_array_list(int capacity) {
    if (capacity <= 0) {
        return NULL;
    }
    
    ArrayList* list = malloc(sizeof(ArrayList));
    if (list == NULL) {
        return NULL;
    }
    
    list->capacity = capacity;
    list->size = 0;
    list->inputs = malloc(capacity * sizeof(char*));
    
    if (list->inputs == NULL) {
        free(list);
        return NULL;
    }

    return list;
}

void add_array_list(ArrayList* list, char* element) {
    if (list == NULL || element == NULL) {
        return;
    }
    
    // Check if we need to resize
    if (list->size >= list->capacity) {
        // Double the capacity
        int new_capacity = list->capacity * 2;
        char** new_inputs = realloc(list->inputs, new_capacity * sizeof(char*));
        
        if (new_inputs == NULL) {
            return; // Failed to resize, could not add element
        }
        
        list->inputs = new_inputs;
        list->capacity = new_capacity;
    }
    
    // Allocate memory for the string copy
    list->inputs[list->size] = malloc((strlen(element) + 1) * sizeof(char));
    if (list->inputs[list->size] == NULL) {
        return;
    }
    
    // Copy the string
    strcpy(list->inputs[list->size], element);
    list->size++;
}

char* get_element_from_list(ArrayList* list, int index) {
    if (list == NULL || index < 0 || index >= list->size) {
        return NULL;
    }
    
    return list->inputs[index];
}

void free_array_list(ArrayList* list) {
    if (list == NULL) {
        return;
    }
    
    // Free all allocated strings
    for (int i = 0; i < list->size; i++) {
        if (list->inputs[i] != NULL) {
            free(list->inputs[i]);
        }
    }
    
    // Free the array of pointers
    free(list->inputs);
    
    // Free the list structure itself
    free(list);
}

int array_list_size(ArrayList* list) {
    if (list == NULL) {
        return -1;
    }
    return list->size;
}

int array_list_capacity(ArrayList* list) {
    if (list == NULL) {
        return -1;
    }
    return list->capacity;
}

I couldn’t attach the local execution output in the question, so here it is