+ goto error;
+ }
+
+ /* Set number of tracker_id and free command header */
+ nr_ids = cmd_header->nb_tracker_id;
+ if (nr_ids > INT_MAX) {
+ ret = -LTTNG_ERR_OVERFLOW;
+ goto error;
+ }
+ free(cmd_header);
+ cmd_header = NULL;
+
+ ids = zmalloc(sizeof(*ids) * nr_ids);
+ if (!ids) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto error;
+ }
+
+ p = cmd_payload;
+ for (i = 0; i < nr_ids; i++) {
+ struct lttcomm_tracker_id_header *tracker_id;
+ struct lttng_tracker_id *id;
+
+ tracker_id = (struct lttcomm_tracker_id_header *) p;
+ p += sizeof(struct lttcomm_tracker_id_header);
+ id = &ids[i];
+
+ id->type = tracker_id->type;
+ switch (tracker_id->type) {
+ case LTTNG_ID_ALL:
+ break;
+ case LTTNG_ID_VALUE:
+ id->value = tracker_id->u.value;
+ break;
+ case LTTNG_ID_STRING:
+ id->string = strdup(p);
+ if (!id->string) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto error;
+ }
+ p += tracker_id->u.var_data_len;
+ break;
+ default:
+ goto error;
+ }
+ }
+ free(cmd_payload);
+ *_ids = ids;
+ *_nr_ids = nr_ids;
+ return 0;
+
+error:
+ if (ids) {
+ for (i = 0; i < nr_ids; i++) {
+ free(ids[i].string);
+ }
+ free(ids);
+ }
+ free(cmd_payload);
+ free(cmd_header);
+ return ret;
+}
+
+/*
+ * List PIDs in the tracker.
+ *
+ * enabled is set to whether the PID tracker is enabled.
+ * pids is set to an allocated array of PIDs currently tracked. On
+ * success, pids must be freed by the caller.
+ * nr_pids is set to the number of entries contained by the pids array.
+ *
+ * Returns 0 on success, else a negative LTTng error code.
+ */
+int lttng_list_tracker_pids(struct lttng_handle *handle,
+ int *_enabled, int32_t **_pids, size_t *_nr_pids)
+{
+ struct lttng_tracker_id *ids = NULL;
+ size_t nr_ids = 0;
+ int *pids = NULL;
+ int ret = 0, i;
+
+ ret = lttng_list_tracker_ids(handle, LTTNG_TRACKER_PID,
+ &ids, &nr_ids);
+ if (ret < 0)