| | 73 | | void perl_signal_args_to_c( | | | 74 | | void (*callback)(void *, void **), void *cb_arg, | | true | 75 | | int signal_id, SV **args, size_t n_args) | | | 76 | | { | | | 77 | | union { | | | 78 | | int v_int; | | | 79 | | unsigned long v_ulong; | | | 80 | | GSList *v_gslist; | | | 81 | | GList *v_glist; | | | 82 | | } saved_args[SIGNAL_MAX_ARGUMENTS];
| | | 83 | | void *p[SIGNAL_MAX_ARGUMENTS];
| | | 84 | | PERL_SIGNAL_ARGS_REC *rec; | | | 85 | | size_t n; | | | 86 | | | | | 87 | | if (!(rec = perl_signal_args_find(signal_id))) { | | | 88 | | const char *name = signal_get_id_str(signal_id);
| | | 89 | | if (!name) { | | | 90 | | croak("%d is not a known signal id", signal_id);
| | | 91 | | } | | | 92 | | croak("\"%s\" is not a registered signal", name);
| | | 93 | | } | | | 94 | | | | | 95 | | for (n = 0; n < SIGNAL_MAX_ARGUMENTS && n < n_args && rec->args[n] != NULL; ++n) {
| | | 96 | | void *c_arg; | | | 97 | | SV *arg = args[n]; | | | 98 | | | | | 99 | | if (!SvOK(arg)) {
| | | 100 | | c_arg = NULL;
| | | 101 | | } else if (strcmp(rec->args[n], "string") == 0) { | | | 102 | | c_arg = SvPV_nolen(arg);
| | | 103 | | } else if (strcmp(rec->args[n], "int") == 0) { | | | 104 | | c_arg = (void *)SvIV(arg);
| | | 105 | | } else if (strcmp(rec->args[n], "ulongptr") == 0) { | | | | | ... | | | 160 | | ); | | | 161 | | } | | | 162 | | c_arg = saved_args[n].v_gslist = gsl; | | | 163 | | } else { | | | 164 | | c_arg = (arg); | | | 165 | | } | | | 166 | | | | | 167 | | p[n] = c_arg; | | | 168 | | } | | | 169 | | | | | 170 | | for (; n < SIGNAL_MAX_ARGUMENTS; ++n) {
| | | 171 | | p[n] = NULL;
| | | 172 | | } | | | 173 | | | | | 174 | | callback(cb_arg, p); | | | 175 | | | | | 176 | | for (n = 0; n < SIGNAL_MAX_ARGUMENTS && n < n_args && rec->args[n] != NULL; ++n) {
| | | 177 | | SV *arg = args[n]; | | | 178 | | | | | 179 | | if (!SvOK(arg)) {
| | | 180 | | continue; | | | 181 | | } | | | 182 | | | | | 183 | | if (strcmp(rec->args[n], "intptr") == 0) { | | | 184 | | SV *t = SvRV(arg);
| | | 185 | | SvIOK_only(t);
| | | 186 | | SvIV_set(t, saved_args[n].v_int);
| | | 187 | | } else if (strncmp(rec->args[n], "gslist_", 7) == 0) { | | saved_args is uninitialized | 188 | | g_slist_free(saved_args[n].v_gslist); | | | 189 | | } else if (strncmp(rec->args[n], "glistptr_", 9) == 0) { | | | 190 | | int is_iobject, is_str; | | | 191 | | AV *av; | | | 192 | | GList *gl, *tmp; | | | 193 | | | | | 194 | | is_iobject = strcmp(rec->args[n]+9, "iobject") == 0; | | | 195 | | is_str = strcmp(rec->args[n]+9, "char*") == 0; | | | 196 | | | | | 197 | | av = (AV *)SvRV(arg);
| | | 198 | | av_clear(av);
| | | 199 | | | | | 200 | | gl = saved_args[n].v_glist; | | | 201 | | for (tmp = gl; tmp != NULL; tmp = tmp->next) {
| | | 202 | | av_push(av,
| | | 203 | | is_iobject ? iobject_bless((SERVER_REC *)tmp->data) : | | | 204 | | is_str ? new_pv(tmp->data) : | | | 205 | | (rec->args[n]+9, tmp->data) | | | 206 | | ); | | | 207 | | } | | | 208 | | | | | 209 | | if (is_str) { | | | 210 | | g_list_foreach(gl, (GFunc)g_free, NULL);
| | | 211 | | } | | | 212 | | g_list_free(gl); |
|