static DWORD WINAPI spinoff(HANDLE in, HANDLE out, char *args, char *cmd, Envy *e) { char args2[8192], path[MAX_PATH], *s, *eb; STARTUPINFO si; PROCESS_INFORMATION pi; Symtab *sym; /* set up the full path of the shell */ sym = symlook("MKSH", S_VAR, 0); if(sym) { strncpy(path, ((Word*)(sym->value))->s, sizeof(path)); path[MAX_PATH-1] = 0; } else { sym = symlook("ROOT", S_VAR, 0); if(sym) rootdir = ((Word*)(sym->value))->s; snprint(path, sizeof(path), "%s\\%s", rootdir, shell); } /* convert to backslash notation */ for(s = strchr(path,'/'); s; s = strchr(s+1, '/')) *s = '\\'; s = args2; s += snprint(args2, sizeof(args2)-1, "%s", path); if(shflags) s += snprint(s, args2+sizeof(args2)-s-1, " %s", shflags); if(args) s += snprint(s, args2+sizeof(args2)-s-1, " %s", args); if(cmd) s += snprint(s, args2+sizeof(args2)-s-1, " \"%s\"", cmd); memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES; si.wShowWindow = SW_SHOW; if (e) eb = exportenv(e); else eb = 0; si.hStdInput = duphandle(in); si.hStdOutput = duphandle(out); si.hStdError = duphandle(GetStdHandle(STD_ERROR_HANDLE)); if(CreateProcess(path, args2, 0, 0, 1, 0, eb, 0, &si, &pi) == FALSE) { perror("can't find shell"); Exit(); } free(eb); CloseHandle(si.hStdInput); CloseHandle(si.hStdOutput); CloseHandle(si.hStdError); childadd(pi.hProcess, pi.dwProcessId); return pi.dwProcessId; }
static int push_promise(struct SessionHandle *data, struct connectdata *conn, const nghttp2_push_promise *frame) { int rv; DEBUGF(infof(data, "PUSH_PROMISE received, stream %u!\n", frame->promised_stream_id)); if(data->multi->push_cb) { struct HTTP *stream; struct curl_pushheaders heads; CURLMcode rc; struct http_conn *httpc; size_t i; /* clone the parent */ CURL *newhandle = duphandle(data); if(!newhandle) { infof(data, "failed to duplicate handle\n"); rv = 1; /* FAIL HARD */ goto fail; } heads.data = data; heads.frame = frame; /* ask the application */ DEBUGF(infof(data, "Got PUSH_PROMISE, ask application!\n")); stream = data->req.protop; if(!stream) { failf(data, "Internal NULL stream!\n"); rv = 1; goto fail; } rv = data->multi->push_cb(data, newhandle, stream->push_headers_used, &heads, data->multi->push_userp); /* free the headers again */ for(i=0; i<stream->push_headers_used; i++) free(stream->push_headers[i]); free(stream->push_headers); stream->push_headers = NULL; if(rv) { /* denied, kill off the new handle again */ (void)Curl_close(newhandle); goto fail; } /* approved, add to the multi handle and immediately switch to PERFORM state with the given connection !*/ rc = Curl_multi_add_perform(data->multi, newhandle, conn); if(rc) { infof(data, "failed to add handle to multi\n"); Curl_close(newhandle); rv = 1; goto fail; } httpc = &conn->proto.httpc; nghttp2_session_set_stream_user_data(httpc->h2, frame->promised_stream_id, newhandle); } else { DEBUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n")); rv = 1; } fail: return rv; }