This command is showing the use of command line argument. The program is creating some history commands. The history command can be added, displayed and retrieved.
Programminghomeworkshelp.com is one of the leading player in providing C Programming Assignment Help. If you are looking for C Programming Homework Help then email us at info@programminghomeworkshelp.com
Python Notes for mca i year students osmania university.docx
C Language Assignment Help
1.
2. Programming in C language
This command is showing the use of command line argument. The program
is creating some history commands. The history command can be added,
displayed and retrieved.
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#define MAX_LINE 80 /* The maximum length command */
#define NUM_HISTORY 10 /* the maxim number of history commands
maintained */
/* a helper function to parse the line into different arguments.
* return the number of arguments passed */
int parse(char line[], char *args[]);
/* history related structure and functions:
*
*/
structhist {
int id;
char command[MAX_LINE + 1];
};
staticintnid = 1; /* the id for the next command added into the
history */
structhist records[NUM_HISTORY]; /* up to NUM_HISTORY records */
/* try to get the history command index from the arg
* ifarg is not a !! or !followed by N, simply return -1. */
intget_history_index(char arg[]);
/* fetch the history command of the given index
* return 0 if failed. otherwise, return 1.
* If index = 0, return the most recent command.
* otherwise, return the command with the given index as its id. */
intfetch_history(int index, char command[]);
/* add the line of command into history */
voidadd_history(char line[]);
/* display the history commands */
voiddisplay_history();
3. int main(void)
{
char *args[MAX_LINE/2 + 1]; /* command line arguments */
intargc; /* number of arguments */
intshouldrun = 1; /* flag to determine when to exit program
*/
char line[MAX_LINE + 1], backup[MAX_LINE + 1];
int background; /* whether & is entered for background
execution */
char *tok;
int child;
/* initialization: clear up the history record */
memset(records, 0, sizeof(records));
while (shouldrun) {
printf("osh> ");
fflush(stdout);
/* read user's input and use strtok to parse it into different
* arguments */
if (fgets(line, sizeof(line), stdin) == NULL) {
break;
}
/* remove n in the line */
if ((tok = strchr(line, 'n')) != NULL) {
*tok = '0';
}
/* use keyword 'exit' to terminate the shell */
if (strcmp(line, "exit") == 0) {
shouldrun = 0;
continue;
}
strcpy(backup, line);
/* parse the arguments */
argc = parse(line, args);
if (argc == 0) { /* empty line */
continue;
}
/* if the argument is !!or !followed by an interger N
* execute the command in history */
if (argc == 1) {
int index = get_history_index(args[0]);
if (index >= 0) {
if (!fetch_history(index, line)) {
/* fail to fetch the command from history */
if (index == 0) {
4. printf("No commands in history.n");
} else {
printf("No such command in history.n");
}
continue;
}
/* otherwise, backup the command and parse
* the arguments again */
strcpy(backup, line);
argc = parse(line, args);
}
}
/* add the current command into history */
add_history(backup);
/* handle 'history' command */
if (argc == 1 &&strcmp(args[0], "history") == 0) {
display_history();
continue;
}
/* if the last command is &, then run it in background */
background = 0;
if (strcmp(args[argc - 1], "&") == 0) {
background = 1;
args[argc - 1] = NULL;
}
/* handle other command by fork/execvp */
/**
* After reading user input, the steps are:
* (1) fork a child process using fork()
* (2) the child process will invoke execvp()
* (3) if command included &, parent will invoke wait()
*/
child = fork();
if (child < 0) {
printf("Fail to create process to run the command.n");
} else if (child > 0) { /* parent process */
if (!background) {
/* not background task, wait until the child is done
*/
waitpid(child, NULL, 0);
}
} else {
/* child process executes the command */
if (execvp(args[0], args) < 0) {
exit(errno);
}
}
5. }
return 0;
}
/* try to get the history command index from the arg
* ifarg is not a $$ or $ followed by N, simply return -1. */
intget_history_index(char arg[])
{
if (strcmp(arg, "!!") == 0) {
return 0;
}
if (arg[0] == '!' &&arg[1] != '0') {
/* check if it is followed by an integer */
int i;
for (i = 1; arg[i] != '0'; i++) {
if (!isdigit(arg[i])) { /* not a digit */
return -1;
}
}
/* otherwise, return N */
returnatoi(&arg[1]);
}
return -1; /* not a history command */
}
/* fetch the history command of the given index
* return 0 if failed. otherwise, return 1.
* If index = 0, return the most recent command.
* otherwise, return the command with the given index as its id. */
intfetch_history(int index, char command[])
{
int i;
if (nid == 1) { /* no command added */
return 0;
}
if (index == 0) { /* fetch the latest one */
index = nid - 1;
}
for (i = NUM_HISTORY - 1; i >= 0; i--) {
if (records[i].id == index) {
/* found the history record with the given index
* copy the command */
strcpy(command, records[i].command);
return 1;
}
}
return 0; /* no command with the index, failed */
}
/* add the line of command into history */
voidadd_history(char line[])
6. {
int i;
/* shift all records left */
for (i = 0; i < NUM_HISTORY - 1; i++) {
records[i] = records[i + 1];
}
/* save the line to the last position in the records array */
records[NUM_HISTORY - 1].id = nid ++;
strcpy(records[NUM_HISTORY - 1].command, line);
}
/* display the history commands */
voiddisplay_history()
{
int i;
/* display each record in the history */
for (i = NUM_HISTORY - 1; i >= 0 && records[i].id > 0; i--) {
printf("%3d %sn", records[i].id, records[i].command);
}
}
/* a helper function to parse the line into different arguments.
* return the number of arguments passed */
int parse(char line[], char *args[]) {
/* use spaces or t to split the line into different parts */
char *tok = strtok(line, " t");
int count = 0;
while (tok != NULL &&strlen(tok) > 0) {
args[count++] = tok;
tok = strtok(NULL, " t");
}
args[count] = NULL; /* add a NULL to the end of the array */
return count;
}