Resource Limits

Due: prior to midnight on Friday, February 1

Please place all of your code in a directory named rlimits.

This assignment will provide practice using the following system functions.

  • getrlimit(): get the current and maximum limits of a system resource
  • setrlimit(): set the current limit of a system resource
  • strerror(): get the string corresponding to the current value in the global variable errno
  • fork(): create a child process
  • execl():  change the .text section of a child process
  • sleep(): pause a process

Program Description

The experiment you are about to conduct will have 2 programs: we’ll call them the parent program and the child program.  Place them in files named parent.c and child.c.

The child program is simple. It simply prints the number in argv[1] that is passed to it and then terminates.

The parent program should do the following:

  • First, limit the number of child processes that it can create using getrlimit() and setrlimit().  Limit the number of child processes to 7.
  • Initialize a counter that should be incremented in each iteration of the loop.
  • Test that the limit works by entering an infinite-loop. In the loop the program should do the following:
    • Call fork() to create a child process.
    • If fork() is successful, the child process should call execl() to run the child program passing to the child program the value of the counter, and the parent process should print the child’s pid.
    • If fork() is unsuccessful, the parent should use strerror() to print the string that corresponds to the error code stored errno, pause for 2 seconds using sleep(), and then terminate.

Below is a screen shot of the output for a working solution.

Riddle

In the program that I wrote, shown running in the above screenshot, I limited the number of child processes to 7.  The program worked correctly and failed after creating 2 child processes.  Why is this correct?

Programming Tips

To set a limit on the number of processes a user can have (e.g. 7), first call getrlimit() to initialize the struct rlimit variable.  After calling getrlimit() change the value of rlim_cur and then call setrlimit().

When a system call fails, print a readable string corresponding to the value in errno.  To do so include <errno.h> and use a statement similar to the one below.

printf("setrlimit failed: %s\n", strerror(errno));

To pass the counter to execl(), you need to store the integer in a string.  To do so, you can use snprintf as shown below.

int count = 0;
char buff[8];
...

snprintf(buff, sizeof(buff), "%d", ++count);

To change the .text section of the child process (i.e. change the program that the child is running) you can use execl() as shown below.  Note: you should definitely check the return value of execl().

execl("./child", "child", buff, NULL)

When the parent process dies, the command prompt is immediately printed to the console.  This may happen before the child processes run and print their statements.  To avoid this behavior simply call the sleep(2) right before the parent terminates.  This will cause the parent to pause for 2 seconds, giving the child processes enough time to print their statements before the command prompt is printed.

Grading

  • Program does not check return value from all system call (-2 for each occurrence)
  • Improper use of the value returned from fork (-5)
  • Missing or misplaced call to sleep (-2)
  • Call fork more than once (-5)
  • Call exec more than once (-5)
  • Set limit on number of processes improperly (-5)
  • Improperly pass the child counter to exec (-5)
  • In the child’s block, after exec, have code that will never execute (-2)
  • After call to exit, have code that will never execute (-2)
  • Includes unnecessary global variables (-2)
  • Parent process does not print the child’s pid (-5)
  • Strerror is not called within printf statements (-2)
  • Invalid call to exec (-5)

© 2017 – 2019, Eric. All rights reserved.