Added new tests examples with vstr
This commit is contained in:
parent
28799e4770
commit
8154311739
35
include/vstr.h
Normal file
35
include/vstr.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef VSTR_INCLUDED
|
||||||
|
#define VSTR_INCLUDED
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
struct Vstr {
|
||||||
|
size_t len; // String len
|
||||||
|
char *buf; // String data
|
||||||
|
};
|
||||||
|
typedef struct Vstr Vstr;
|
||||||
|
|
||||||
|
#define Vstr_Fmt "%.*s"
|
||||||
|
#define Vstr_Arg(vstr) (int) (vstr).len, (vstr).buf
|
||||||
|
#define VSTR(cstr) vstr_n(cstr, sizeof(cstr) - 1)
|
||||||
|
#define VSTR_NULL vstr_n(NULL, 0)
|
||||||
|
|
||||||
|
size_t pack_vstr(unsigned char *buffer, Vstr *vstr);
|
||||||
|
void unpack_vstr(unsigned char *buffer, Vstr *vstr);
|
||||||
|
size_t pack_vstr_array(unsigned char *buffer, Vstr *array, size_t count);
|
||||||
|
Vstr *unpack_vstr_array(unsigned char *buffer, size_t *count);
|
||||||
|
Vstr vstr_s(const char *s);
|
||||||
|
Vstr vstr_n(const char *s, size_t n);
|
||||||
|
bool vstr_cmp(const Vstr v1, const Vstr v2);
|
||||||
|
const char *vstr_str(const Vstr haystack, const Vstr needle);
|
||||||
|
Vstr vstr_after_delim(const Vstr v, const char *delims);
|
||||||
|
Vstr vstr_before_delim(const Vstr v, const char *delims);
|
||||||
|
Vstr vstr_substr(Vstr v, size_t start, size_t stop);
|
||||||
|
Vstr vstr_trim(Vstr v);
|
||||||
|
Vstr vstr_trim_left(Vstr v);
|
||||||
|
Vstr vstr_trim_right(Vstr v);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
215
src/vstr.c
Normal file
215
src/vstr.c
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
#include "../include/vstr.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
size_t pack_vstr(unsigned char *buffer, Vstr *vstr) {
|
||||||
|
size_t offset = 0;
|
||||||
|
|
||||||
|
// Pack the length of the string first (size_t)
|
||||||
|
buffer[offset++] = (vstr->len >> 56) & 0xFF;
|
||||||
|
buffer[offset++] = (vstr->len >> 48) & 0xFF;
|
||||||
|
buffer[offset++] = (vstr->len >> 40) & 0xFF;
|
||||||
|
buffer[offset++] = (vstr->len >> 32) & 0xFF;
|
||||||
|
buffer[offset++] = (vstr->len >> 24) & 0xFF;
|
||||||
|
buffer[offset++] = (vstr->len >> 16) & 0xFF;
|
||||||
|
buffer[offset++] = (vstr->len >> 8) & 0xFF;
|
||||||
|
buffer[offset++] = vstr->len & 0xFF;
|
||||||
|
|
||||||
|
// Pack the string data
|
||||||
|
memcpy(&buffer[offset], vstr->buf, vstr->len);
|
||||||
|
offset += vstr->len;
|
||||||
|
|
||||||
|
return offset; // Return the total packed size
|
||||||
|
}
|
||||||
|
void unpack_vstr(unsigned char *buffer, Vstr *vstr) {
|
||||||
|
unsigned int offset = 0;
|
||||||
|
|
||||||
|
// Unpack the length of the string (size_t)
|
||||||
|
vstr->len = 0;
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
vstr->len = (vstr->len << 8) | buffer[offset++];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate memory for the string and copy it from the buffer
|
||||||
|
vstr->buf = (char *)malloc(vstr->len + 1); // +1 for null terminator
|
||||||
|
if (vstr->buf != NULL) {
|
||||||
|
memcpy(vstr->buf, &buffer[offset], vstr->len);
|
||||||
|
vstr->buf[vstr->len] = '\0'; // Null-terminate the string
|
||||||
|
} else {
|
||||||
|
vstr->len = 0; // If memory allocation fails, set len to 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t pack_vstr_array(unsigned char *buffer, Vstr *array, size_t count) {
|
||||||
|
size_t offset = 0;
|
||||||
|
|
||||||
|
// Pack the number of elements in the array
|
||||||
|
buffer[offset++] = (count >> 56) & 0xFF;
|
||||||
|
buffer[offset++] = (count >> 48) & 0xFF;
|
||||||
|
buffer[offset++] = (count >> 40) & 0xFF;
|
||||||
|
buffer[offset++] = (count >> 32) & 0xFF;
|
||||||
|
buffer[offset++] = (count >> 24) & 0xFF;
|
||||||
|
buffer[offset++] = (count >> 16) & 0xFF;
|
||||||
|
buffer[offset++] = (count >> 8) & 0xFF;
|
||||||
|
buffer[offset++] = count & 0xFF;
|
||||||
|
|
||||||
|
// Pack each Vstr in the array
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
// Pack the length of the string
|
||||||
|
buffer[offset++] = (array[i].len >> 56) & 0xFF;
|
||||||
|
buffer[offset++] = (array[i].len >> 48) & 0xFF;
|
||||||
|
buffer[offset++] = (array[i].len >> 40) & 0xFF;
|
||||||
|
buffer[offset++] = (array[i].len >> 32) & 0xFF;
|
||||||
|
buffer[offset++] = (array[i].len >> 24) & 0xFF;
|
||||||
|
buffer[offset++] = (array[i].len >> 16) & 0xFF;
|
||||||
|
buffer[offset++] = (array[i].len >> 8) & 0xFF;
|
||||||
|
buffer[offset++] = array[i].len & 0xFF;
|
||||||
|
|
||||||
|
// Pack the string data
|
||||||
|
memcpy(&buffer[offset], array[i].buf, array[i].len);
|
||||||
|
offset += array[i].len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset; // Return the total packed size
|
||||||
|
}
|
||||||
|
Vstr *unpack_vstr_array(unsigned char *buffer, size_t *count) {
|
||||||
|
size_t offset = 0;
|
||||||
|
|
||||||
|
// Unpack the number of elements in the array
|
||||||
|
*count = 0;
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
*count = (*count << 8) | buffer[offset++];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate memory for the Vstr array
|
||||||
|
Vstr *array = malloc(*count * sizeof(Vstr));
|
||||||
|
if (!array) return NULL; // Memory allocation failure
|
||||||
|
|
||||||
|
// Unpack each Vstr in the array
|
||||||
|
for (size_t i = 0; i < *count; i++) {
|
||||||
|
// Unpack the length of the string
|
||||||
|
array[i].len = 0;
|
||||||
|
for (int j = 0; j < 8; j++) {
|
||||||
|
array[i].len = (array[i].len << 8) | buffer[offset++];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate memory for the string
|
||||||
|
array[i].buf = malloc(array[i].len + 1); // +1 for null terminator
|
||||||
|
if (!array[i].buf) {
|
||||||
|
// Free previously allocated memory in case of failure
|
||||||
|
for (size_t k = 0; k < i; k++) {
|
||||||
|
free(array[k].buf);
|
||||||
|
}
|
||||||
|
free(array);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the string data
|
||||||
|
memcpy(array[i].buf, &buffer[offset], array[i].len);
|
||||||
|
array[i].buf[array[i].len] = '\0'; // Null-terminate the string
|
||||||
|
offset += array[i].len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vstr vstr_s(const char *s){
|
||||||
|
Vstr v = {s == NULL ? 0 : strlen(s), (char *)s};
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
Vstr vstr_n(const char *s, size_t n){
|
||||||
|
Vstr v = {n,(char *)s};
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
bool vstr_cmp(const Vstr v1, const Vstr v2){
|
||||||
|
size_t i = 0;
|
||||||
|
while (i < v1.len && i < v2.len) {
|
||||||
|
int c1 = v1.buf[i];
|
||||||
|
int c2 = v2.buf[i];
|
||||||
|
if (c1 < c2) return false;
|
||||||
|
if (c1 > c2) return true;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i < v1.len) return true;
|
||||||
|
if (i < v2.len) return false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const char *vstr_str(const Vstr haystack, const Vstr needle){
|
||||||
|
size_t i;
|
||||||
|
if (needle.len > haystack.len) return NULL;
|
||||||
|
if (needle.len == 0) return haystack.buf;
|
||||||
|
for (i = 0; i <= haystack.len - needle.len; i++) {
|
||||||
|
if (memcmp(haystack.buf + i, needle.buf, needle.len) == 0) {
|
||||||
|
return haystack.buf + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Vstr vstr_after_delim(const Vstr v, const char *delims) {
|
||||||
|
// Handle NULL pointer or empty string view
|
||||||
|
if (v.buf == NULL || delims == NULL) {
|
||||||
|
return vstr_n(NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
while (i < v.len) {
|
||||||
|
// Check if the current character is a delimiter
|
||||||
|
for (size_t j = 0; delims[j] != '\0'; j++) {
|
||||||
|
if (v.buf[i] == delims[j]) {
|
||||||
|
Vstr result = vstr_n(v.buf+i+1, v.len-i-1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the whole string if no delimiter was found
|
||||||
|
Vstr result = vstr_n(v.buf, i);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
Vstr vstr_before_delim(const Vstr v, const char *delims) {
|
||||||
|
// Handle NULL pointer or empty string view
|
||||||
|
if (v.buf == NULL || delims == NULL) {
|
||||||
|
return vstr_n(NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
while (i < v.len) {
|
||||||
|
// Check if the current character is a delimiter
|
||||||
|
for (size_t j = 0; delims[j] != '\0'; j++) {
|
||||||
|
if (v.buf[i] == delims[j]) {
|
||||||
|
Vstr result = vstr_n(v.buf, i);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the whole string if no delimiter was found
|
||||||
|
Vstr result = vstr_n(v.buf, i);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
Vstr vstr_substr(Vstr v, size_t start, size_t stop) {
|
||||||
|
if (start >= v.len || stop > v.len || start >= stop) {
|
||||||
|
// Return an empty Vstr if indices are out of bounds or invalid
|
||||||
|
return vstr_n(NULL, 0);
|
||||||
|
}
|
||||||
|
size_t sub_len = stop - start;
|
||||||
|
return vstr_n(v.buf + start, sub_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_space(int c) {
|
||||||
|
return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f';
|
||||||
|
}
|
||||||
|
Vstr vstr_trim(Vstr v){
|
||||||
|
while (v.len > 0 && is_space((int) *v.buf)) v.buf++, v.len--;
|
||||||
|
while (v.len > 0 && is_space((int) *(v.buf + v.len - 1))) v.len--;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
Vstr vstr_trim_left(Vstr v){
|
||||||
|
while (v.len > 0 && is_space((int) *v.buf)) v.buf++, v.len--;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
Vstr vstr_trim_right(Vstr v){
|
||||||
|
while (v.len > 0 && is_space((int) *(v.buf + v.len - 1))) v.len--;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,15 @@
|
|||||||
#include "../include/exectd.h"
|
#include "../include/exectd.h"
|
||||||
int main() {
|
int main() {
|
||||||
char *argv[] = {"/bin/ping", "-c","3","myrepos.dev", NULL}; // Example arguments
|
// Arguments for the ls command
|
||||||
char *envp[] = {NULL}; // Example environment variables
|
char *argv[] = {"ls", "-l", "-a", NULL};
|
||||||
int status = execute_job("/bin/ping", argv, envp);
|
|
||||||
|
// Custom environment variables
|
||||||
|
char *envp[] = {
|
||||||
|
"MY_ENV_VAR=example",
|
||||||
|
"PATH=/usr/bin:/bin", // Ensure PATH is set for executable lookup
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
int status = execute_job("/bin/ls", argv, envp);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
// Handle error
|
// Handle error
|
||||||
printf("my_execve returned error code: %d\n", status);
|
printf("my_execve returned error code: %d\n", status);
|
||||||
|
@ -1,10 +1,19 @@
|
|||||||
#include "../include/exectd.h"
|
#include "../include/exectd.h"
|
||||||
int main() {
|
int main() {
|
||||||
char *argv[] = {"/bin/ping", "-c","3","myrepos.dev", NULL}; // Example arguments
|
|
||||||
char *envp[] = {NULL}; // Example environment variables
|
// 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
|
||||||
|
};
|
||||||
|
|
||||||
int fd = ext_open("tests/bin/stdout_dup", O_WRONLY | O_CREAT);
|
int fd = ext_open("tests/bin/stdout_dup", O_WRONLY | O_CREAT);
|
||||||
int fd2 = ext_open("tests/bin/stderr_dup", O_WRONLY | O_CREAT);
|
int fd2 = ext_open("tests/bin/stderr_dup", O_WRONLY | O_CREAT);
|
||||||
int status = shell_job("/bin/ping", argv, envp, fd, fd2);
|
int status = shell_job("/bin/ls", argv, envp, fd, fd2);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
// Handle error
|
// Handle error
|
||||||
printf("Shell job returned error code: %d\n", status);
|
printf("Shell job returned error code: %d\n", status);
|
||||||
|
114
tests/04_packed.c
Normal file
114
tests/04_packed.c
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
#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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user