Пример #1
0
static int collect_children(struct pstree_item *item)
{
	pid_t *ch;
	int ret, i, nr_children, nr_inprogress;

	ret = parse_children(item->pid.real, &ch, &nr_children);
	if (ret < 0)
		return ret;

	nr_inprogress = 0;
	for (i = 0; i < nr_children; i++) {
		struct pstree_item *c;
		pid_t pid = ch[i];

		/* Is it already frozen? */
		if (child_collected(item, pid))
			continue;

		nr_inprogress++;

		pr_info("Seized task %d, state %d\n", pid, ret);

		c = alloc_pstree_item();
		if (c == NULL) {
			ret = -1;
			goto free;
		}

		if (!opts.freeze_cgroup)
			/* fails when meets a zombie */
			seize_catch_task(pid);

		ret = seize_wait_task(pid, item->pid.real, &dmpi(c)->pi_creds);
		if (ret < 0) {
			/*
			 * Here is a race window between parse_children() and seize(),
			 * so the task could die for these time.
			 * Don't worry, will try again on the next attempt. The number
			 * of attempts is restricted, so it will exit if something
			 * really wrong.
			 */
			ret = 0;
			xfree(c);
			continue;
		}

		c->pid.real = pid;
		c->parent = item;
		c->state = ret;
		list_add_tail(&c->sibling, &item->children);

		/* Here is a recursive call (Depth-first search) */
		ret = collect_task(c);
		if (ret < 0)
			goto free;
	}
free:
	xfree(ch);
	return ret < 0 ? ret : nr_inprogress;
}
Пример #2
0
struct cParseNode* parse_rule(unsigned int rule, struct Grammar* grammar, struct TokenStream* tokens, struct Error* error) {
    struct cParseNode* node = _new_parsenode(rule);
    struct cParseNode* tmp;
    int i;
    LOG("parsing rule #%d %s (token at %d)\n", rule, grammar->rules.rules[rule].name, tokens->at);
    int at = tokens->at;
    INDENT();
    for (i=0; i < grammar->rules.rules[rule].num; i++) {
        tokens->at = at;
        tmp = parse_children(rule, &(grammar->rules.rules[rule].options[i]), grammar, tokens, error);
        if (tmp != NULL) {
            LOG("CHild success! %d\n", i);
            if (tmp != UNINITIALIZED) {
                node->child = tmp;
            }
            DEDENT();
            return node;
        }
    }
    LOG("failed rule %d\n", rule);
    DEDENT();
    tokens->at = at;
    return NULL;
}
Пример #3
0
struct cParseNode* check_special(unsigned int rule, struct RuleSpecial special, struct cParseNode* current, struct Grammar* grammar, struct TokenStream* tokens, struct Error* error) {
    struct cParseNode* tmp;
    int at, i;
    LOG("special\n");
    INDENT();
    if (special.type == STAR) {
        LOG("star!\n");
        while (tokens->at < tokens->num) {
            at = tokens->at;
            tmp = parse_children(rule, special.option, grammar, tokens, error);
            if (tmp == NULL) {
                tokens->at = at;
                break;
            }
            current = append_nodes(current, tmp);
            if (at == tokens->at) {
                break;
            }
        }
        LOG("awesome star\n");
        DEDENT();
        return current;
    } else if (special.type == PLUS) {
        LOG("plus!\n");
        at = tokens->at;
        tmp = parse_children(rule, special.option, grammar, tokens, error);
        if (tmp == NULL) {
            tokens->at = at;
            LOG("failed plus\n");
            DEDENT();
            return NULL;
        }
        current = append_nodes(current, tmp);
        if (at == tokens->at) {
            return current;
        }
        while (tokens->at < tokens->num) {
            at = tokens->at;
            tmp = parse_children(rule, special.option, grammar, tokens, error);
            if (tmp == NULL) {
                tokens->at = at;
                break;
            }
            current = append_nodes(current, tmp);
            if (at == tokens->at) {
                break;
            }
        }
        LOG("good plus\n");
        DEDENT();
        return current;
    } else if (special.type == OR) {
        LOG("or!\n");
        at = tokens->at;
        for (i=0;i<special.option->num;i++) {
            // each of the child items with be of the special STRAIGHT option
            // type -> allowing the OR special to have a list of lists
            tmp = parse_children(rule, special.option->items[i].value.special.option, grammar, tokens, error);
            if (tmp != NULL) {
                LOG("got or...\n");
                current = append_nodes(current, tmp);
                DEDENT();
                return current;
            }
        }
        LOG("fail or\n");
        DEDENT();
        return NULL;
    } else if (special.type == QUESTION) {
        LOG("?maybe\n");
        at = tokens->at;
        tmp = parse_children(rule, special.option, grammar, tokens, error);
        LOG("done maybe children\n");
        if (tmp == NULL) {
            LOG("not taking it\n");
            tokens->at = at;
            DEDENT();
            return current;
        }
        current = append_nodes(current, tmp);
        LOG("got maybe\n");
        DEDENT();
        return current;
    } else if (special.type == NOIGNORE) {
        LOG("no ignore (initial %d)\n", grammar->rules.rules[rule].dont_ignore);
        int before_ignore = grammar->rules.rules[rule].dont_ignore;
        at = tokens->at;
        grammar->rules.rules[rule].dont_ignore = 1;
        tmp = parse_children(rule, special.option, grammar, tokens, error);
        grammar->rules.rules[rule].dont_ignore = before_ignore;
        if (tmp == NULL) {
            tokens->at = at;
            LOG("failed ignore\n");
            DEDENT();
            return NULL;
        }
        current = append_nodes(current, tmp);
        LOG("ignore success! back to %d %d", grammar->rules.rules[rule].dont_ignore, before_ignore);
        DEDENT();
        return current;
    } else if (special.type == NOT) {
        LOG("NOT\n");
        at = tokens->at;
        tmp = parse_children(rule, special.option, grammar, tokens, error);
        if (tmp == NULL) {
            if (tokens->at < tokens->num) {
                tmp = _new_parsenode(rule);
                tmp->token = &tokens->tokens[tokens->at];
                tmp->type = NTOKEN;
                tokens->at += 1;
                current = append_nodes(current, tmp);
                LOG("awesome. eating token\n");
            } else {
                LOG("not enough tokens to eat\n");
                at = tokens->at;
                return NULL;
            }
            DEDENT();
            return current;
        }
        LOG("nope, it passed\n");
        tokens->at = at;
        DEDENT();
        return NULL;
    } else {
        LOG("unknown special type: %s\n", special.type);
        DEDENT();
        return NULL;
    }
    LOG("umm shouldnt happen");
    DEDENT();
    return NULL;
}
Пример #4
0
static pj_json_elem* parse_elem_throw(struct parse_state *st,
                                      pj_json_elem *elem)
{
    pj_str_t name = {NULL, 0}, value = {NULL, 0};
    pj_str_t token;

    if (!elem)
	elem = pj_pool_alloc(st->pool, sizeof(*elem));

    /* Parse name */
    if (*st->scanner.curptr == '"') {
	pj_scan_get_char(&st->scanner);
	pj_scan_get_until_ch(&st->scanner, '"', &token);
	pj_scan_get_char(&st->scanner);

	if (*st->scanner.curptr == ':') {
	    pj_scan_get_char(&st->scanner);
	    name = token;
	} else {
	    value = token;
	}
    }

    if (value.slen) {
	/* Element with string value and no name */
	pj_json_elem_string(elem, &name, &value);
	return elem;
    }

    /* Parse value */
    if (pj_cis_match(&st->float_spec, *st->scanner.curptr) ||
	*st->scanner.curptr == '-')
    {
	float val;
	pj_bool_t neg = PJ_FALSE;

	if (*st->scanner.curptr == '-') {
	    pj_scan_get_char(&st->scanner);
	    neg = PJ_TRUE;
	}

	pj_scan_get(&st->scanner, &st->float_spec, &token);
	val = pj_strtof(&token);
	if (neg) val = -val;

	pj_json_elem_number(elem, &name, val);

    } else if (*st->scanner.curptr == '"') {
	unsigned err;
	char *start = st->scanner.curptr;

	err = parse_quoted_string(st, &token);
	if (err) {
	    st->scanner.curptr = start + err;
	    return NULL;
	}

	pj_json_elem_string(elem, &name, &token);

    } else if (pj_isalpha(*st->scanner.curptr)) {

	if (pj_scan_strcmp(&st->scanner, "false", 5)==0) {
	    pj_json_elem_bool(elem, &name, PJ_FALSE);
	    pj_scan_advance_n(&st->scanner, 5, PJ_TRUE);
	} else if (pj_scan_strcmp(&st->scanner, "true", 4)==0) {
	    pj_json_elem_bool(elem, &name, PJ_TRUE);
	    pj_scan_advance_n(&st->scanner, 4, PJ_TRUE);
	} else if (pj_scan_strcmp(&st->scanner, "null", 4)==0) {
	    pj_json_elem_null(elem, &name);
	    pj_scan_advance_n(&st->scanner, 4, PJ_TRUE);
	} else {
	    return NULL;
	}

    } else if (*st->scanner.curptr == '[') {
	pj_json_elem_array(elem, &name);
	if (parse_children(st, elem) != PJ_SUCCESS)
	    return NULL;

    } else if (*st->scanner.curptr == '{') {
	pj_json_elem_obj(elem, &name);
	if (parse_children(st, elem) != PJ_SUCCESS)
	    return NULL;

    } else {
	return NULL;
    }

    return elem;
}