115 lines
3.5 KiB
C
115 lines
3.5 KiB
C
#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;
|
|
}
|