aboutgitcodelistschat:MatrixIRC
path: root/cooker/call.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2023-06-07 23:02:23 +0200
committerStefano Brivio <sbrivio@redhat.com>2023-06-07 23:06:32 +0200
commitc38fccbc867019d6c063be1c1d8137edfe52f8de (patch)
treeb3c1b398b4eb40e862263ee084b1dbb7463c1ada /cooker/call.c
parent1c1a9da7a4f9c4c1990192e14763ebf423d812a9 (diff)
downloadseitan-c38fccbc867019d6c063be1c1d8137edfe52f8de.tar
seitan-c38fccbc867019d6c063be1c1d8137edfe52f8de.tar.gz
seitan-c38fccbc867019d6c063be1c1d8137edfe52f8de.tar.bz2
seitan-c38fccbc867019d6c063be1c1d8137edfe52f8de.tar.lz
seitan-c38fccbc867019d6c063be1c1d8137edfe52f8de.tar.xz
seitan-c38fccbc867019d6c063be1c1d8137edfe52f8de.tar.zst
seitan-c38fccbc867019d6c063be1c1d8137edfe52f8de.zip
mknod/mknodat values, initial support for MASK flag, OP_BITWISE
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'cooker/call.c')
-rw-r--r--cooker/call.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/cooker/call.c b/cooker/call.c
index 7aef157..7ae3d48 100644
--- a/cooker/call.c
+++ b/cooker/call.c
@@ -113,10 +113,14 @@ static union value parse_field(struct gluten_ctx *g, struct arg *args,
if (tag_offset.type == OFFSET_NULL)
die(" tag not found");
- if (base_offset->type == OFFSET_NULL)
+ if (base_offset->type == OFFSET_NULL) {
*base_offset = tag_offset;
- else
+ } else if (f->flags & MASK || add) {
+ emit_bitwise(g, f->type, BITWISE_OR, offset,
+ offset, tag_offset);
+ } else {
emit_copy_field(g, f, offset, tag_offset);
+ }
}
if (json_object_get_count(tmp2) > count)
@@ -252,9 +256,10 @@ bool arg_needs_temp(struct field *f, int pos, JSON_Value *jvalue,
case INT:
case LONG:
case U32:
+ return false;
case GNU_DEV_MAJOR:
case GNU_DEV_MINOR:
- return false;
+ return true;
case SELECT:
f_inner = f->desc.d_select->field;
if (arg_needs_temp(f_inner, pos, jvalue, top_level_tag, level))
@@ -300,7 +305,7 @@ bool arg_needs_temp(struct field *f, int pos, JSON_Value *jvalue,
}
static struct gluten_offset parse_arg(struct gluten_ctx *g, struct arg *args,
- struct arg *a,
+ struct arg *a, bool multi_field,
struct gluten_offset offset,
JSON_Value *jvalue)
{
@@ -314,10 +319,15 @@ static struct gluten_offset parse_arg(struct gluten_ctx *g, struct arg *args,
return offset;
}
- if (arg_needs_temp(&a->f, a->pos, jvalue, &top_level_tag, 0))
- offset = gluten_rw_alloc(g, a->f.size);
- else if (a->f.size && !top_level_tag)
+ if (arg_needs_temp(&a->f, a->pos, jvalue, &top_level_tag, 0) ||
+ multi_field) {
+ if (a->f.size)
+ offset = gluten_rw_alloc(g, a->f.size);
+ else
+ offset = gluten_rw_alloc_type(g, a->f.type);
+ } else if ((a->f.size && !top_level_tag)) {
offset = gluten_ro_alloc(g, a->f.size);
+ }
parse_field(g, args, &offset, a->pos, &a->f, jvalue, false, false);
return offset;
@@ -336,6 +346,8 @@ static void parse_call(struct gluten_ctx *g, struct ns_spec *ns, long nr,
struct {
bool needs_fd;
bool has_fd;
+ bool found;
+ bool multi_field;
} arg_check[6] = { 0 };
int arg_max_pos = -1;
unsigned count = 0;
@@ -349,6 +361,10 @@ static void parse_call(struct gluten_ctx *g, struct ns_spec *ns, long nr,
a = g->selected_arg[a->pos];
}
+ if (arg_check[a->pos].found)
+ arg_check[a->pos].multi_field = true;
+ arg_check[a->pos].found = true;
+
if (a->f.type == FDPATH)
arg_check[a->pos].needs_fd = true;
@@ -362,10 +378,13 @@ static void parse_call(struct gluten_ctx *g, struct ns_spec *ns, long nr,
/* TODO: Factor this out into a function in... parse.c? */
for (a = args; a->f.name; a++) {
JSON_Value *jvalue;
+ bool multi_field;
if (a->f.type == SELECTED)
a = g->selected_arg[a->pos];
+ multi_field = arg_check[a->pos].multi_field;
+
/* Not common with parse_match(), though */
if ((jvalue = json_object_get_value(obj, a->f.name))) {
if (arg_check[a->pos].has_fd)
@@ -373,15 +392,15 @@ static void parse_call(struct gluten_ctx *g, struct ns_spec *ns, long nr,
else if (arg_check[a->pos].needs_fd)
arg_check[a->pos].has_fd = true;
- offset[a->pos] = parse_arg(g, args, a, offset[a->pos],
- jvalue);
+ offset[a->pos] = parse_arg(g, args, a, multi_field,
+ offset[a->pos], jvalue);
count++;
} else if (arg_check[a->pos].needs_fd &&
arg_check[a->pos].has_fd) {
;
} else if (a->f.flags & SIZE) {
- offset[a->pos] = parse_arg(g, args, a, offset[a->pos],
- jvalue);
+ offset[a->pos] = parse_arg(g, args, a, multi_field,
+ offset[a->pos], jvalue);
} else {
die(" No specification for argument %s", a->f.name);
}