void script_process(char* script) { // Split script in independent pipelines char* array[10]; int numPipelines = gettokens(script, array, 10, ";"); // run script commands int i; for(i = 0; i < numPipelines; ++i) { // expand environment variables and substitute command line char pointer // with the one with expanded environment variables (if necesary) // char* expanded = expand_envVars(array[i]); // if(expanded) array[i] = expanded; array[i] = environment_expand(array[i]); // move commands to background (if necesary) background(array[i]); // Exec `cd` (it's a built-in, but must change shell environment itself, // so we check and exec for it directly here) if(builtin_cd(array[i])) { free(array[i]); continue; } // Set environment variable if(environment_set(array[i])) { free(array[i]); continue; } // run foreground command pipeline_process(array[i]); // free line created by environment variables expansion free(array[i]); } }
int background(char* line) // Check and exec on background all the commands ended with '&' on the command // line and return the last, foreground command { // Split pipeline in independent commands char* array[10]; int numCommands = gettokens(line, array, 10, "&"); // run script commands int i; for(i = 0; i < numCommands-1; ++i) { switch(fork()) { case -1: return -1; case 0: // child { // redirect stdin to /dev/null redirect_stdin("/dev/null"); // process pipeline pipeline_process(array[i]); exitError(); } // parent loop to exec in background the next command (if any) } } // collapse line to let only the last (not background) command on it int len = strlen(array[numCommands-1]); memmove(line, array[numCommands-1], len); *(line+len) = '\0'; return 0; }
static void ind_ovs_handle_packet_miss(struct ind_ovs_upcall_thread *thread, struct ind_ovs_port *port, struct nl_msg *msg, struct nlattr **attrs) { struct nlmsghdr *nlh = nlmsg_hdr(msg); struct genlmsghdr *gnlh = (void *)(nlh + 1); struct nlattr *key = attrs[OVS_PACKET_ATTR_KEY]; struct nlattr *packet = attrs[OVS_PACKET_ATTR_PACKET]; assert(key && packet); struct ind_ovs_parsed_key pkey; ind_ovs_parse_key(key, &pkey); struct pipeline_result *result = &thread->result; pipeline_result_reset(result); indigo_error_t err = pipeline_process(&pkey, result); if (err < 0) { return; } struct ind_ovs_flow_stats **stats_ptrs = xbuf_data(&result->stats); int num_stats_ptrs = xbuf_length(&result->stats) / sizeof(void *); int i; for (i = 0; i < num_stats_ptrs; i++) { struct ind_ovs_flow_stats *stats = stats_ptrs[i]; __sync_fetch_and_add(&stats->packets, 1); __sync_fetch_and_add(&stats->bytes, nla_len(packet)); } /* Check for a single controller action */ { uint32_t actions_length = xbuf_length(&result->actions); struct nlattr *first_action = xbuf_data(&result->actions); if (actions_length >= NLA_HDRLEN && actions_length == NLA_ALIGN(first_action->nla_len) && first_action->nla_type == IND_OVS_ACTION_CONTROLLER) { /* * The only action is sending the packet to the controller. * It's wasteful to send it all the way through the kernel * to be received as another upcall, so request a pktin * directly here. */ uint64_t userdata = *XBUF_PAYLOAD(first_action, uint64_t); ind_ovs_upcall_request_pktin(pkey.in_port, port, packet, key, IVS_PKTIN_REASON(userdata), IVS_PKTIN_METADATA(userdata)); return; } } /* Reuse the incoming message for the packet execute */ gnlh->cmd = OVS_PACKET_CMD_EXECUTE; struct nlattr *actions = nla_nest_start(msg, OVS_PACKET_ATTR_ACTIONS); ind_ovs_translate_actions(&pkey, &result->actions, msg); ind_ovs_nla_nest_end(msg, actions); /* Don't send the packet back out if it would be dropped. */ if (nla_len(actions) > 0) { nlh->nlmsg_pid = 0; nlh->nlmsg_seq = 0; nlh->nlmsg_flags = NLM_F_REQUEST; struct iovec *iovec = &thread->tx_queue[thread->tx_queue_len++]; iovec->iov_base = nlh; iovec->iov_len = nlh->nlmsg_len; if (thread->log_upcalls) { LOG_VERBOSE("Sending upcall reply:"); ind_ovs_dump_msg(nlh); } } /* See the comment for ind_ovs_upcall_seen_key. */ if (!ind_ovs_disable_kflows && ind_ovs_upcall_seen_key(thread, key)) { /* Create a kflow with the given key and actions. */ ind_ovs_bh_request_kflow(key); } }