exectd/tests/04_packed.c

115 lines
3.5 KiB
C
Raw Permalink Normal View History

2024-11-23 15:46:38 +00:00
#include "../include/exectd.h"
#include "../include/vstr.h"
#include <stdlib.h>
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;
}