#include "../include/exectd.h" #include "../include/vstr.h" #include size_t pack_execvpe_args(unsigned char *buffer, const char *file, char *const argv[], char *const envp[]) { unsigned char *start = buffer; // Pack the `file` string Vstr file_vstr = vstr_s(file); buffer += pack_vstr(buffer, &file_vstr); // Pack `argv` size_t argv_count = 0; while (argv && argv[argv_count]) argv_count++; memcpy(buffer, &argv_count, sizeof(size_t)); buffer += sizeof(size_t); for (size_t i = 0; i < argv_count; i++) { Vstr arg_vstr = vstr_s(argv[i]); buffer += pack_vstr(buffer, &arg_vstr); } // Pack `envp` size_t envp_count = 0; while (envp && envp[envp_count]) envp_count++; memcpy(buffer, &envp_count, sizeof(size_t)); buffer += sizeof(size_t); for (size_t i = 0; i < envp_count; i++) { Vstr env_vstr = vstr_s(envp[i]); buffer += pack_vstr(buffer, &env_vstr); } return buffer - start; // Total packed size } void unpack_execvpe_args(unsigned char *buffer, char **file, char ***argv, char ***envp) { // Unpack `file` Vstr file_vstr; unpack_vstr(buffer, &file_vstr); buffer += sizeof(size_t) + file_vstr.len; *file = strndup(file_vstr.buf, file_vstr.len); free(file_vstr.buf); // Unpack `argv` size_t argv_count; memcpy(&argv_count, buffer, sizeof(size_t)); buffer += sizeof(size_t); *argv = malloc((argv_count + 1) * sizeof(char *)); for (size_t i = 0; i < argv_count; i++) { Vstr arg_vstr; unpack_vstr(buffer, &arg_vstr); buffer += sizeof(size_t) + arg_vstr.len; (*argv)[i] = strndup(arg_vstr.buf, arg_vstr.len); free(arg_vstr.buf); } (*argv)[argv_count] = NULL; // Unpack `envp` size_t envp_count; memcpy(&envp_count, buffer, sizeof(size_t)); buffer += sizeof(size_t); *envp = malloc((envp_count + 1) * sizeof(char *)); for (size_t i = 0; i < envp_count; i++) { Vstr env_vstr; unpack_vstr(buffer, &env_vstr); buffer += sizeof(size_t) + env_vstr.len; (*envp)[i] = strndup(env_vstr.buf, env_vstr.len); free(env_vstr.buf); } (*envp)[envp_count] = NULL; } int main(void) { // Original arguments const char *file = "/bin/ls"; // Arguments for the ls command char *argv[] = {"ls", "-l", "-a", NULL}; // Custom environment variables char *envp[] = { "MY_ENV_VAR=example", "PATH=/usr/bin:/bin", // Ensure PATH is set for executable lookup NULL }; // Buffer for packing unsigned char buffer[1024]; // Adjust size as needed size_t packed_size; // Pack the arguments packed_size = pack_execvpe_args(buffer, file, argv, envp); (void)packed_size; // Unpack the arguments char *unpacked_file; char **unpacked_argv; char **unpacked_envp; unpack_execvpe_args(buffer, &unpacked_file, &unpacked_argv, &unpacked_envp); // Call execute_job with unpacked arguments int status = execute_job(unpacked_file, unpacked_argv, unpacked_envp); // Free unpacked arguments free(unpacked_file); for (char **arg = unpacked_argv; *arg; ++arg) free(*arg); free(unpacked_argv); for (char **env = unpacked_envp; *env; ++env) free(*env); free(unpacked_envp); // Check execution status if (status != 0) { printf("execute_job returned error code: %d\n", status); } printf("Job finished with %d \n",status); // Code here will run after the child process has finished return 0; }