|  | #include <dirent.h>
 | 
  
    |  | #include <errno.h>
 | 
  
    |  | #include <pthread.h>
 | 
  
    |  | #include <signal.h>
 | 
  
    |  | #include <stdio.h>
 | 
  
    |  | #include <stdlib.h>
 | 
  
    |  | #include <string.h>
 | 
  
    |  | #include <unistd.h>
 | 
  
    |  | 
 | 
  
    |  | volatile int signal_count = 0;
 | 
  
    |  | 
 | 
  
    |  | #define SIGNAL_TO_USE SIGPROF
 | 
  
    |  | 
 | 
  
    |  | void signal_handler(int _signal, siginfo_t *_info, void *_ucontext) {
 | 
  
    |  |     signal_count++;
 | 
  
    |  | }
 | 
  
    |  | 
 | 
  
    |  | void *background_thread(void *main_thread_id) {
 | 
  
    |  |     pthread_t main_tid = *(pthread_t *)main_thread_id;
 | 
  
    |  |     while (1) {
 | 
  
    |  |         pthread_kill(main_tid, SIGNAL_TO_USE);
 | 
  
    |  |     }
 | 
  
    |  |     return NULL;
 | 
  
    |  | }
 | 
  
    |  | 
 | 
  
    |  | int main(int argc, char *argv[]) {
 | 
  
    |  |     if (argc < 2) {
 | 
  
    |  |         fprintf(stderr, "Usage: %s <directory>\n", argv[0]);
 | 
  
    |  |         exit(EXIT_FAILURE);
 | 
  
    |  |     }
 | 
  
    |  | 
 | 
  
    |  |     pthread_t tid;
 | 
  
    |  |     pthread_t main_tid = pthread_self();
 | 
  
    |  | 
 | 
  
    |  |     struct sigaction sa = { .sa_flags = SA_RESTART | SA_SIGINFO, .sa_sigaction = signal_handler };
 | 
  
    |  |     sigemptyset(&sa.sa_mask);
 | 
  
    |  |     sigaction(SIGNAL_TO_USE, &sa, NULL);
 | 
  
    |  | 
 | 
  
    |  |     fprintf(stderr, "Set up signal handler!\n");
 | 
  
    |  | 
 | 
  
    |  |     // Create the background thread
 | 
  
    |  |     if (pthread_create(&tid, NULL, background_thread, &main_tid) != 0) {
 | 
  
    |  |         perror("Failed to create thread");
 | 
  
    |  |         exit(EXIT_FAILURE);
 | 
  
    |  |     }
 | 
  
    |  | 
 | 
  
    |  |     // Wait until at least one signal is received
 | 
  
    |  |     while (signal_count == 0);
 | 
  
    |  | 
 | 
  
    |  |     fprintf(stderr, "Received %d signals, calling readdir...\n", signal_count);
 | 
  
    |  | 
 | 
  
    |  |     const char *path = argv[1];
 | 
  
    |  |     DIR *dir = opendir(path);
 | 
  
    |  |     if (dir == NULL) {
 | 
  
    |  |         fprintf(stderr, "Failed to open directory '%s': %s\n", path, strerror(errno));
 | 
  
    |  |         exit(EXIT_FAILURE);
 | 
  
    |  |     }
 | 
  
    |  | 
 | 
  
    |  |     struct dirent *entry;
 | 
  
    |  |     int fileCount = 0;
 | 
  
    |  | 
 | 
  
    |  |     while ((entry = readdir(dir)) != NULL) {
 | 
  
    |  |         if (entry->d_type == DT_REG) {  // Check if the entry is a regular file
 | 
  
    |  |             fileCount++;
 | 
  
    |  |         }
 | 
  
    |  |     }
 | 
  
    |  | 
 | 
  
    |  |     if (errno) { // Check if readdir() set errno
 | 
  
    |  |         fprintf(stderr, "Failed to read directory '%s': %s\n", path, strerror(errno));
 | 
  
    |  |         closedir(dir);
 | 
  
    |  |         exit(EXIT_FAILURE);
 | 
  
    |  |     }
 | 
  
    |  | 
 | 
  
    |  |     printf("The directory '%s' contains %d files.\n", path, fileCount);
 | 
  
    |  | 
 | 
  
    |  |     if (closedir(dir) < 0) {
 | 
  
    |  |         fprintf(stderr, "Failed to close directory '%s': %s\n", path, strerror(errno));
 | 
  
    |  |         exit(EXIT_FAILURE);
 | 
  
    |  |     }
 | 
  
    |  | 
 | 
  
    |  |     return EXIT_SUCCESS;
 | 
  
    |  | }
 |