Lines Matching refs:lsp

40 	struct lws_spawn_piped *lsp = lws_container_of(sul,
45 lws_spawn_piped_kill_child_process(lsp);
51 struct lws_spawn_piped *lsp = lws_container_of(sul,
55 __func__, lsp->reap_retry_budget);
56 if (!lws_spawn_reap(lsp) && !lsp->pipes_alive) {
57 if (--lsp->reap_retry_budget) {
58 lws_sul_schedule(lsp->info.vh->context, lsp->info.tsi,
59 &lsp->sul_reap, lws_spawn_sul_reap,
62 lwsl_err("%s: Unable to reap lsp %p, killing\n",
63 __func__, lsp);
64 lsp->reap_retry_budget = 20;
65 lws_spawn_piped_kill_child_process(lsp);
116 struct lws_spawn_piped *lsp = *_lsp;
119 if (!lsp)
122 lws_dll2_remove(&lsp->dll);
124 lws_sul_cancel(&lsp->sul);
125 lws_sul_cancel(&lsp->sul_reap);
129 if (lsp->pipe_fds[n][!!(n == 0)] == 0)
132 if (lsp->pipe_fds[n][!!(n == 0)] >= 0) {
133 close(lsp->pipe_fds[n][!!(n == 0)]);
134 lsp->pipe_fds[n][!!(n == 0)] = LWS_SOCK_INVALID;
137 if (lsp->stdwsi[n]) {
138 lws_set_timeout(lsp->stdwsi[n], 1, LWS_TO_KILL_ASYNC);
139 lsp->stdwsi[n] = NULL;
147 lws_spawn_reap(struct lws_spawn_piped *lsp)
150 void *opaque = lsp->info.opaque;
151 lsp_cb_t cb = lsp->info.reap_cb;
160 if (lsp->child_pid < 1)
165 memset(&lsp->si, 0, sizeof(lsp->si));
167 n = wait4(lsp->child_pid, &status, WNOHANG, &rusa);
170 lsp->si.si_code = WIFEXITED(status);
172 n = waitid(P_PID, (id_t)lsp->child_pid, &lsp->si, WEXITED | WNOHANG | WNOWAIT);
175 lwsl_info("%s: child %d still running\n", __func__, lsp->child_pid);
179 if (!lsp->si.si_code)
184 if (!lsp->reaped) {
186 lsp->reaped = lws_now_usecs();
193 lws_sul_schedule(lsp->info.vh->context, lsp->info.tsi,
194 &lsp->sul, lws_spawn_timeout,
205 if (!lsp->ungraceful && lsp->pipes_alive) {
207 lsp->pipes_alive);
213 lws_sul_cancel(&lsp->sul);
224 lsp->accounting[0] = (lws_usec_t)((uint64_t)tms.tms_cstime * 1000000) / hz;
225 lsp->accounting[1] = (lws_usec_t)((uint64_t)tms.tms_cutime * 1000000) / hz;
226 lsp->accounting[2] = (lws_usec_t)((uint64_t)tms.tms_stime * 1000000) / hz;
227 lsp->accounting[3] = (lws_usec_t)((uint64_t)tms.tms_utime * 1000000) / hz;
230 temp = *lsp;
232 n = wait4(lsp->child_pid, &status, WNOHANG, &rusa);
235 lsp->si.si_code = WIFEXITED(status);
236 if (lsp->si.si_code == CLD_EXITED)
240 n = waitid(P_PID, (id_t)lsp->child_pid, &temp.si, WEXITED | WNOHANG);
246 lsp->child_pid = -1;
248 /* destroy the lsp itself first (it's freed and plsp set NULL */
250 if (lsp->info.plsp)
251 lws_spawn_piped_destroy(lsp->info.plsp);
264 lws_spawn_piped_kill_child_process(struct lws_spawn_piped *lsp)
268 if (lsp->child_pid <= 0)
271 lsp->ungraceful = 1; /* don't wait for flushing, just kill it */
273 if (lws_spawn_reap(lsp))
274 /* that may have invalidated lsp */
278 n = kill(-lsp->child_pid, SIGTERM);
280 lsp->child_pid, n, errno);
288 n = kill(lsp->child_pid, SIGTERM);
290 n = kill(lsp->child_pid, SIGPIPE);
292 n = kill(lsp->child_pid, SIGKILL);
297 lsp->child_pid, errno);
306 n = waitpid(-lsp->child_pid, &status, WNOHANG);
310 n = waitpid(lsp->child_pid, &status, WNOHANG);
316 lws_spawn_reap(lsp);
317 /* that may have invalidated lsp */
332 struct lws_spawn_piped *lsp;
345 lsp = lws_zalloc(sizeof(*lsp), __func__);
346 if (!lsp)
350 lsp->info = *i;
351 lsp->reap_retry_budget = 20;
358 lsp->pipe_fds[n][0] = -1;
359 lsp->pipe_fds[n][1] = -1;
365 if (pipe(lsp->pipe_fds[n]) == -1)
367 lws_plat_apply_FD_CLOEXEC(lsp->pipe_fds[n][n == 0]);
378 lsp->stdwsi[n] = lws_create_stdwsi(i->vh->context, i->tsi,
380 if (!lsp->stdwsi[n]) {
381 lwsl_err("%s: unable to create lsp stdwsi\n", __func__);
386 &lsp->stdwsi[n]->lc, "nspawn-stdwsi-%d", n);
388 lsp->stdwsi[n]->lsp_channel = (uint8_t)n;
389 lws_vhost_bind_wsi(i->vh, lsp->stdwsi[n]);
390 lsp->stdwsi[n]->a.protocol = pcol;
391 lsp->stdwsi[n]->a.opaque_user_data = i->opaque;
393 lwsl_debug("%s: lsp stdwsi %p: pipe idx %d -> fd %d / %d\n", __func__,
394 lsp->stdwsi[n], n, lsp->pipe_fds[n][n == 0],
395 lsp->pipe_fds[n][n != 0]);
399 lsp->stdwsi[n]->desc.sockfd = lsp->pipe_fds[n][n == 0];
400 if (fcntl(lsp->pipe_fds[n][n == 0], F_SETFL, O_NONBLOCK) < 0) {
421 if (context->event_loop_ops->sock_accept(lsp->stdwsi[n]))
424 if (__insert_wsi_socket_into_fds(context, lsp->stdwsi[n]))
427 lsp->stdwsi[n]->parent = i->opt_parent;
428 lsp->stdwsi[n]->sibling_list = i->opt_parent->child_list;
429 i->opt_parent->child_list = lsp->stdwsi[n];
433 if (lws_change_pollfd(lsp->stdwsi[LWS_STDIN], LWS_POLLIN, LWS_POLLOUT))
435 if (lws_change_pollfd(lsp->stdwsi[LWS_STDOUT], LWS_POLLOUT, LWS_POLLIN))
437 if (lws_change_pollfd(lsp->stdwsi[LWS_STDERR], LWS_POLLOUT, LWS_POLLIN))
441 lsp->stdwsi[LWS_STDIN]->desc.sockfd,
442 lsp->stdwsi[LWS_STDOUT]->desc.sockfd,
443 lsp->stdwsi[LWS_STDERR]->desc.sockfd);
447 lsp->child_pid = fork();
449 lsp->child_pid = vfork();
451 if (lsp->child_pid < 0) {
457 if (!lsp->child_pid)
461 if (lsp->info.disable_ctrlc)
470 if (lsp->child_pid) {
479 close(lsp->pipe_fds[n][n != 0]);
481 lsp->pipes_alive = 3;
482 lsp->created = lws_now_usecs();
484 lwsl_info("%s: lsp %p spawned PID %d\n", __func__, lsp,
485 lsp->child_pid);
487 lws_sul_schedule(context, i->tsi, &lsp->sul, lws_spawn_timeout,
492 lws_dll2_add_head(&lsp->dll, i->owner);
495 lws_sul_schedule(context, i->tsi, &lsp->sul,
498 return lsp;
529 if (dup2(lsp->pipe_fds[m][m != 0], m) < 0) {
541 close(lsp->pipe_fds[m][m != 0]);
571 __remove_wsi_socket_from_fds(lsp->stdwsi[n]);
574 if (lsp->stdwsi[n])
575 __lws_free_wsi(lsp->stdwsi[n]);
579 if (lsp->pipe_fds[n][0] >= 0)
580 close(lsp->pipe_fds[n][0]);
581 if (lsp->pipe_fds[n][1] >= 0)
582 close(lsp->pipe_fds[n][1]);
585 lws_free(lsp);
593 lws_spawn_stdwsi_closed(struct lws_spawn_piped *lsp, struct lws *wsi)
597 assert(lsp);
598 lsp->pipes_alive--;
599 lwsl_debug("%s: pipes alive %d\n", __func__, lsp->pipes_alive);
600 if (!lsp->pipes_alive)
601 lws_sul_schedule(lsp->info.vh->context, lsp->info.tsi,
602 &lsp->sul_reap, lws_spawn_sul_reap, 1);
605 if (lsp->stdwsi[n] == wsi)
606 lsp->stdwsi[n] = NULL;