commit c83d3ad2215baa5da4309224a33cdb9d7029a2d8
parent 9d332950dd77f13f48c8bff595208b70c1139d9d
Author: 5hif7y <[email protected]>
Date: Fri, 3 Jan 2025 01:44:20 -0300
9 run a program
Diffstat:
| M | app/main.c | | | 101 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- |
1 file changed, 90 insertions(+), 11 deletions(-)
diff --git a/app/main.c b/app/main.c
@@ -4,13 +4,17 @@
#include <stdlib.h>
#ifdef _WIN32
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
#define F_OK 0
#else
+ #include <sys/wait.h>
#include <unistd.h>
#endif
void parse_input(const char *input, char *cmd, char **args, int *argc);
bool find_executable(const char *cmd, char *result_path);
+void run_executable(const char *cmd, char **args);
int main() {
@@ -65,7 +69,12 @@ int main() {
printf("Usage: type [command]\n");
}
} else {
- printf("%s: command not found\n", cmd);
+ char path[512];
+ if (find_executable(cmd, path)){
+ run_executable(path, args);
+ } else {
+ printf("%s: command not found\n", cmd);
+ }
}
//free mem
@@ -101,6 +110,33 @@ void parse_input(const char *input, char *cmd, char **args, int *argc){
}
bool find_executable(const char *cmd, char *result_path){
+
+ // First, search in current folder
+ #ifdef _WIN32
+ const char *extensions[] = {".exe", NULL}; // Extension support list
+ // ------------
+ if (strchr(cmd, '.')){
+ snprintf(result_path, 512, ".\\%s", cmd);
+ if (access(result_path, F_OK) == 0){
+ return true;
+ }
+ } else {
+ for (const char **ext = extensions; *ext != NULL; ext++){
+ snprintf(result_path, 512, ".\\%s%s", cmd, *ext);
+ if (access(result_path, F_OK) == 0){
+ return true;
+ }
+ }
+
+ #else
+ // In POSIX systems, simply search in current folder
+ snprintf(result_path, 512, "./%s", cmd);
+ if (access(result_path, F_OK) == 0){
+ return true;
+ }
+ #endif
+
+ // Second, search in PATH
char *path_env = getenv("PATH");
if(!path_env){
return false;
@@ -111,32 +147,75 @@ bool find_executable(const char *cmd, char *result_path){
path_copy[sizeof(path_copy) - 1] = '\0';
char separator = ':';
-#ifdef _WIN32
- separator = ';';
-#endif
+ #ifdef _WIN32
+ separator = ';';
+ #endif
char *dir = strtok(path_copy, &separator);
while (dir != NULL){
- snprintf(result_path, 512, "%s/%s", dir, cmd);
-#ifdef _WIN32
- const char *extensions[] = {".exe", NULL}; // Extension support list
- for (const char **ext = extensions; *ext != NULL; ext++){
- snprintf(result_path, 512, "%s\\%s%s", dir, cmd, *ext);
+ if (strlen(dir) > 0) {
+ #ifdef _WIN32
+ if (strchr(cmd, '.')){
+ snprintf(result_path, 512, "%s\\%s", dir, cmd);
if (access(result_path, F_OK) == 0){
return true;
}
+ } else {
+ for (const char **ext = extensions; *ext != NULL; ext++){
+ snprintf(result_path, 512, "%s\\%s%s", dir, cmd, *ext);
+ if (access(result_path, F_OK) == 0){
+ return true;
+ }
+ }
}
-#else
+ #else
+ snprintf(result_path, 512, "%s/%s", dir, cmd);
if(access(result_path, X_OK) == 0){
return true;
}
-#endif
+ #endif
+ }
dir = strtok(NULL, &separator);
}
return false;
}
+void run_executable(const char *cmd, char **args){
+ #ifdef _WIN32
+ // 1. Build command line
+ char command_line[1024] = {0};
+ snprintf(command_line, sizeof(command_line), "\"%s\"", cmd);
+
+ for (int i = 0; args[i] != NULL; i++){
+ strncat(command_line, " ", sizeof(command_line) - strlen(command_line) - 1);
+ strncat(command_line, args[i], sizeof(command_line) - strlen(command_line) - 1);
+ }
+ // 2. Setup structures for 'CreateProcess'
+ STARTUPINFO si = {0};
+ PROCESS_INFORMATION pi = {0};
+ si.cb = sizeof(STARTUPINFO);
+
+ // 3. Try to create process
+ if (!CreateProcess(NULL, command_line, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)){
+ fprintf(stderr, "Error: error executing command %s\n", cmd);
+ } else {
+ WaitForSingleObject(pi.hProcess, INFINITE);
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ }
+
+ #else
+ // Use 'execvp' in POSIX systems
+ if (fork() == 0){
+ execvp(cmd, args);
+ perror("Error executing command");
+ exit(EXIT_FAILURE);
+ } else {
+ wait(NULL);
+ }
+ #endif
+}