aboutgitcodelistschat:MatrixIRC
path: root/cooker/call.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2023-12-21 12:06:05 +0100
committerStefano Brivio <sbrivio@redhat.com>2023-12-21 12:45:36 +0100
commitbdbec30a849807fb5e6841a38cfe0d168e5962b9 (patch)
tree210949d96b4d764235c1c5b81ad2eebb61681f95 /cooker/call.c
parentc72c2493de8990c3a3b4780ec1429a3c359c121e (diff)
downloadseitan-bdbec30a849807fb5e6841a38cfe0d168e5962b9.tar
seitan-bdbec30a849807fb5e6841a38cfe0d168e5962b9.tar.gz
seitan-bdbec30a849807fb5e6841a38cfe0d168e5962b9.tar.bz2
seitan-bdbec30a849807fb5e6841a38cfe0d168e5962b9.tar.lz
seitan-bdbec30a849807fb5e6841a38cfe0d168e5962b9.tar.xz
seitan-bdbec30a849807fb5e6841a38cfe0d168e5962b9.tar.zst
seitan-bdbec30a849807fb5e6841a38cfe0d168e5962b9.zip
seitan: Add netlink, sendto()/sendmsg(), iovec handling, demo with routes
A bit rough at the moment, but it does the trick. Bonus: setsockopt() (with magic values only, not used in any demo yet). Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'cooker/call.c')
-rw-r--r--cooker/call.c61
1 files changed, 55 insertions, 6 deletions
diff --git a/cooker/call.c b/cooker/call.c
index bb53829..dd37fe9 100644
--- a/cooker/call.c
+++ b/cooker/call.c
@@ -72,7 +72,7 @@ static union value parse_metadata(struct gluten_ctx *g, struct field *f,
if (tag_offset.type == OFFSET_NULL)
die(" tag not found");
- if ((*base_offset)->type == OFFSET_NULL) {
+ if ((*base_offset)->type == OFFSET_NULL || (f->flags & WBUF)) {
**base_offset = tag_offset;
} else if (f->flags & MASK || add) {
emit_bitwise(g, f->type, BITWISE_OR, offset, offset,
@@ -133,6 +133,10 @@ Examples of arguments:
- STRING: abcd write abcd to ro_data (using size), and pointer to it
parse_arg() passes ro_data offset
+- IOV: <tag> write (one!) struct iovec with iov_base pointer to tag
+ parse_arg() passes null offset
+ parse_field() gives back data offset
+
- STRUCT: 1, 2 write struct to ro_data, and pointer to it
parse_arg() passes ro_data offset
@@ -169,12 +173,38 @@ static union value parse_field(struct gluten_ctx *g, struct arg *args,
(tmp1 = json_value_get_object(jvalue)) && is_metadata_obj(tmp1)) {
v = parse_metadata(g, f, &base_offset, offset, tmp1, dry_run,
add);
- if (v.v_num == 0)
+ if (!(f->flags & IOV) && v.v_num == 0)
+ return v;
+ }
+
+ if (f->flags & IOV) {
+ struct gluten_offset iov;
+ struct iovec *iovp;
+ intptr_t *msg_iov;
+
+ if (dry_run)
return v;
+
+ /* iov_base: v */
+ /* iov_len: at the moment from field */
+ msg_iov = (intptr_t *)gluten_ptr(&g->g, offset);
+
+ iov = gluten_rw_alloc(g, sizeof(struct iovec));
+ iovp = (struct iovec *)gluten_ptr(&g->g, iov);
+ iovp->iov_base = (void *)(intptr_t)base_offset->offset;
+ gluten_relocation_add(g, iov);
+
+ iovp->iov_len = f->size;
+
+ *msg_iov = iov.offset;
+ gluten_relocation_add(g, offset);
+
+ return v;
}
if (!jvalue && !(f->flags & SIZE))
return v;
+
switch (f->type) {
case USHORT:
case INT:
@@ -249,12 +279,28 @@ static union value parse_field(struct gluten_ctx *g, struct arg *args,
tmp1 = json_value_get_object(jvalue);
f_value = json_object_get_value(tmp1, f_inner->name);
- debug(" parse struct internal value:%s",
+ debug(" parse struct, field %s, internal value:%s",
+ f_inner->name,
json_serialize_to_string(f_value));
- if (!f_value)
+ if (!f_value && !(f_inner->flags & SIZE))
continue;
- parse_field(g, args, &struct_start, index, f_inner,
- f_value, false, add);
+
+ if (f_inner->size && f_inner->type == SELECT) {
+ struct gluten_offset ptr_offset;
+ intptr_t *link;
+
+ ptr_offset = gluten_rw_alloc(g, f_inner->size);
+ parse_field(g, args, &ptr_offset, index, f_inner,
+ f_value, false, add);
+
+ link = (intptr_t *)gluten_ptr(&g->g, offset);
+ *link = ptr_offset.offset;
+ gluten_relocation_add(g, offset);
+ } else {
+ parse_field(g, args, &struct_start, index, f_inner,
+ f_value, false, add);
+ }
+
if (base_offset->type == OFFSET_NULL)
*base_offset = struct_start;
}
@@ -278,6 +324,9 @@ bool arg_needs_temp(struct field *f, int pos, JSON_Value *jvalue,
if (f->flags & COPY_ON_CALL)
return true;
+ if (f->flags & IOV)
+ return true;
+
if (f->flags & SIZE)
return false;