Ejemplo n.º 1
0
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]);
	}
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
Archivo: upcall.c Proyecto: mchalla/ivs
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);
    }
}