0
/* Includes */
#include <unistd.h>     /* Symbolic Constants */
#include <sys/types.h>  /* Primitive System Data Types */ 
#include <errno.h>      /* Errors */
#include <stdio.h>      /* Input/Output */
#include <stdlib.h>     /* General Utilities */
#include <pthread.h>    /* POSIX Threads */
#include <string.h>     /* String handling */
#include <signal.h>
#include <sys/mman.h>
#include <semaphore.h>  /* Semaphore */
#include <limits.h>
#include <stdint.h>

/* Global Variables */
sem_t* semaphore;
pid_t otherPid;
sigset_t sigSet;
pthread_t tid1;
char file[100];
FILE* fptr;

void childProcess()
{
    
    int value;
    //get semaphore value
    sem_getvalue(semaphore, &value);
    printf("Detailed search file count is %d.\n", value);
    fprintf(fptr, "_Detailed search file count is %d._\n", value);
    printf("Detailed search is grabbing the file. \n");
    fprintf(fptr, "_Detailed search is grabbing the file._ \n");
    sem_wait(semaphore);
    sem_getvalue(semaphore, &value);
    printf("Detailed search file count is %d.\n", value);
    fprintf(fptr, "_Detailed search file count is %d._\n", value);
    //START CRITICAL REGION
    printf("Starting to do a detailed search...\n");
    fprintf(fptr,"_Starting to do a detailed search..._\n");
    for(int i =0; i < 60; ++i){
        printf(".\n");
        fprintf(fptr, ".\n");
        sleep(1);
    }
    //END CRITICAL REGION
    sem_post(semaphore);


    //Exit child process
    printf("Exit detailed search\n");
    fprintf(fptr, "_Exit detailed search_\n");
    _exit(0);
}

void* checkHungChild(void*a)
{
    int* status = a;
    //check if child process is waiting long
    printf("Checking if detailed search is doing O.K.....\n");
    fprintf(fptr, "_Checking if detailed search is doing O.K....._\n");
    sleep(10);
    //check if there is a lock on the semaphore
    if(sem_trywait(semaphore) != 0){
        printf("detailed search appears to be taking a while...\n");
        fprintf(fptr, "_detailed search appears to be taking a while..._\n");
        *status = 1;
    }
    else{
        printf("detailed search appears to be running fine...\n");
        fprintf(fptr, "_detailed search appears to be running fine..._\n");
        *status = 0;
    }
    return NULL;
}
void parentProcess()
{
    
    //Detect hung Child Process and kill it after a timeout
    sleep(2);
    //check if child process is running
    if(getpgid(otherPid) >= 0){
        printf("detailed search is running...\n");
        fprintf(fptr,"_detailed search is running..._\n");
    }
    int value;
    sem_getvalue(semaphore, &value);
    printf("The fast search has a total of %d files related to your input.\n", value);
    fprintf(fptr, "_The fast search has a total of %d files related to your input._\n", value);
   //check if there is a lock on the semaphore
    if(sem_trywait(semaphore) != 0){
        pthread_t tid1;
        int status = 0;
        printf("Detecting if detailed search's hung or running to long to find your file....\n");
        fprintf(fptr, "_Detecting if detailed search's hung or running to long to find your file...._\n");
      //check if child process is running a long time
        if(pthread_create(&tid1, NULL, checkHungChild, &status))
        {
            printf("ERROR creating timer thread\n");
            fprintf(fptr,"_ERROR creating timer thread_\n");
            _exit(1);
        }
        if(pthread_join(tid1,NULL)){
            printf("\n ERROR joining timer thread.\n");
            fprintf(fptr,"\n_ERROR joining timer thread._\n");
            _exit(1);
        }
        if(status ==1){
            //Kill child process
            printf("Stopping detailed search on your computer with ID of %d.\n", value);
            fprintf(fptr, "_Stopping detailed search on your computer with ID of %d._\n", value);
            
            kill(otherPid, SIGTERM);
            printf("detailed search ended.\n");
            fprintf(fptr, "_detailed search ended._\n");

            //Prove that the child process is killed
            printf("Checking if detailed search has been terminated\n");
            fprintf(fptr,"_Checking if detailed search has been terminated_\n");
            sleep(5);
            kill(otherPid,SIGUSR2);
            sleep(1);
            printf("Confirmed detailed search is done.\n");
            fprintf(fptr,"_Confirmed detailed search is done._\n");
            printf("Started a fast search.\n");
            fprintf(fptr, "_Started a fast search._\n");
            //Try to get semaphore
            sem_getvalue(semaphore, &value);
            printf("Your fast search finds %d file(s).\n", value);
            fprintf(fptr, "_Your fast search finds %d file(s)._\n", value);
            if(sem_trywait(semaphore) != 0)
            {
                if(value == 0)
                {
                    sem_post(semaphore);
                    printf("Cleaned up and finally got the file.\n");
                    fprintf(fptr,"_Cleaned up and finally got the file._\n");
                    sem_getvalue(semaphore, &value);
                    printf("The fast search got %d file related to your input.\n", value);
                    fprintf(fptr,"_The fast search got %d file related to your input._\n", value);

                }
                else{
                    printf("Finally got the file.\n");
                    fprintf(fptr,"_Finally got the file._\n");
                }
                //check if the found file is corrupt
                //if so, delete the file
                printf("Your file is %s.\n", file);
                fprintf(fptr,"_Your file is %s._\n", file);
                if(strcmp(file, "file2") == 0){
                    printf("file is corrupted. Deleting file\n");
                    fprintf(fptr,"_file is corrupted. Deleting file_\n");
                    sem_destroy(semaphore);
                }
                
            }
            printf("Exit fast search.\n");
            fprintf(fptr, "_Exit fast search._\n");
                _exit(0);
        }
    }
}
//Utility Methods
void signalHandeler1(int signum){
    
    printf("Caught Signal: %d\n", signum);
    fprintf(fptr,"_Caught Signal: %d_\n", signum);
    printf(" Exit detailed search Process\n");
    fprintf(fptr,"_Exit detailed search Process_\n");
    sem_post(semaphore);
    _exit(0);
}
void signalHandeler2(int signum){
    printf("Singal still alive\n");
    fprintf(fptr,"_Singal still alive_\n");
}

