Phasor 2.2.0
Stack VM based Programming Language
Loading...
Searching...
No Matches
IO.c
Go to the documentation of this file.
1#include "IO.h"
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#ifdef _WIN32
6#include <windows.h>
7#else
8#include <unistd.h>
9#include <sys/wait.h>
10#endif
11
12static char** parse_argv(const char* cmd, int* argc) {
13 if (!cmd || !*cmd) return NULL;
14 size_t len = strlen(cmd);
15 char* copy = malloc(len + 1);
16 if (!copy) return NULL;
17
18#ifdef _WIN32
19 strcpy_s(copy, len + 1, cmd);
20#else
21 strcpy(copy, cmd);
22#endif
23
24 *argc = 0;
25#ifdef _WIN32
26 char* context = NULL;
27 char* token = strtok_s(copy, " ", &context);
28#else
29 char* token = strtok(copy, " ");
30#endif
31 while (token) {
32 (*argc)++;
33#ifdef _WIN32
34 token = strtok_s(NULL, " ", &context);
35#else
36 token = strtok(NULL, " ");
37#endif
38 }
39
40#ifdef _WIN32
41 strcpy_s(copy, len + 1, cmd);
42#else
43 strcpy(copy, cmd);
44#endif
45
46 char** argv = malloc((*argc + 1) * sizeof(char*));
47 if (!argv) { free(copy); return NULL; }
48
49 int i = 0;
50#ifdef _WIN32
51 token = strtok_s(copy, " ", &context);
52#else
53 token = strtok(copy, " ");
54#endif
55 while (token) {
56 argv[i] = malloc(strlen(token) + 1);
57 if (!argv[i]) {
58 for (int j = 0; j < i; j++) free(argv[j]);
59 free(argv);
60 free(copy);
61 return NULL;
62 }
63#ifdef _WIN32
64 strcpy_s(argv[i], strlen(token) + 1, token);
65#else
66 strcpy(argv[i], token);
67#endif
68 i++;
69#ifdef _WIN32
70 token = strtok_s(NULL, " ", &context);
71#else
72 token = strtok(NULL, " ");
73#endif
74 }
75 argv[i] = NULL;
76 free(copy);
77 return argv;
78}
79
80static void free_argv(char** argv) {
81 if (!argv) return;
82 for (int i = 0; argv[i]; i++) free(argv[i]);
83 free(argv);
84}
85
86void asm_print_stdout(const char* s, int64_t len) {
87 fwrite(s, 1, (size_t)len, stdout);
88 fflush(stdout);
89}
90
91void asm_print_stderr(const char* s, int64_t len) {
92 fwrite(s, 1, (size_t)len, stderr);
93 fflush(stderr);
94}
95
96int64_t asm_system(const char* cmd) {
97 return (int64_t)system(cmd);
98}
99
100char *asm_system_out(const char* cmd) {
101 int argc;
102 char** argv = parse_argv(cmd, &argc);
103 if (!argv) return NULL;
104 char* output = NULL;
105 size_t output_size = 0;
106 size_t output_capacity = 1024;
107 output = malloc(output_capacity);
108 if (!output) {
109 free_argv(argv);
110 return NULL;
111 }
112#ifdef _WIN32
113 SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
114 HANDLE hRead, hWrite;
115 if (!CreatePipe(&hRead, &hWrite, &sa, 0)) {
116 free(output);
117 free_argv(argv);
118 return NULL;
119 }
120 STARTUPINFO si = { sizeof(STARTUPINFO) };
121 si.dwFlags = STARTF_USESTDHANDLES;
122 si.hStdOutput = hWrite; // capture stdout
123 si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
124 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
125 PROCESS_INFORMATION pi;
126 if (!CreateProcess(NULL, (char*)cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
127 CloseHandle(hRead);
128 CloseHandle(hWrite);
129 free(output);
130 free_argv(argv);
131 return NULL;
132 }
133 CloseHandle(hWrite);
134 DWORD bytesRead;
135 char buffer[1024];
136 while (ReadFile(hRead, buffer, sizeof(buffer), &bytesRead, NULL) && bytesRead > 0) {
137 if (output_size + bytesRead >= output_capacity) {
138 output_capacity *= 2;
139 char* new_output = realloc(output, output_capacity);
140 if (!new_output) {
141 CloseHandle(hRead);
142 CloseHandle(pi.hProcess);
143 CloseHandle(pi.hThread);
144 free(output);
145 free_argv(argv);
146 return NULL;
147 }
148 output = new_output;
149 }
150 memcpy(output + output_size, buffer, bytesRead);
151 output_size += bytesRead;
152 }
153 output[output_size] = '\0';
154 CloseHandle(hRead);
155 WaitForSingleObject(pi.hProcess, INFINITE);
156 CloseHandle(pi.hProcess);
157 CloseHandle(pi.hThread);
158#else
159 int pipefd[2];
160 if (pipe(pipefd) == -1) {
161 free(output);
162 free_argv(argv);
163 return NULL;
164 }
165 pid_t pid = fork();
166 if (pid == -1) {
167 close(pipefd[0]);
168 close(pipefd[1]);
169 free(output);
170 free_argv(argv);
171 return NULL;
172 }
173 if (pid == 0) {
174 close(pipefd[0]);
175 dup2(pipefd[1], STDOUT_FILENO);
176 close(pipefd[1]);
177 execvp(argv[0], argv);
178 _exit(1);
179 } else {
180 close(pipefd[1]);
181 ssize_t bytesRead;
182 char buffer[1024];
183 while ((bytesRead = read(pipefd[0], buffer, sizeof(buffer))) > 0) {
184 if (output_size + bytesRead >= output_capacity) {
185 output_capacity *= 2;
186 char* new_output = realloc(output, output_capacity);
187 if (!new_output) {
188 close(pipefd[0]);
189 free(output);
190 free_argv(argv);
191 return NULL;
192 }
193 output = new_output;
194 }
195 memcpy(output + output_size, buffer, bytesRead);
196 output_size += bytesRead;
197 }
198 output[output_size] = '\0';
199 close(pipefd[0]);
200 int status;
201 waitpid(pid, &status, 0);
202 }
203#endif
204 free_argv(argv);
205 return output;
206}
207
208char *asm_system_err(const char* cmd) {
209 int argc;
210 char** argv = parse_argv(cmd, &argc);
211 if (!argv) return NULL;
212 char* output = NULL;
213 size_t output_size = 0;
214 size_t output_capacity = 1024;
215 output = malloc(output_capacity);
216 if (!output) {
217 free_argv(argv);
218 return NULL;
219 }
220#ifdef _WIN32
221 SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
222 HANDLE hRead, hWrite;
223 if (!CreatePipe(&hRead, &hWrite, &sa, 0)) {
224 free(output);
225 free_argv(argv);
226 return NULL;
227 }
228 STARTUPINFO si = { sizeof(STARTUPINFO) };
229 si.dwFlags = STARTF_USESTDHANDLES;
230 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
231 si.hStdError = hWrite;
232 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
233 PROCESS_INFORMATION pi;
234 if (!CreateProcess(NULL, (char*)cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
235 CloseHandle(hRead);
236 CloseHandle(hWrite);
237 free(output);
238 free_argv(argv);
239 return NULL;
240 }
241 CloseHandle(hWrite);
242 DWORD bytesRead;
243 char buffer[1024];
244 while (ReadFile(hRead, buffer, sizeof(buffer), &bytesRead, NULL) && bytesRead > 0) {
245 if (output_size + bytesRead >= output_capacity) {
246 output_capacity *= 2;
247 char* new_output = realloc(output, output_capacity);
248 if (!new_output) {
249 CloseHandle(hRead);
250 CloseHandle(pi.hProcess);
251 CloseHandle(pi.hThread);
252 free(output);
253 free_argv(argv);
254 return NULL;
255 }
256 output = new_output;
257 }
258 memcpy(output + output_size, buffer, bytesRead);
259 output_size += bytesRead;
260 }
261 output[output_size] = '\0';
262 CloseHandle(hRead);
263 WaitForSingleObject(pi.hProcess, INFINITE);
264 CloseHandle(pi.hProcess);
265 CloseHandle(pi.hThread);
266#else
267 int pipefd[2];
268 if (pipe(pipefd) == -1) {
269 free(output);
270 free_argv(argv);
271 return NULL;
272 }
273 pid_t pid = fork();
274 if (pid == -1) {
275 close(pipefd[0]);
276 close(pipefd[1]);
277 free(output);
278 free_argv(argv);
279 return NULL;
280 }
281 if (pid == 0) {
282 close(pipefd[0]);
283 dup2(pipefd[1], STDERR_FILENO);
284 close(pipefd[1]);
285 execvp(argv[0], argv);
286 _exit(1);
287 } else {
288 close(pipefd[1]);
289 ssize_t bytesRead;
290 char buffer[1024];
291 while ((bytesRead = read(pipefd[0], buffer, sizeof(buffer))) > 0) {
292 if (output_size + bytesRead >= output_capacity) {
293 output_capacity *= 2;
294 char* new_output = realloc(output, output_capacity);
295 if (!new_output) {
296 close(pipefd[0]);
297 free(output);
298 free_argv(argv);
299 return NULL;
300 }
301 output = new_output;
302 }
303 memcpy(output + output_size, buffer, bytesRead);
304 output_size += bytesRead;
305 }
306 output[output_size] = '\0';
307 close(pipefd[0]);
308 int status;
309 waitpid(pid, &status, 0);
310 }
311#endif
312 free_argv(argv);
313 return output;
314}
char * asm_system_err(const char *cmd)
CRT system call, get err.
Definition IO.c:208
void asm_print_stdout(const char *s, int64_t len)
Native print function.
Definition IO.c:86
int64_t asm_system(const char *cmd)
CRT system call.
Definition IO.c:96
static void free_argv(char **argv)
Definition IO.c:80
void asm_print_stderr(const char *s, int64_t len)
Native print error function.
Definition IO.c:91
static char ** parse_argv(const char *cmd, int *argc)
Definition IO.c:12
char * asm_system_out(const char *cmd)
CRT system call, get out.
Definition IO.c:100