#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <stddef.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#define MAX_PATH 2048// Maximal full path length we support
#define MAX_COMMANDS 8
#define MAX_COMMAND_LENGTH 48
int main (int argc, char **argv) {
int i = 0;
int j = 0;
int k = 0; //test only
int fork_num = 0;
char file_name[MAX_PATH];
char file_path[MAX_PATH + 1];
FILE* cmd_file;
struct stat file_stat;
char *cmd_hldr;//[MAX_COMMAND_LENGTH];
char *cmd_ary[MAX_COMMANDS]; //add another dimension here for each arg
char *delimiter = " ";
pid_t childpid;
char *cmd_to_fork[MAX_COMMAND_LENGTH];
int totalpipeid[16];//Stores the ids of the pipes
//check if there is enough arguements (a filename and nothing more)
if (argc != 2) {
fprintf(stderr, "invalid number of arguments, please supply a filename\n");
perror("Error");
exit(1);
}
strcpy(file_name, argv[1]);
strcpy(file_path, "./");
strcat(file_path, file_name);
// obtain file status
if (stat(file_path, &file_stat) == -1) {
// error getting stat
fprintf(stderr, "%s cannot be read properly (cannot get stat)\n", file_name);
perror ("Error");
exit(1);
}
//check if the filename names a regular file
if(S_ISREG(file_stat.st_mode)) {
//printf("'%s' is regular file at '%s'\n", file_name, file_path);
cmd_file = fopen(file_path, "r");
//make sure file opens ok
if (!cmd_file) {
fprintf(stderr, "Failed opening file %s for reading \n", file_path);
perror ("Error");
exit(1);
}
cmd_hldr = malloc(MAX_COMMAND_LENGTH);
//loop to read each command from the file, into cmd_ary
while((fgets(cmd_hldr, MAX_COMMAND_LENGTH, cmd_file)) != NULL) {
if(fork_num > 7) {
fprintf(stderr, "File contains too many commands, will only perform the first %d\n", MAX_COMMANDS);
perror ("Error:");
break;
}
//unessecary, don't need to remove newline from command strings
/*for(i = 0; i < MAX_COMMAND_LENGTH;i++) {
//printf("char %d of command %d is %c\n", i, fork_num, cmd_hldr[i]);
if (cmd_hldr[i] == "\n") {
cmd_hldr[i] = " ";
//cmd_hldr[i+1] = " ";
break;
}
}*/
cmd_ary[fork_num] = malloc(strlen(cmd_hldr) + 1);
strcpy(cmd_ary[fork_num], cmd_hldr);
//printf("command number %d is %s\n", fork_num, cmd_ary[fork_num]);
fork_num++;
}
if (fclose(cmd_file) == -1) {
fprintf(stderr, "unable to close [%s]\n", file_path);
perror("Error");
exit(1);
}
}
//file named by filename is not a regular file, quit
else {
fprintf(stderr, "%s is not a regular file\n", file_name);
perror("Error");
exit(1);
}
/*************************************
* file is open now, next read
* commands one by one, forking them
* to seperate processes
************************************/
for(i = 0; i < fork_num; i++) {
printf("executing command number %d which is %s\n", i, cmd_ary[i]);
j = 0;
cmd_hldr = strtok(cmd_ary[i], delimiter);
//Store the program name for execution
char program_name[strlen(cmd_hldr)];
strcpy(program_name,cmd_hldr);
//Store the arguments for the program
//cmd_hldr = strtok(NULL, delimiter);
cmd_to_fork[j] = malloc(strlen(cmd_hldr) + 1);
strcpy(cmd_to_fork[j], cmd_hldr);
printf("arg %d of command %d is %s\n", j, i, cmd_to_fork[j]);
while (( cmd_hldr = strtok(NULL, delimiter)) != NULL) {
j++;
cmd_to_fork[j] = malloc(strlen(cmd_hldr) + 1);
strcpy(cmd_to_fork[j], cmd_hldr);
printf("arg %d of command %d is %s\n", j, i, cmd_to_fork[j]);
}
/*
//fork here? pipe when?
int pipeid[2];
int secondpipe[2];
int status;
if (pipe(pipeid)) {
printf("Pipe failed!\n");
perror("Error");
}
if (pipe(secondpipe)) {
printf("Second pipe failed!\n");
perror("Error");
}
childpid = fork();
//dup2(pipeid[0],0);
//dup2(pipeid[1],1);
//char getarray[1000];
//gets(getarray);
//printf("done\n");
// exit(1);
if (childpid == 0) { //Child
if (dup2(pipeid[1],1)==-1) {
perror("Error with duping output");
}
close(pipeid[1]);
close(pipeid[0]);
execvp(program_name, cmd_to_fork);
//printf("ZOMG\n");
}
else { //Parent
if (dup2(pipeid[0],secondpipe[1])==-1) {
perror("Error with duping input");
}
close(pipeid[1]);
//close(pipeid[0]);
wait(&status);
if (WIFEXITED(status) != 1) {
perror("Child Exit Error:");
}
//execvp(program_name, cmd_to_fork);
}
*/
}
return 1;
}