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)
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()))