int bproc_nodelist_(struct bproc_node_set_t *ns, int fd) { int r; struct stat statbuf; struct pollfd pfd; pfd.fd = fd; pfd.events = POLLIN; /* There's some wackiness possible here. The machine state might change while we're reading the status file. To guard against this, we do a read and then check to see if a change has occurred. This might be a bit paranoid. */ bproc_nodeset_init(ns, 0); /* make this safe to use grow */ again: if (fstat(fd, &statbuf)) return -1; if (bproc_nodeset_grow(ns, statbuf.st_size / sizeof(*ns->node))) { bproc_nodeset_free(ns); /* we may have allocated stuff earlier */ return -1; } lseek(fd, 0, SEEK_SET); r = read(fd, ns->node, statbuf.st_size); if (r == -1) { bproc_nodeset_free(ns); return -1; } if (r != statbuf.st_size) goto again; /* explicitly check for changes */ poll(&pfd, 1, 0); if (pfd.revents & POLLIN) goto again; ns->size = statbuf.st_size / sizeof(*ns->node); return ns->size; }
int bproc_nodefilter(struct bproc_node_set_t *out, struct bproc_node_set_t *in, const char *str) { int i, r; int max_id; struct bproc_node_info_t **id_map; bproc_nodeset_init(out, 0); /* First build an ID map - this will be valuable for node ranges, etc. */ max_id = -1; for (i = 0; i < in->size; i++) { if (in->node[i].node > max_id) max_id = in->node[i].node; } if (max_id == -1) /* no nodes, just bail out now. */ return 0; id_map = malloc(sizeof(*id_map) * (max_id + 1)); if (!id_map) { fprintf(stderr, "out of memory.\n"); errno = ENOMEM; return -1; } memset(id_map, 0, sizeof(*id_map) * (max_id + 1)); for (i = 0; i < in->size; i++) id_map[in->node[i].node] = &in->node[i]; while (*str) { while (*str == ',') str++; r = filter_chunk(str, id_map, max_id, out); if (r <= 0) { bproc_nodeset_free(out); free(id_map); return -1; } str += r; } free(id_map); return 0; }