fixed concats with pipes and error messages
This commit is contained in:
118
GdBShell.java
118
GdBShell.java
@@ -7,17 +7,11 @@ import java.util.Scanner;
|
|||||||
|
|
||||||
import static cTools.KernelWrapper.*;
|
import static cTools.KernelWrapper.*;
|
||||||
|
|
||||||
//TODO find why some calls dont terminate
|
|
||||||
|
|
||||||
//TODO remove stringbuilders/buffers because they are unnecessary
|
|
||||||
|
|
||||||
//TODO implement auto source?
|
|
||||||
|
|
||||||
public class GdBShell {
|
public class GdBShell {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
|
||||||
System.out.println("Welcome!");
|
System.out.println("Welcome!");
|
||||||
String shellPrefix = "EN@GdBShell:";//print actual user instead of EN??
|
String shellPrefix = "EN@GdBShell:";//print actual user instead of EN??
|
||||||
int runningInt = 0;
|
int runningInt = 0;
|
||||||
@@ -41,7 +35,7 @@ public class GdBShell {
|
|||||||
|
|
||||||
//gets rid of the home/user directory and builds a string
|
//gets rid of the home/user directory and builds a string
|
||||||
for (int i = 3; (i < directoryArray.length); i++) {
|
for (int i = 3; (i < directoryArray.length); i++) {
|
||||||
str = str + "/"+ directoryArray[i];
|
str = str + "/" + directoryArray[i];
|
||||||
}
|
}
|
||||||
System.out.print("(" + runningInt + ")");
|
System.out.print("(" + runningInt + ")");
|
||||||
printColor(shellPrefix, "purple", false);
|
printColor(shellPrefix, "purple", false);
|
||||||
@@ -88,7 +82,7 @@ public class GdBShell {
|
|||||||
|
|
||||||
boolean singleCommand = true;
|
boolean singleCommand = true;
|
||||||
//execute possible concatenations
|
//execute possible concatenations
|
||||||
for (i=1; i < commandsArr.length; i++) {
|
for (i = 1; i < commandsArr.length; i++) {
|
||||||
|
|
||||||
|
|
||||||
singleCommand = false;
|
singleCommand = false;
|
||||||
@@ -97,39 +91,21 @@ public class GdBShell {
|
|||||||
|
|
||||||
if (prevValue == 0) {
|
if (prevValue == 0) {
|
||||||
|
|
||||||
printColor("Process exited without error", "green", true);
|
|
||||||
prevValue = parseRedirect(commandsArr[i]);
|
prevValue = parseRedirect(commandsArr[i]);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (prevValue == 0) {
|
|
||||||
printColor("Process exited without error", "green", true);
|
|
||||||
} else {
|
|
||||||
if (singleCommand == false) {
|
|
||||||
printColor("Stopped concatenation at command number " + (i - 1) + " \"" + String.join(" ", commandsArr[i - 1]) + "\":", "red", true);
|
|
||||||
}
|
|
||||||
switch (prevValue) {
|
|
||||||
|
|
||||||
case -1:
|
if (prevValue != 0 && singleCommand == false) {
|
||||||
printColor("Pipe failed","red",true);
|
printColor("Stopped concatenation at command number " + (i - 1) + " \"" + String.join(" ", commandsArr[i - 1]) + "\"", "red", true);
|
||||||
break;
|
|
||||||
case Integer.MIN_VALUE + 1://from execute()
|
|
||||||
printColor("Entered empty command", "red", true);
|
|
||||||
break;
|
|
||||||
case Integer.MIN_VALUE://from execute
|
|
||||||
printColor("Couldn't find executable assigned to \"" + Arrays.toString(commandsArr[i - 1]) + "\"", "red", true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printColor("Exited with error code " + prevValue, "red", true);//everything else
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parseRedirect(String[] inputArray){//should take pipe and read/write,, add >> for append?
|
static int parseRedirect(String[] inputArray) {//should take pipe and read/write,, add >> for append?
|
||||||
//find last occurrences of < and >
|
//find last occurrences of < and >
|
||||||
int redirectInPos = -1;
|
int redirectInPos = -1;
|
||||||
int redirectOutPos = -1;
|
int redirectOutPos = -1;
|
||||||
@@ -159,29 +135,26 @@ public class GdBShell {
|
|||||||
//TODO look up error return value of OPEN to separate from no redirect initialized as -1
|
//TODO look up error return value of OPEN to separate from no redirect initialized as -1
|
||||||
int fd_in = -1;
|
int fd_in = -1;
|
||||||
if (redirectInPos != -1) {
|
if (redirectInPos != -1) {
|
||||||
if (checkls(inputArray[redirectInPos + 1])) {
|
if (inputArray.length > redirectInPos + 1 && checkls(inputArray[redirectInPos + 1])) {
|
||||||
fd_in = open(inputArray[redirectInPos + 1], O_RDONLY);
|
fd_in = open(inputArray[redirectInPos + 1], O_RDONLY);
|
||||||
} else {
|
} else {
|
||||||
return -10;
|
printColor("Error: Invalid input file path", "red", true);
|
||||||
|
return -1;
|
||||||
}//throw error because invalid input file
|
}//throw error because invalid input file
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd_out = -1;
|
int fd_out = -1;
|
||||||
if (redirectOutPos != -1) {
|
if (redirectOutPos != -1) {
|
||||||
fd_out = open(inputArray[redirectOutPos + 1], O_WRONLY | O_CREAT | O_TRUNC);//overwrite file if exists, create else
|
fd_out = open(inputArray[redirectOutPos + 1], O_WRONLY | O_CREAT | O_TRUNC);//overwrite file if exists, create else
|
||||||
|
if (inputArray.length <= redirectOutPos + 1) {
|
||||||
|
printColor("Error: No output file specified after redirect output symbol", "red", true);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] command = Arrays.copyOfRange(inputArray, 0, firstPos);
|
String[] command = Arrays.copyOfRange(inputArray, 0, firstPos);
|
||||||
int returnValue = parsePipe(command, fd_in, fd_out);
|
int returnValue = parsePipe(command, fd_in, fd_out);
|
||||||
|
|
||||||
//close potential files
|
|
||||||
/*
|
|
||||||
if (fd_in != -1) {
|
|
||||||
close(fd_in);
|
|
||||||
}
|
|
||||||
if (fd_out != -1) {
|
|
||||||
close(fd_out);
|
|
||||||
}*/
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -189,11 +162,10 @@ public class GdBShell {
|
|||||||
static int parsePipe(String[] inputArray, int fd_in, int fd_out) {
|
static int parsePipe(String[] inputArray, int fd_in, int fd_out) {
|
||||||
|
|
||||||
String[][] command = splitArray(inputArray, "|");
|
String[][] command = splitArray(inputArray, "|");
|
||||||
//for(int i=0;i<command.length;i++){System.out.println(Arrays.toString(command[i]));}
|
|
||||||
|
|
||||||
|
|
||||||
//execute commands
|
//execute commands
|
||||||
int returnValue;
|
int returnValue = 0;
|
||||||
//first command gets stdin
|
//first command gets stdin
|
||||||
int lastIn = -1;
|
int lastIn = -1;
|
||||||
int[] pipe1fd = new int[2];//array to pass to pipe as out parameter, then contains the read end[0] and write end[1]
|
int[] pipe1fd = new int[2];//array to pass to pipe as out parameter, then contains the read end[0] and write end[1]
|
||||||
@@ -201,14 +173,21 @@ public class GdBShell {
|
|||||||
int[] pipe3fd;
|
int[] pipe3fd;
|
||||||
if (command.length > 1) {
|
if (command.length > 1) {
|
||||||
returnValue = pipe(pipe1fd);
|
returnValue = pipe(pipe1fd);
|
||||||
if(returnValue!=0){printColor("Error opening pipe","red", true);return returnValue;}
|
if (returnValue != 0) {
|
||||||
|
printColor("Error opening pipe", "red", true);
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
returnValue = execute(command[0], fd_in,false, pipe1fd[1],true);//execute first command with potential input from file
|
returnValue = execute(command[0], fd_in, false, pipe1fd[1], true);//execute first command with potential input from file
|
||||||
|
|
||||||
for (int i = 1; i < command.length - 1; i++) {
|
for (int i = 1; i < command.length - 1; i++) {
|
||||||
returnValue = pipe(pipe2fd);
|
returnValue = pipe(pipe2fd);
|
||||||
if(returnValue!=0){printColor("Error opening pipe","red", true);return returnValue;}
|
if (returnValue != 0) {
|
||||||
returnValue = execute(command[i], pipe1fd[0],true, pipe2fd[1],true);
|
printColor("Error opening pipe", "red", true);
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
returnValue = greaterAbsolute(execute(command[i], pipe1fd[0], true, pipe2fd[1], true), returnValue);
|
||||||
|
|
||||||
//variable swap
|
//variable swap
|
||||||
pipe3fd = pipe2fd;
|
pipe3fd = pipe2fd;
|
||||||
@@ -222,18 +201,15 @@ public class GdBShell {
|
|||||||
}
|
}
|
||||||
// execute last (or only) command
|
// execute last (or only) command
|
||||||
|
|
||||||
returnValue = execute(command[command.length - 1], lastIn,true, fd_out,true);
|
returnValue = greaterAbsolute(execute(command[command.length - 1], lastIn, true, fd_out, true), returnValue);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int execute(String[] inputArray, int fd_in,boolean closefdIn, int fd_out, boolean closefdOut) {//0 for read, 1 for write
|
static int execute(String[] inputArray, int fd_in, boolean closefdIn, int fd_out, boolean closefdOut) {//0 for read, 1 for write
|
||||||
System.out.println(Arrays.toString(inputArray)+ " fd_in: "+fd_in+" fd_out: "+fd_out);
|
System.out.println(Arrays.toString(inputArray) + " fd_in: " + fd_in + " fd_out: " + fd_out);
|
||||||
int[] intArray = new int[]{Integer.MIN_VALUE};//to pass to the waitpid function
|
int[] intArray = new int[]{Integer.MIN_VALUE};//to pass to the waitpid function
|
||||||
//split the Array into path and arguments
|
//split the Array into path and arguments
|
||||||
|
|
||||||
@@ -253,7 +229,8 @@ public class GdBShell {
|
|||||||
path = which(input);//"/bin/"+input;
|
path = which(input);//"/bin/"+input;
|
||||||
//}
|
//}
|
||||||
} else {
|
} else {
|
||||||
return Integer.MIN_VALUE + 1;
|
printColor("Entered empty command", "red", true);
|
||||||
|
return -1;
|
||||||
}// internal error code
|
}// internal error code
|
||||||
|
|
||||||
|
|
||||||
@@ -279,36 +256,47 @@ public class GdBShell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//execute the program
|
//execute the program
|
||||||
if(execv(path, inputArray)<0){
|
if (execv(path, inputArray) < 0) {
|
||||||
printColor("execv fatal error", "red", true);
|
printColor("execv fatal error", "red", true);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//papa process
|
//papa process
|
||||||
else {
|
else {
|
||||||
if (forkInt<0){
|
if (forkInt < 0) {
|
||||||
printColor("Error: fork", "red",true);
|
printColor("Error: fork() returned Error", "red", true);
|
||||||
return forkInt;
|
return forkInt;
|
||||||
}
|
}
|
||||||
//close open files that only the child process needs
|
//close open files that only the child process needs
|
||||||
if(closefdIn&&fd_in!=-1){close(fd_in);}
|
if (closefdIn && fd_in != -1) {
|
||||||
if(closefdOut&&fd_out!=-1){close(fd_out);}
|
close(fd_in);
|
||||||
|
}
|
||||||
|
if (closefdOut && fd_out != -1) {
|
||||||
|
close(fd_out);
|
||||||
|
}
|
||||||
|
|
||||||
//wait for child
|
//wait for child
|
||||||
if(waitpid(forkInt, intArray, 0)<0){
|
int f;
|
||||||
printColor("Error: waiting for child", "red",true);
|
if ((f = waitpid(forkInt, intArray, 0)) < 0) {
|
||||||
|
printColor("Error " + f + ": waiting for child", "red", true);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
if (intArray[0] == 0) {
|
||||||
|
printColor("Process exited without error", "green", true);
|
||||||
|
} else {
|
||||||
|
printColor("Process exited with error code " + intArray[0], "red", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
printColor("Couldn't find executable assigned to \"" + inputArray[0] + "\"", "red", true);
|
||||||
}
|
}
|
||||||
return intArray[0];//contains Integer.MIN_VALUE if no program was found using the which command
|
return intArray[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<Integer> findArrayOccurrence(Object[] oArr, Object o) {
|
public static ArrayList<Integer> findArrayOccurrence(Object[] oArr, Object o) {
|
||||||
@@ -333,6 +321,14 @@ public class GdBShell {
|
|||||||
return sArr;
|
return sArr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int greaterAbsolute(int a, int b) {
|
||||||
|
if (Math.abs(a) > Math.abs(b)) {
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String which(String arguments) {
|
public static String which(String arguments) {
|
||||||
ProcessBuilder prcBuilder = new ProcessBuilder();
|
ProcessBuilder prcBuilder = new ProcessBuilder();
|
||||||
|
|||||||
Reference in New Issue
Block a user