2

This program should use fork() to create processes, store the PID of the child process into a singly linked list, after fork fails kill the processes one at a time, then free the nodes in the linked list, and finally print out how many processes were created before ending the program.

Currently it does not do these things and I am not sure where to go with it. It will compile correctly, but when I run it in the Minix terminal that I have to use it does nothing. When I go to shutdown the terminal, I end up getting "shutdown: can't fork(): Resource temporarily unavailable". So something is going wrong and any help would be appreciated. Thank you.

/*
   Problem: Write a complete C-program to determine the number of
   simultaneous processes Minix can support for a single user. Be
   aware that a users' login shell is itself a process. Once this has
   been determined, any processes created will have to be terminated.
   Created processes will have to be kept track of in a singly linked list
   with node structure dynamically allocated at runtime.

   Solution: Create processes until fork() fails. Each child process will
   call pause(). The signal will be delivered by the parent process using
   kill() system call. When fork() fails, terminate the children processes
   one at a time using childs' PID and SIGKILL signal. You will have to
   keep track of children process PIDs in a singly linked list.

   Data-structure used: A singly linked list

   Accessing functions for the data structure: malloc() and free() to
   dynamically handle the node storage

   Errors handled: None.

   Limitations: None.

*/

#define _POSIX_SOURCE
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

struct lnode {
   int pid;
   struct lnode *next;
};

    /* Dynamically allocates node storage at runtime using
       malloc().
    */

struct lnode*
getnode(void)
{
   return malloc(sizeof(struct lnode));
}

/* Frees nodes dynamically allocated by getnode before
   the program is terminated.
*/

void
freenode(struct lnode *tmp)
{
   free(tmp);
}

/* Display the output of how many simultaneous processes Minix
   can support for a single user.
*/

void
printtotal(int count)
{
   fprintf(stdout, "For this user: %d\n", count);
}

int
main(int argc, char *argv[])
{
   struct lnode *curr;
   struct lnode *tmp;
   int count = 1;
   int pidholder = 1;

   tmp = NULL;

   while(pidholder > 0) {
      curr = getnode();

      pidholder = fork();

      if(pidholder < 0)
         exit(-1);
      else if(pidholder == 0)
         pause();
      else if(pidholder > 0) {
         curr->pid = pidholder;
         curr->next = tmp;
         tmp = curr;
      }
   }

   curr = tmp;

   while(curr) {
      pidholder = curr->pid;

      kill(pidholder, SIGKILL);

      tmp = curr;
      curr = curr->next;
      freenode(tmp);
   }

   printtotal(count);

   exit(0);
}
mimiG
  • 21
  • 1

1 Answers1

0

I figured out where I was going wrong after leaving the program alone for the night and trying it fresh in the morning.

When fork() would fail in the while loop it would exit the program and this was causing issues because once I removed this part the program executed properly. I believe this is because the kill part of the program did not run, leaving all of those processes running. Additionally, I realized I had forgotten to include a line of code to increment the counter to keep track of how many processes were being created.

Here is the working code for main:

int
main(int argc, char *argv[])
{
   struct lnode *curr;
   struct lnode *tmp;
   int count = 1;
   int pidholder = 0;

   tmp = NULL;

   while(pidholder >= 0) {
      curr = getnode();

      pidholder = fork();

      if(pidholder == 0)
         pause();
      else if(pidholder > 0) {
         curr->pid = pidholder;
         curr->next = tmp;
         tmp = curr;
         count = count + 1;
      }
   }

   curr = tmp;

   while(curr) {
      pidholder = curr->pid;

      kill(pidholder, SIGKILL);

      tmp = curr;
      curr = curr->next;
      freenode(tmp);
   }

   printtotal(count);

   exit(0);
}
mimiG
  • 21
  • 1