-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunc_callin.c
182 lines (148 loc) · 5 KB
/
func_callin.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#include <builtins.h>
#include <command.h> // for COMMAND.flags, among other things
#ifndef EXECUTION_FAILURE
#include <shell.h>
#endif
#include <builtins/bashgetopt.h> // for internal_getopt(), etc.
#include <builtins/common.h> // for no_options()
#include <stdio.h>
#include <stdarg.h>
#include "word_list_stack.h"
// Mysterious "line" value of COMMAND object: -538976289
// Is this number random or repeated?
// Copied from execute_cmd.h from bash source code, using code in command.h.
extern int execute_command PARAMS((COMMAND *));
extern int execute_shell_function PARAMS((SHELL_VAR *, WORD_LIST *));
SHELL_VAR *make_callback_function(void)
{
// Make WORD_LIST with a command and its arguments
WORD_LIST *head = NULL, *tail = NULL;
const char *wlist[] = {
"callout_target",
"imaginary",
"pretend",
"bogus",
// "echo",
// "Hello from the make_callback_function",
NULL
};
const char **wlarray = wlist;
WL_WALK(head, tail, wlarray);
// Make a COMMAND object, identify as `cm_simple` (command.h, enum command_type)
COMMAND *cmd = (COMMAND*)alloca(sizeof(COMMAND));
memset(cmd, 0, sizeof(COMMAND));
cmd->type = cm_simple;
cmd->value.Simple = (SIMPLE_COM*)alloca(sizeof(SIMPLE_COM));
memset(cmd->value.Simple, 0, sizeof(SIMPLE_COM));
cmd->value.Simple->words = head;
execute_command(cmd);
return NULL;
}
int call_with_execute_command(const char *function_name, ...)
{
SHELL_VAR *sv = find_function(function_name);
if (sv == NULL)
{
fprintf(stderr, "FAILED TO FIND function \x1b[32;1m%s\x1b[m.\n", function_name);
return EXECUTION_FAILURE;
}
WORD_LIST *head = NULL, *tail = NULL;
WL_APPEND(tail, function_name);
head = tail;
// Add any extra parameters to the WORD_LIST:
va_list args_list;
va_start(args_list, function_name);
const char *val;
while ((val = va_arg(args_list, const char*)))
WL_APPEND(tail, val);
va_end(args_list);
int flags = CMD_INHIBIT_EXPANSION | CMD_STDPATH;
COMMAND *command;
command = make_bare_simple_command();
command->value.Simple->words = head;
command->value.Simple->redirects = (REDIRECT *)NULL;
command->flags = command->value.Simple->flags = flags;
return execute_command(command);
}
static int func_callin(WORD_LIST *list)
{
printf("Entered 'func_callin'\n");
if (list == NULL)
{
builtin_usage();
return EX_USAGE;
}
/*****************************************
* Begin constructing COMMAND for callin
*****************************************/
// Begin constructing stack-based SHELL_VAR* containing
// a stack-based COMMAND.
// Make WORD_LIST with a command and its arguments
const char *bound_function_name = "CALLIN_CALLBACK";
WORD_LIST *head = NULL, *tail = NULL;
const char *wlist[] = {
"callout_target",
bound_function_name,
"imaginary",
"pretend",
"bogus",
// "echo",
// "Hello from the make_callback_function",
NULL
};
const char **wlarray = wlist;
WL_WALK(head, tail, wlarray);
// Make a COMMAND object, identify as `cm_simple` (command.h, enum command_type)
COMMAND *cmd = (COMMAND*)alloca(sizeof(COMMAND));
memset(cmd, 0, sizeof(COMMAND));
cmd->type = cm_simple;
cmd->value.Simple = (SIMPLE_COM*)alloca(sizeof(SIMPLE_COM));
memset(cmd->value.Simple, 0, sizeof(SIMPLE_COM));
cmd->value.Simple->words = head;
SHELL_VAR* svar_command = bind_function(bound_function_name, cmd);
/*****************************************
* DONE constructing COMMAND for callin
*****************************************/
const char *callback_function = list->word->word;
if (svar_command)
{
printf("Made a nice SVAR variable of type COMMAND of name %s.\n", bound_function_name);
return call_with_execute_command(callback_function, bound_function_name, NULL);
}
else
{
fprintf(stderr, "Failed to bind_command for function %s.\n", callback_function);
return EXECUTION_FAILURE;
}
}
static char *desc_func_callin[] = {
"This is a experiment aspiring to create function within",
"a builtin that can be returned to a calling function to",
"enable the calling script to initiate an action rather than",
"wait for the function to call out.",
(char *)NULL
};
struct builtin func_callin_struct = {
.name = "func_callin",
.function = func_callin,
.flags = BUILTIN_ENABLED,
.long_doc = desc_func_callin,
.short_doc = "func_callin return_variable",
.handle = 0
};
static int func_callin_callback(WORD_LIST *list)
{
return EXECUTION_SUCCESS;
}
static char *desc_func_callin_callback[] = {
"This function should only be handed to a ascript by func_callin.",
(char*)NULL
};
struct builtin func_callin_callback_struct = {
.name = "func_callin_callback",
.function = func_callin_callback,
.flags = BUILTIN_ENABLED,
.long_doc = desc_func_callin_callback,
.short_doc = "func_callin_callback return_variable",
.handle = 0
};