| 274 | |
| 275 | |
| 276 | inline static int w_async_exec(struct sip_msg* msg, async_ctx *ctx, |
| 277 | str* cmd, str* in, pv_spec_t* out, pv_spec_t* err, pv_spec_t* avp_env) |
| 278 | { |
| 279 | struct hf_wrapper *hf=0; |
| 280 | environment_t* backup_env=0; |
| 281 | exec_async_param *param; |
| 282 | int ret, fd; |
| 283 | |
| 284 | if (msg == 0 || cmd == 0) |
| 285 | return -1; |
| 286 | |
| 287 | if (avp_env != NULL) { |
| 288 | if ((hf=get_avp_values_list(msg, &(avp_env->pvp))) == 0) |
| 289 | return -1; |
| 290 | backup_env=replace_env(hf); |
| 291 | if (!backup_env) { |
| 292 | LM_ERR("replace env failed\n"); |
| 293 | release_vars(hf); |
| 294 | release_hf_struct(hf); |
| 295 | return -1; |
| 296 | } |
| 297 | release_hf_struct(hf); |
| 298 | } |
| 299 | |
| 300 | /* better do this alloc now (before starting the async) to avoid |
| 301 | * the unplesant situation of having the async started and have a |
| 302 | * memory failure -> tricky to recover */ |
| 303 | param = (exec_async_param*)shm_malloc(sizeof(exec_async_param)); |
| 304 | if(param==NULL) { |
| 305 | LM_ERR("failed to allocate new async param\n"); |
| 306 | if (backup_env) unset_env(backup_env); |
| 307 | return -1; |
| 308 | } |
| 309 | |
| 310 | ret = start_async_exec(msg, cmd, in, out, &fd); |
| 311 | |
| 312 | if (backup_env) |
| 313 | unset_env(backup_env); |
| 314 | |
| 315 | /* populate resume point (if async started) */ |
| 316 | if (ret==1) { |
| 317 | param->outvar = out; |
| 318 | /* that ^^^^ is save as "out" is a in private mem, but in all |
| 319 | * processes (set before forking) */ |
| 320 | param->buf = NULL; |
| 321 | ctx->resume_param = (void*)param; |
| 322 | ASYNC_SET_RESUME_F(ctx, resume_async_exec); |
| 323 | async_status = fd; |
| 324 | } else if (ret==2) { |
| 325 | /* no IO done, but success */ |
| 326 | shm_free(param); |
| 327 | ctx->resume_param = NULL; |
| 328 | ASYNC_CLEAR_RESUME_F(ctx); |
| 329 | async_status = ASYNC_NO_IO; |
| 330 | } else { |
| 331 | /* error */ |
| 332 | shm_free(param); |
| 333 | ctx->resume_param = NULL; |
nothing calls this directly
no test coverage detected