2d882bc37eaed5cf3c4636be129b55c7242c420f
[akaros.git] / user / apps / parlib / run_binary.c
1 #include <string.h>
2 #include <stdlib.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <fcntl.h>
6 #include <stdint.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <parlib.h>
10
11 extern char * readline(const char *prompt);
12
13 #define MALLOC_SIZE     1048576
14 #define READ_SIZE       1024
15
16 int run_binary_filename(const char* cmdline, size_t colors)
17 {
18         int ret = 0;
19
20         char argv_buf[PROCINFO_MAX_ARGV_SIZE] = {0};
21         char* argv_buf_ptr = argv_buf;
22         for(int argc = 0; ; argc++)
23         {
24                 while(*cmdline == ' ')
25                         cmdline++;
26                 if(*cmdline == 0)
27                         break;
28
29                 char* p = strchr(cmdline,' ');
30                 int len = p == NULL ? strlen(cmdline) : p-cmdline;
31
32                 memcpy(argv_buf_ptr,cmdline,len);
33                 argv_buf_ptr[len] = 0;
34                 argv_buf_ptr += len+1;
35
36                 if(p == NULL)
37                 {
38                         argc++;
39                         break;
40                 }
41
42                 cmdline = p;
43         }
44         
45
46         int fd = open(argv_buf, O_RDONLY, 0);
47         if(fd < 0)
48         {
49                 printf("open failed\n");
50                 ret = -1;
51                 goto open_error;
52         }
53         
54         int total_bytes_read = 0;
55         int bytes_read = 0;
56         int bufsz = 0;
57         void* binary_buf = NULL;
58         
59         while(1) {
60                 if(total_bytes_read+READ_SIZE > bufsz)
61                 {
62                         void* temp_buf = realloc(binary_buf,bufsz+MALLOC_SIZE);
63                         if(temp_buf == NULL)
64                         {
65                                 printf("realloc failed\n");
66                                 ret = -1;
67                                 goto realloc_error;
68                         }
69
70                         binary_buf = temp_buf;
71                         bufsz += MALLOC_SIZE;
72                 }
73
74                 bytes_read = read(fd, binary_buf+total_bytes_read, READ_SIZE);
75                 total_bytes_read += bytes_read;
76                 if(bytes_read < 0)
77                 {
78                         printf("read error\n");
79                         ret = -1;
80                         goto read_error;
81                 }
82                 if(bytes_read == 0) break;
83         }
84         printf("Loading Binary: %s, ROMSIZE: %d\n",argv_buf,total_bytes_read);
85         ret = sys_run_binary(binary_buf, total_bytes_read, argv_buf, PROCINFO_MAX_ARGV_SIZE, colors);
86         if(ret < 0)
87                 fprintf(stderr, "Error: Unable to run remote binary\n");
88         else
89                 syscall(SYS_yield,0,0,0,0,0);
90
91 read_error:
92 realloc_error:
93         free(binary_buf);
94         close(fd);
95 open_error:
96         return ret;
97 }
98
99 void run_binary(size_t colors)
100 {
101         char* readline_result = readline("\nEnter name of binary to execute: ");
102         if (readline_result == NULL) {
103                 printf("Error reading from console.\n");
104                 return;
105         }
106         run_binary_filename(readline_result, colors);
107 }
108