Question
C PROGRAMMING: Write a c program which does the following: the program is much like init and You will read from a configuration file whose
C PROGRAMMING:
Write a c program which does the following: the program is much like "init" and You will read from a configuration file whose name must be specified on the command-line (init defaults to reading /etc/inittab, but that default would be pointless for this).
The config file will look like this: (run-level):(once/respawn):(command-line to be executed)
i.e.config file
:once:echo Hello, inittab-using world # This comment is not output
4:respawn:echo Aha, run-level four! :respawn:listener)
and if you $gcc -Wall myinit.c
$./a.out -r4 [runlevel] config_file
$Hello, inittab-using world
Aha, run-level four!
Aha, run-level four!
....
("Aha, run-level four!" will continue to output until user press control + c to exit)
REQ: The program is to read from the config file and if there is a run-level execute the given process at the level, if there is no run-level, then the line applies to all run-levels. (execute all run-levels)
and if there is a 'once' after the first ':' just output the command-line to be executed with sh ?c string after the second ":" once; or if there is a 'respawn' after the first ':' just keep outputting the command-line to be executed with sh ?c string after the second ":" until user press control+c to exit;
and the subprocesses MUST run in parallel. If the inittab lists commands "cmd1" and "cmd2" (on separate lines), you can't run cmd1 and wait for it to finish and then run cmd2. You need to start all of the commands in the file before doing any wait() calls;
also ignore the line starts with "#";
)
The program takes an optional ?r parameter which indicates the run- level, which is a single character whose meaning is described below. If this parameter is not present, the run-level defaults to 3. Use getopt() to parse the command-line, and output a fatal error message if the subsequent number of file name parameters is not exactly 1.
The configuration file has one entry per line, with fields separated by colons. Comments are introduced by # and run to the end of the line; and blank lines are permitted (that is, they must be ignored, rather than yielding an error message).
Hint:
if ((p = strchr(buf, ' ')))
*p = '\0';
if ((p = strchr(buf, ' ')))
*p = '\0';
If the line is not empty (nor is solely a comment), it contains three colon-separated fields (the real inittabs first field is omitted here):
The first field is a list of which run-levels the given process should be executed for, as a string of individual run-level characters. For example, 23 indicates that the process should be run in run- levels 2 and 3. If this first field on the line is empty, then the line applies to all run-levels. Otherwise, if the current run-level as specified by the ?r option is not listed, your program will discard this line after parsing.
The second field specifies the re-spawning behaviour for this process. For this assignment, the contents of this field must be either the string once, which means that the process should be executed once and your program will ignore whether or when it terminates; or the string respawn, which indicates that your program should watch for the process to terminate and then start a new one. Any other value is a fatal error.
The third field is a command-line to be executed with sh ?c string.
You may impose a maximum of 100 entries, but if this is exceeded you must exit with an appropriate error message rather than exceeding array bounds.
Your subprocesses MUST run in parallel. If the inittab lists commands "cmd1" and "cmd2" (on separate lines), you can't run cmd1 and wait for it to finish and then run cmd2. You need to start all of the commands in the file before doing any wait() calls.
(input file)inittab:
# Example inittab, running various silly programs
:once:echo Hello, inittab-using world # This comment is not output 4:once:echo Aha, run-level four! :respawn:listener -p 1487 /bin/echo $USER says that this is the end of the internet. \ Please turn around.
12:respawn:333 123:respawn:222
# enable 'biff' only on , not a workstation, and send yourself some e-mail #12:respawn:111
The program should output as follow: $ ./myinit -r12 inittab
output: ./myinit: runlevel must be a single character
usage: ./myinit [-r runlevel] file
$./myinit -r4 inittab
Hello, inittab-using world
Aha, run-level four!
^C (control+c to exit)
$./myinit -r1 inittab
Hello, inittab-using world
^C
NOTE: ":once:echo Hello" means "Hello" only output once where ":respawn:echo Hello" means "Hello" will output forever until user press "control + c" to exit. Ignore the lines started with "#" treated as comments.
And here are what I have done so far, help is very appreciated
myinit.c
#include
#include
#include
#include
#include
#include
#define MAXLINE 100 /*MAXLINE from the input file will be processed*/
#define MAXCHAR 500 /*MAXCHARACTER in a line*/
char *buf;
int width = MAXCHAR;
int main(int argc, char **argv)
{
int c, runlevel, status = 0;
FILE *fp;
pid_t child_pid; /* child process information */
int child_status;
extern void process(FILE *fp);
while ((c = getopt(argc, argv, "r")) != EOF) {
switch (c) {
case 'r':
if ((runlevel = atoi(argv[1])) == 0)
status = 1;
break;
default:
status = 1;
}
}
if (status){
fprintf(stderr, "usage: %s [-r runlevel] file ", argv[0]);
return (1);
}
/*
if ((buf = malloc(width + 1)) == NULL) {
fprintf(stderr, "%s: no memory! ", argv[0]);
return (1);
}
*/
if ((fp = fopen(argv[2], "r")) == NULL){
perror(argv[2]);
return (1);
}
else{
process(fp);
fclose(fp);
}
return 0;
}
void process(FILE *fp)
{
int c;
while ((c=getc(fp)) != EOF)
{
}
}
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started