license and readme, lacks screenshots and recording etc
[tinysh-parallel/.git] / tinysh.c
1 #include <stdio.h>
2 #include <stdbool.h>
3 #include <unistd.h>
4 #include <sys/types.h>
5 #include <sys/wait.h>
6 #include <stdlib.h>
7 #include <string.h>
8
9
10 int COMMANDS_SIZE;
11 char **parse_command(char *my_line, char value)
12 {
13     int buffer_size = 64;
14     int i = 0;
15     char *arg;
16     char **args = malloc(buffer_size * sizeof(char*));
17     char *valuee = &value;
18     arg = strtok(my_line, valuee);
19     while (arg != NULL) {
20         args[i] = arg;
21         i++;
22         arg = strtok(NULL, valuee);
23     }
24
25     args[i] = NULL;
26     COMMANDS_SIZE = i;
27     return args;
28 }
29 void trimTrailing(char * str)
30 {
31     int index, i;
32
33     /* Set default index */
34     index = -1;
35
36     /* Find last index of non-white space character */
37     i = 0;
38     while(str[i] != '\0')
39     {
40         if(str[i] != ' ' && str[i] != '\t' && str[i] != '\n')
41         {
42             index= i;
43         }
44
45         i++;
46     }
47
48     /* Mark next character to last non-white space character as NULL */
49     str[index + 1] = '\0';
50 }
51 ////////////////////EXEC PROGRAM FUNCTION/////////////
52 //
53 //
54 //
55 static int exec_prog(int argc, const char **argv) {
56
57   pid_t pid[argc];
58   int status, timeout /* unused ifdef WAIT_FOR_COMPLETION */;
59
60   // this block executes when pid=0, (I am the father process)
61
62   for (int i =0; i < argc; i++) {
63
64     if ((pid[i] = fork()) < 0) {  /* fork a child process           */
65       printf("*** ERROR: forking child process failed\n");
66       exit(1);
67      } else if (pid[i] == 0) {  /* for the child process:         */
68        trimTrailing(argv[i]);
69        char **value = parse_command(argv[i], ' ');
70        if (strcmp(value[0], "")) {
71         if (execvp(value[0], value) < 0) {  /* execute the command  */
72                  printf("*** ERROR: exec failed\n");
73                  exit(1);
74             }
75         exit(0);
76        } else {
77         printf("");
78         exit(0);
79        }
80      }
81
82   }
83
84   for (int i =0; i < argc; i++) {
85     do {
86       if ((pid[i] = waitpid(pid[i], &status, WNOHANG)) == -1) {
87         perror("wait() error");
88       }
89       else if (pid[i] == 0) {
90         /*printf("child is still running ");*/
91         sleep(1);
92       } else {
93         if (WIFEXITED(status))
94         printf("child exited with status of %d\n", WEXITSTATUS(status));
95         /*else puts("child did not exit successfully");*/
96       }
97     } while (pid[i] == 0);
98
99   }
100
101     return 0;
102 }
103 //
104 //
105 //
106 //////////////////////////////////////////////////////
107
108 ////////////////////BATCH MODE PROCESS////////////////
109 //
110 //
111 //
112 int batchModeStart(const char **argv) {
113
114
115
116 }
117 //
118 //
119 //
120 //////////////////////////////////////////////////////
121
122 void promptPrint(){
123 printf("⌈[tinysh] \n↳>>> ");
124 }
125
126
127 char *read_command_line(void)
128 {
129     int bufsize = 1024;
130     char *buffer = malloc(sizeof(char) * bufsize);
131     int c;
132     int i = 0;
133
134     while ( c != '\n' ) {
135         c = getchar();
136         buffer[i] = c;
137         i++;
138     }
139
140     return buffer;
141 }
142
143
144 int main (int argc, char *argv[]){
145
146   char *prompt = argv[0];
147   char *filename;
148   bool batchMode = false;
149   if ( argc == 2) {
150     filename = argv[1];
151     batchMode = true;
152   } else if (argc != 1) {
153     printf("Wrong ammount of arguments, only one file per batch \n");
154   }
155
156   /*promptPrint();*/
157   /*exec_prog(1, filename);*/
158   /*exec_prog(&argv[1]);*/
159
160
161
162 //Oscar J Rodriguez B (@josuer08)
163   if (!batchMode) {
164     bool active = true;
165     char *arguments;
166     while (active) {
167       promptPrint();
168       arguments = read_command_line();
169       char **args = parse_command(arguments, ';');
170       trimTrailing(args[0]);
171       if (strcmp(args[0], "exit") == 0) {/* is it an "exit"?     */
172         active = false;  /*   exit if it is                */
173       } else {
174         exec_prog(COMMANDS_SIZE,args);
175       }
176       /*printf("%d", COMMANDS_SIZE);*/
177       /*printf("%s and %s", args[0], args[1]);*/
178     }
179   } else {
180     char * buffer = 0;
181     long length;
182     FILE * f = fopen (filename, "rb");
183
184     if (f) {
185       fseek (f, 0, SEEK_END);
186       length = ftell (f);
187       fseek (f, 0, SEEK_SET);
188       buffer = malloc (length);
189       if (buffer) {
190         fread (buffer, 1, length, f);
191       }
192       fclose (f);
193     }
194
195     if (buffer) {
196     char **args = parse_command(buffer, ';');
197     trimTrailing(args[0]);
198     /*printf("%s", buffer);*/
199     exec_prog(COMMANDS_SIZE,args);
200     }
201
202
203     return 0;
204
205   }
206
207
208
209
210 }