int main(int argc, char* argv[])
{
    fptr = fopen("deadlockoutput.txt", "w+");
    
     pid_t pid;
     //ask for user input and make sure input is not empty
     //and its a real file (file1 does not exist)
  do{
    printf("Please input a real file:   ");
    scanf(" %s", file);
    fprintf(fptr,"_Please input a real file:   %s_", file);
  }while(file==NULL || strcmp(file, "file1") == 0 );
    //create shared semaphore
    semaphore = (sem_t*)mmap(0,sizeof(sem_t), PROT_READ|
    PROT_WRITE,MAP_SHARED|
    MAP_ANONYMOUS, -1, 0);
    
    fprintf(fptr, "## Deadlock Program Log File\n\n");
    
    if(sem_init(semaphore,1,1) != 0){
        printf("failed to create semaphore.\n");
        fprintf(fptr, "_failed to create semaphore._\n");
        exit(EXIT_FAILURE);
    }

    //use fork()
    setvbuf(stdout, NULL,_IOLBF,0); //so redirect works
    pid = fork();
     if (pid == -1)
    {
        // Error: If fork() returns -1 then an error happened (for example, number of processes reached the limit).
        fprintf(stderr,"Can't fork, error %d\n", errno);
        fprintf(fptr,"_Can't fork, error %d_\n", errno);
        exit(EXIT_FAILURE);
    }
     printf("Searching your computer for file!\n");
     fprintf(fptr,"_Searching your computer for file!_\n");
    // OK: If fork() returns non zero then the parent process is running else child process is running
    if (pid == 0)
    {
        printf("fork() returned 0 to run a fast level search\n");
        fprintf(fptr,"_fork() returned 0 to run a fast level search_\n");
        // Run Producer Process logic as a Child Process
        otherPid = getppid();
        childProcess();
    }
    else
    {
        printf("fork() returned non zero number to run a detailed search\n");
        fprintf(fptr,"_fork() returned non zero number to run a detailed search_\n");
        // Run Consumer Process logic as a Parent Process
        otherPid = pid;
        parentProcess();
    }
    
    fclose(fptr);
    //Cleanup
    sem_destroy(semaphore);
    
    

    // Return OK
    return 0;
} 

This program used Semaphore for search a file and avoid the deadlock situation. I need to print out the console output result. However, there is a txt but there are no words inside. Please help. The problem that I followed the step for input and output but there is no result inside of the txt file. This is from the assignment: Print the necessary process data using fprintf to show a log of activities: which processes are running, what resource they are trying to access, whether the resource is available, and whether the process is starved.

  • 3
    That's too much code. Questions seeking debugging help must provide a [mre] with emphasis on *minimal*. Please take the [tour] and read [ask]. – kaylum Oct 13 '21 at 05:52
  • 1
    Why not just replace every `fprintf` with `printf`, remove `fptr` and run `./yourprogram > deadlockoutput.txt 2>&1`. If you want the output to the console as well as redirected to the file, then pipe to `tee`. This presumes a Linux like OS. See [How do I get both STDOUT and STDERR to go to the terminal and a log file?](https://stackoverflow.com/q/363223/3422102) – David C. Rankin Oct 13 '21 at 05:57
  • I have to use fprintf() because it was a requirement for the assignment. – zhaoyun255 Oct 13 '21 at 06:10

0 Answers0