Advertisement
tari

tari

Dec 8th, 2010
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.95 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <sys/wait.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>
  8.  
  9. char *trimSpaces(char *str);
  10.  
  11. int main(int argc, char *argv[]) {
  12.     if(argc < 1 || argc > 2) {
  13.         char error_message[30] = "An error has occurred\n";
  14.         write(STDERR_FILENO, error_message, strlen(error_message));
  15.         exit(1);
  16.     }
  17.     int PATH_LEN = 512;
  18.     int endAfterThisBatch = 0;
  19.     char* home = getenv("HOME");
  20.     if(argc == 1) {
  21.     for(;;) { /* Goes until "exit" or error. */
  22.         /* Interactive mode */
  23.         char s[513] = {'\0'};
  24.         printf("mysh> ");
  25.         fgets(s, 513, stdin);
  26.         /* remove newline character from input */
  27.         *(strchr(s,'\n')) = '\0';
  28.        
  29.         /*Handle a batch of concurrent processes (+) per iteration of loop */
  30.         char *concurrent = NULL;
  31.         char *sBAK1 = NULL;
  32.         concurrent = strtok_r(s, ";", &sBAK1);
  33.         while(concurrent != NULL) {
  34.             concurrent = trimSpaces(concurrent);
  35.             /* Sets flag to exit after command group, if "exit" is present */
  36.             if(strcmp(concurrent, "exit") == 0) {
  37.                 endAfterThisBatch = 1;        
  38.             }
  39.             /* pwd command */
  40.             else if(strcmp(concurrent, "pwd") == 0) {
  41.                 char *path = malloc(PATH_LEN);
  42.                 path = getcwd(path, PATH_LEN);
  43.                 printf(path);
  44.                 free(path);
  45.                 printf("\n");
  46.             }
  47.             /* blank cd command, back to home dir */
  48.             else if(strcmp(concurrent, "cd") == 0) { /* borked on Vista */
  49.                 chdir(home);
  50.             }
  51.             /* cd command with dir to change to */
  52.             else if(strncmp(concurrent, "cd ", 3) == 0) {
  53.                 concurrent = concurrent + 2; /* moves past the "cd" */
  54.                 concurrent = trimSpaces(concurrent);
  55.                 chdir(concurrent);
  56.             }
  57.             else {
  58.                 // Handle output redirection
  59.                 concurrent = strtok(concurrent, ">");
  60.                 concurrent = trimSpaces(concurrent); //Might have spaces between this and >
  61.                 char *outf = strtok(NULL, ">");
  62.                 int fd = -1;
  63.                 if (outf != NULL) {
  64.                     *(outf-1) = '\0';   //Keep redirection from being processed into argv
  65.                     outf = trimSpaces(outf);
  66.                     fd = open(outf, O_WRONLY | O_CREAT | O_TRUNC); //handles errors transparently
  67.                 }
  68.                 // Parse string into argv for execvp
  69.                 int argc = 0;
  70.                 char *args = strtok(concurrent, " ");
  71.                 char **argv = malloc(sizeof(char*));
  72.                 while (args != NULL) {
  73.                     argv = realloc(argv, (argc+1)*sizeof(char*));
  74.                     argv[argc++] = args;
  75.                     args = strtok(NULL, " ");
  76.                 }
  77.                 argv[argc] = '\0';
  78.                 int pid = fork();
  79.                 if (pid == 0) {
  80.                     if (fd != -1) {
  81.                         dup2(fd, STDOUT_FILENO);
  82.                     }
  83.                     execvp(argv[0], argv);
  84.                 } else {
  85.                     wait(&pid);
  86.                 }
  87.                 free(argv);
  88.             }
  89.             concurrent = strtok_r(NULL, ";", &sBAK1);
  90.         }
  91.  
  92.         if(endAfterThisBatch == 1) {
  93.              exit(0);
  94.         }
  95.     } /* End infinite for loop */
  96.     } /* End if statement for interactive mode */
  97.    
  98.    
  99.     if(argc == 2) {
  100.         /* Batch mode */
  101.         printf("Batch mode isn't implemented!\n");
  102.     }
  103.     return 0;
  104. }
  105.  
  106. char *trimSpaces(char *str) {
  107.     char *end;
  108.     // Trim leading space
  109.     while(isspace(*str)) str++;
  110.  
  111.     // Trim trailing space
  112.     end = str + strlen(str) - 1;
  113.     while(end > str && isspace(*end)) {
  114.         end--;
  115.     }
  116.   // Write new null terminator
  117.   *(end+1) = 0;
  118.   return str;
  119. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement