Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/wait.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- char *trimSpaces(char *str);
- int main(int argc, char *argv[]) {
- if(argc < 1 || argc > 2) {
- char error_message[30] = "An error has occurred\n";
- write(STDERR_FILENO, error_message, strlen(error_message));
- exit(1);
- }
- int PATH_LEN = 512;
- int endAfterThisBatch = 0;
- char* home = getenv("HOME");
- if(argc == 1) {
- for(;;) { /* Goes until "exit" or error. */
- /* Interactive mode */
- char s[513] = {'\0'};
- printf("mysh> ");
- fgets(s, 513, stdin);
- /* remove newline character from input */
- *(strchr(s,'\n')) = '\0';
- /*Handle a batch of concurrent processes (+) per iteration of loop */
- char *concurrent = NULL;
- char *sBAK1 = NULL;
- concurrent = strtok_r(s, ";", &sBAK1);
- while(concurrent != NULL) {
- concurrent = trimSpaces(concurrent);
- /* Sets flag to exit after command group, if "exit" is present */
- if(strcmp(concurrent, "exit") == 0) {
- endAfterThisBatch = 1;
- }
- /* pwd command */
- else if(strcmp(concurrent, "pwd") == 0) {
- char *path = malloc(PATH_LEN);
- path = getcwd(path, PATH_LEN);
- printf(path);
- free(path);
- printf("\n");
- }
- /* blank cd command, back to home dir */
- else if(strcmp(concurrent, "cd") == 0) { /* borked on Vista */
- chdir(home);
- }
- /* cd command with dir to change to */
- else if(strncmp(concurrent, "cd ", 3) == 0) {
- concurrent = concurrent + 2; /* moves past the "cd" */
- concurrent = trimSpaces(concurrent);
- chdir(concurrent);
- }
- else {
- // Handle output redirection
- concurrent = strtok(concurrent, ">");
- concurrent = trimSpaces(concurrent); //Might have spaces between this and >
- char *outf = strtok(NULL, ">");
- int fd = -1;
- if (outf != NULL) {
- *(outf-1) = '\0'; //Keep redirection from being processed into argv
- outf = trimSpaces(outf);
- fd = open(outf, O_WRONLY | O_CREAT | O_TRUNC); //handles errors transparently
- }
- // Parse string into argv for execvp
- int argc = 0;
- char *args = strtok(concurrent, " ");
- char **argv = malloc(sizeof(char*));
- while (args != NULL) {
- argv = realloc(argv, (argc+1)*sizeof(char*));
- argv[argc++] = args;
- args = strtok(NULL, " ");
- }
- argv[argc] = '\0';
- int pid = fork();
- if (pid == 0) {
- if (fd != -1) {
- dup2(fd, STDOUT_FILENO);
- }
- execvp(argv[0], argv);
- } else {
- wait(&pid);
- }
- free(argv);
- }
- concurrent = strtok_r(NULL, ";", &sBAK1);
- }
- if(endAfterThisBatch == 1) {
- exit(0);
- }
- } /* End infinite for loop */
- } /* End if statement for interactive mode */
- if(argc == 2) {
- /* Batch mode */
- printf("Batch mode isn't implemented!\n");
- }
- return 0;
- }
- char *trimSpaces(char *str) {
- char *end;
- // Trim leading space
- while(isspace(*str)) str++;
- // Trim trailing space
- end = str + strlen(str) - 1;
- while(end > str && isspace(*end)) {
- end--;
- }
- // Write new null terminator
- *(end+1) = 0;
- return str;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement