Esempio n. 1
0
def write_syscall(dirpath, syscall):
    local_vars = []
    for datatype, name in (
            ("payload_size_t", "payload_size"),
            ("int", "error")):
        local_vars.append(Variable(datatype, name))
    if 0 < len(syscall.input_args):
        for datatyoe, name in (("int", "wfd"), ):
            local_vars.append(Variable(datatype, name))
    for a in syscall.args:
        if (a.datatype == "void *") or data_of_argument(syscall, a).out:
            continue
        if a.datatype == "char *":
            local_vars.extend(make_string_locals(a.name))
            continue
        if a.datatype == "struct iovec *":
            local_vars.append(Variable(a.datatype, a.name))
            local_vars.append(Variable("u_int", "i"))
            name = "{name}_payload_size".format(**vars(a))
            local_vars.append(Variable("payload_size_t", name))

            size = bufsize_of_datatype("size_t")
            datatype = "char (*)[{size}]".format(**locals())
            name = "{name}_iov_len_buf".format(name=a.name)
            local_vars.append(Variable(datatype, name))

            name = "{name}_iov_len_len".format(name=a.name)
            local_vars.append(Variable("int *", name))
            continue
        for datatype, fmt, size in (
                (a.datatype, "{name}", None),
                ("char", "{name}_buf", bufsize_of_datatype(a.datatype)),
                ("int", "{name}_len", None)):
            v = Variable(datatype, fmt.format(name=a.name), size)
            local_vars.append(v)

    name = syscall.name
    with open(join(dirpath, name) + ".c", "w") as fp:
        p, print_newline = partial_print(fp)
        print_head(syscall, p, name)
        print_locals(p, local_vars)
        print_newline()
        print_encoding(p, syscall)
        if 0 < len(syscall.args):
            print_newline()
        print_write(p, print_newline, syscall)
        print_newline()
        print_tail(p, print_newline, syscall)
Esempio n. 2
0
def print_fslave_return(p, print_newline, syscall):
    output_args = syscall.output_args
    args = ", ".join([make_formal_arguments_of_execute_return(syscall, a)
                      for a in output_args])
    p("""\
static void
execute_return(struct slave_thread *slave_thread, int retval, int errnum, {args})
{{
""".format(**locals()))

    local_vars = [Variable(datatype, name, size) for datatype, name, size in (
        ("payload_size_t", "payload_size", None),
        ("char", "retval_buf", bufsize_of_datatype(syscall.rettype)),
        ("int", "retval_len", None),
        ("int", "wfd", None))]
    out_arguments = syscall.output_args
    for a in out_arguments:
        datatype = a.datatype
        if a.datatype in ("char *", "void *"):
            # in case of an array
            continue

        st = data_of_argument(syscall, a).struct
        append = local_vars.append
        if st is not None:
            for datatype, name in st.expand_all_members(a.name):
                fmt = "{name}_len"
                append(Variable("int", fmt.format(**locals())))

                fmt = "{name}_buf"
                size = bufsize_of_datatype(datatype)
                append(Variable("char", fmt.format(**locals()), size))
            continue

        name = a.name
        size = bufsize_of_datatype(drop_pointer(datatype))
        append(Variable("int", "{name}_len".format(**locals())))
        append(Variable("char", "{name}_buf".format(**locals()), size))

    print_locals(p, local_vars)
    print_newline()
    cmd_name = make_cmd_name(syscall.name)
    return_func = get_fslave_return_func(syscall)
    p("""\
\tif (retval == -1) {{
\t\t{return_func}(slave_thread, {cmd_name}_RETURN, retval, errnum);
\t\treturn;
\t}}
""".format(**locals()))
    print_newline()
    p("""\
\tretval_len = encode_{datatype}(retval, retval_buf, array_sizeof(retval_buf));
""".format(datatype=concrete_datatype_of_abstract_datatype(syscall.rettype)))
    for a in out_arguments:
        if a.datatype in ("char *", "void *"):
            continue
        st = data_of_argument(syscall, a).struct
        if st is not None:
            for datatype, var, name in st.zip_members(a.name, "->"):
                struct_name = a.name
                t = concrete_datatype_of_abstract_datatype(datatype)
                p("""\
\t{var}_len = encode_{t}({name}, {var}_buf, array_sizeof({var}_buf));
""".format(**locals()))
            continue
        name = a.name
        t = drop_pointer(a.datatype)
        datatype = concrete_datatype_of_abstract_datatype(t)
        p("""\
\t{name}_len = encode_{datatype}({name}, {name}_buf, sizeof({name}_buf));
""".format(**locals()))

    payload_size = make_payload_size_expr(syscall, out_arguments, "retsize")
    p("""\
\tpayload_size = retval_len + {payload_size};

\twfd = slave_thread->fsth_wfd;
\twrite_command(wfd, {cmd_name}_RETURN);
\twrite_payload_size(wfd, payload_size);
\twrite_or_die(wfd, retval_buf, retval_len);
""".format(**locals()))
    for a in out_arguments:
        if a.datatype in ("char *", "void *"):
            name = a.name
            size = data_of_argument(syscall, a).retsize
            p("""\
\twrite_or_die(wfd, {name}, {size});
""".format(**locals()))
            continue
        st = data_of_argument(syscall, a).struct
        if st is not None:
            for _, name in st.expand_all_members(a.name):
                p("""\
\twrite_or_die(wfd, {name}_buf, {name}_len);
""".format(**locals()))
            continue
        name = a.name
        p("""\
\twrite_or_die(wfd, {name}_buf, {name}_len);
""".format(**locals()))

    newlined = False
    for a in out_arguments:
        data = data_of_argument(syscall, a)
        if not data.is_array:
            continue
        if not newlined:
            print_newline()
            newlined = True
        p("""\
\tfree({name});
""".format(**vars(a)))
    p("""\
}}
""".format(**locals()))