// retoor #define _GNU_SOURCE #include "bash_executor.h" #include #include #include #include #include #include char *r_bash_execute(const char *command, bool interactive) { if (!command) { return strdup("Error: null command"); } size_t len = strlen(command); char *cmd_with_nl = malloc(len + 2); if (!cmd_with_nl) { return strdup("Error: memory allocation failed"); } strcpy(cmd_with_nl, command); if (len > 0 && cmd_with_nl[len - 1] != '\n') { cmd_with_nl[len] = '\n'; cmd_with_nl[len + 1] = '\0'; } else if (len == 0) { cmd_with_nl[0] = '\n'; cmd_with_nl[1] = '\0'; } char tmp_script[] = "/tmp/r_bash_XXXXXX.sh"; int fd = mkstemps(tmp_script, 3); if (fd == -1) { free(cmd_with_nl); perror("mkstemps"); return strdup("Error: failed to create temp script"); } if (write(fd, cmd_with_nl, strlen(cmd_with_nl)) == -1) { close(fd); free(cmd_with_nl); unlink(tmp_script); return strdup("Error: failed to write to temp script"); } close(fd); free(cmd_with_nl); char *output = NULL; if (interactive) { char *run_cmd = NULL; if (asprintf(&run_cmd, "bash %s", tmp_script) == -1) { unlink(tmp_script); return strdup("Error: asprintf failed"); } int status = system(run_cmd); free(run_cmd); if (asprintf(&output, "Command exited with status %d", status) == -1) { output = strdup("Command completed (asprintf failed for status)."); } } else { char *run_cmd = NULL; if (asprintf(&run_cmd, "bash %s 2>&1", tmp_script) == -1) { unlink(tmp_script); return strdup("Error: asprintf failed"); } FILE *fp = popen(run_cmd, "r"); free(run_cmd); if (!fp) { unlink(tmp_script); return strdup("Error: popen failed"); } char buffer[1024]; size_t total_size = 0; while (fgets(buffer, sizeof(buffer), fp)) { // Print to stderr for the user in a subtle dim/gray color fprintf(stderr, "\033[2m%s\033[0m", buffer); size_t chunk_len = strlen(buffer); char *new_output = realloc(output, total_size + chunk_len + 1); if (!new_output) { free(output); pclose(fp); unlink(tmp_script); return strdup("Error: memory allocation failed"); } output = new_output; strcpy(output + total_size, buffer); total_size += chunk_len; } pclose(fp); if (!output) { output = strdup(""); } } unlink(tmp_script); return output; }