Make libustctl list only online pids v3
[ust.git] / libustctl / libustctl.c
CommitLineData
ab33e65c 1/* Copyright (C) 2009 Pierre-Marc Fournier, Philippe Proulx-Barrette
8b26d56b 2 * Copyright (C) 2011 Ericsson AB
ab33e65c
PP
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
ef290fca 19#define _GNU_SOURCE
ab33e65c
PP
20#include <stdio.h>
21#include <unistd.h>
22#include <getopt.h>
23#include <stdlib.h>
24#include <fcntl.h>
25#include <string.h>
26#include <dirent.h>
ab33e65c
PP
27
28#include "ustcomm.h"
2298f329 29#include "ust/ustctl.h"
2a79ceeb 30#include "usterr.h"
ab33e65c 31
8b26d56b 32static int do_cmd(int sock,
72098143
NC
33 const struct ustcomm_header *req_header,
34 const char *req_data,
35 struct ustcomm_header *res_header,
36 char **res_data)
37{
8b26d56b 38 int result, saved_errno = 0;
72098143
NC
39 char *recv_buf;
40
72098143
NC
41 recv_buf = zmalloc(USTCOMM_BUFFER_SIZE);
42 if (!recv_buf) {
43 saved_errno = ENOMEM;
8b26d56b 44 goto out;
72098143
NC
45 }
46
8b26d56b 47 result = ustcomm_req(sock, req_header, req_data, res_header, recv_buf);
72098143
NC
48 if (result > 0) {
49 saved_errno = -res_header->result;
50 if (res_header->size == 0 || saved_errno > 0) {
51 free(recv_buf);
52 } else {
53 if (res_data) {
54 *res_data = recv_buf;
55 } else {
56 free(recv_buf);
57 }
58 }
59 } else {
60 ERR("ustcomm req failed");
61 if (result == 0) {
62 saved_errno = ENOTCONN;
63 } else {
64 saved_errno = -result;
65 }
66 free(recv_buf);
67 }
68
8b26d56b 69out:
72098143 70 errno = saved_errno;
72098143
NC
71 if (errno) {
72 return -1;
73 }
74
75 return 0;
76}
77
8b26d56b
NC
78int ustctl_connect_pid(pid_t pid)
79{
80 int sock;
81
82 if (ustcomm_connect_app(pid, &sock)) {
83 ERR("could not connect to PID %u", (unsigned int) pid);
84 errno = ENOTCONN;
85 return -1;
86 }
87
88 return sock;
89}
90
8b6984b8
NC
91static int realloc_pid_list(pid_t **pid_list, unsigned int *pid_list_size)
92{
93 pid_t *new_pid_list;
94 unsigned int new_pid_list_size = 2 * *pid_list_size;
95
96 new_pid_list = realloc(*pid_list,
97 new_pid_list_size * sizeof(pid_t));
98 if (!*new_pid_list) {
99 return -1;
100 }
101
102 *pid_list = new_pid_list;
103 *pid_list_size = new_pid_list_size;
104
105 return 0;
106}
107
108static int get_pids_in_dir(DIR *dir, pid_t **pid_list,
109 unsigned int *pid_list_index,
dde0eeef 110 unsigned int *pid_list_size)
772030fe 111{
08230db7 112 struct dirent *dirent;
0f79e1ef 113 pid_t read_pid;
ab33e65c 114
772030fe 115 while ((dirent = readdir(dir))) {
ab33e65c 116 if (!strcmp(dirent->d_name, ".") ||
dde0eeef
NC
117 !strcmp(dirent->d_name, "..") ||
118 !strcmp(dirent->d_name, "ust-consumer") ||
119 dirent->d_type == DT_DIR) {
ab33e65c
PP
120
121 continue;
122 }
123
0f79e1ef 124 if (ustcomm_is_socket_live(dirent->d_name, &read_pid)) {
8b6984b8 125
0f79e1ef 126 (*pid_list)[(*pid_list_index)++] = (long) read_pid;
8b6984b8
NC
127
128 if (*pid_list_index == *pid_list_size) {
129 if (realloc_pid_list(pid_list, pid_list_size)) {
130 return -1;
131 }
132 }
ab33e65c
PP
133 }
134 }
135
8b6984b8
NC
136 (*pid_list)[*pid_list_index] = 0; /* Array end */
137
138 return 0;
dde0eeef 139}
ab33e65c 140
1031eea2 141static pid_t *get_pids_non_root(void)
dde0eeef
NC
142{
143 char *dir_name;
144 DIR *dir;
8b6984b8 145 unsigned int pid_list_index = 0, pid_list_size = 1;
dde0eeef
NC
146 pid_t *pid_list = NULL;
147
148 dir_name = ustcomm_user_sock_dir();
149 if (!dir_name) {
ab33e65c
PP
150 return NULL;
151 }
152
dde0eeef
NC
153 dir = opendir(dir_name);
154 if (!dir) {
155 goto free_dir_name;
156 }
157
158 pid_list = malloc(pid_list_size * sizeof(pid_t));
1031eea2
NC
159 if (!pid_list) {
160 goto close_dir;
161 }
dde0eeef 162
8b6984b8
NC
163 if (get_pids_in_dir(dir, &pid_list, &pid_list_index, &pid_list_size)) {
164 /* if any errors are encountered, force freeing of the list */
165 pid_list[0] = 0;
dde0eeef
NC
166 }
167
168close_dir:
ab33e65c 169 closedir(dir);
dde0eeef
NC
170
171free_dir_name:
172 free(dir_name);
173
174 return pid_list;
ab33e65c
PP
175}
176
1031eea2
NC
177static pid_t *get_pids_root(void)
178{
179 char *dir_name;
180 DIR *tmp_dir, *dir;
8b6984b8 181 unsigned int pid_list_index = 0, pid_list_size = 1;
1031eea2
NC
182 pid_t *pid_list = NULL;
183 struct dirent *dirent;
8b6984b8 184 int result;
1031eea2
NC
185
186 tmp_dir = opendir(USER_TMP_DIR);
187 if (!tmp_dir) {
188 return NULL;
189 }
190
191 pid_list = malloc(pid_list_size * sizeof(pid_t));
192 if (!pid_list) {
193 goto close_tmp_dir;
194 }
195
196 while ((dirent = readdir(tmp_dir))) {
197 /* Compare the dir to check for the USER_SOCK_DIR_BASE prefix */
198 if (!strncmp(dirent->d_name, USER_SOCK_DIR_BASE,
199 strlen(USER_SOCK_DIR_BASE))) {
200
8b6984b8
NC
201 if (asprintf(&dir_name, USER_TMP_DIR "/%s",
202 dirent->d_name) < 0) {
1031eea2
NC
203 goto close_tmp_dir;
204 }
205
206 dir = opendir(dir_name);
207
208 free(dir_name);
209
210 if (!dir) {
211 continue;
212 }
213
8b6984b8
NC
214 result = get_pids_in_dir(dir, &pid_list, &pid_list_index,
215 &pid_list_size);
1031eea2
NC
216
217 closedir(dir);
8b6984b8
NC
218
219 if (result) {
220 /*
221 * if any errors are encountered,
222 * force freeing of the list
223 */
224 pid_list[0] = 0;
225 break;
226 }
1031eea2
NC
227 }
228 }
229
230close_tmp_dir:
231 closedir(tmp_dir);
232
233 return pid_list;
234}
235
236pid_t *ustctl_get_online_pids(void)
237{
8b6984b8
NC
238 pid_t *pid_list;
239
1031eea2 240 if (geteuid()) {
8b6984b8 241 pid_list = get_pids_non_root();
1031eea2 242 } else {
8b6984b8
NC
243 pid_list = get_pids_root();
244 }
245
246 if (pid_list && pid_list[0] == 0) {
247 /* No PID at all */
248 free(pid_list);
249 pid_list = NULL;
1031eea2 250 }
8b6984b8
NC
251
252 return pid_list;
1031eea2
NC
253}
254
ab33e65c 255/**
b521931e 256 * Sets ust_marker state (USTCTL_MS_ON or USTCTL_MS_OFF).
ab33e65c
PP
257 *
258 * @param mn Marker name
259 * @param state Marker's new state
260 * @param pid Traced process ID
2298f329 261 * @return 0 if successful, or errors {USTCTL_ERR_GEN, USTCTL_ERR_ARG}
ab33e65c 262 */
b521931e
MD
263int ustctl_set_ust_marker_state(int sock, const char *trace, const char *channel,
264 const char *ust_marker, int state)
ef290fca 265{
72098143 266 struct ustcomm_header req_header, res_header;
b521931e 267 struct ustcomm_ust_marker_info ust_marker_inf;
ef290fca
PMF
268 int result;
269
b521931e
MD
270 result = ustcomm_pack_ust_marker_info(&req_header,
271 &ust_marker_inf,
d89b8191 272 trace,
72098143 273 channel,
b521931e 274 ust_marker);
72098143
NC
275 if (result < 0) {
276 errno = -result;
277 return -1;
08b8805e 278 }
ab33e65c 279
72098143 280 req_header.command = state ? ENABLE_MARKER : DISABLE_MARKER;
ab33e65c 281
b521931e 282 return do_cmd(sock, &req_header, (char *)&ust_marker_inf,
72098143 283 &res_header, NULL);
ab33e65c
PP
284}
285
763f41e5
DS
286/**
287 * Set subbuffer size.
288 *
289 * @param channel_size Channel name and size
290 * @param pid Traced process ID
291 * @return 0 if successful, or error
292 */
8b26d56b
NC
293int ustctl_set_subbuf_size(int sock, const char *trace, const char *channel,
294 unsigned int subbuf_size)
763f41e5 295{
72098143
NC
296 struct ustcomm_header req_header, res_header;
297 struct ustcomm_channel_info ch_inf;
763f41e5
DS
298 int result;
299
72098143
NC
300 result = ustcomm_pack_channel_info(&req_header,
301 &ch_inf,
d89b8191 302 trace,
72098143
NC
303 channel);
304 if (result < 0) {
305 errno = -result;
08b8805e
DG
306 return -1;
307 }
763f41e5 308
72098143
NC
309 req_header.command = SET_SUBBUF_SIZE;
310 ch_inf.subbuf_size = subbuf_size;
763f41e5 311
8b26d56b 312 return do_cmd(sock, &req_header, (char *)&ch_inf,
72098143 313 &res_header, NULL);
763f41e5
DS
314}
315
316/**
317 * Set subbuffer num.
318 *
319 * @param channel_num Channel name and num
320 * @param pid Traced process ID
321 * @return 0 if successful, or error
322 */
8b26d56b
NC
323int ustctl_set_subbuf_num(int sock, const char *trace, const char *channel,
324 unsigned int num)
763f41e5 325{
72098143
NC
326 struct ustcomm_header req_header, res_header;
327 struct ustcomm_channel_info ch_inf;
763f41e5
DS
328 int result;
329
72098143
NC
330 result = ustcomm_pack_channel_info(&req_header,
331 &ch_inf,
d89b8191 332 trace,
72098143
NC
333 channel);
334 if (result < 0) {
335 errno = -result;
08b8805e
DG
336 return -1;
337 }
763f41e5 338
72098143
NC
339 req_header.command = SET_SUBBUF_NUM;
340 ch_inf.subbuf_num = num;
341
8b26d56b 342 return do_cmd(sock, &req_header, (char *)&ch_inf,
72098143 343 &res_header, NULL);
763f41e5 344
763f41e5
DS
345}
346
8b26d56b
NC
347
348static int ustctl_get_subbuf_num_size(int sock, const char *trace, const char *channel,
349 int *num, int *size)
e77b8e8e 350{
72098143
NC
351 struct ustcomm_header req_header, res_header;
352 struct ustcomm_channel_info ch_inf, *ch_inf_res;
e77b8e8e
DS
353 int result;
354
72098143
NC
355
356 result = ustcomm_pack_channel_info(&req_header,
357 &ch_inf,
d89b8191 358 trace,
72098143
NC
359 channel);
360 if (result < 0) {
361 errno = -result;
08b8805e
DG
362 return -1;
363 }
e77b8e8e 364
72098143
NC
365 req_header.command = GET_SUBBUF_NUM_SIZE;
366
8b26d56b 367 result = do_cmd(sock, &req_header, (char *)&ch_inf,
72098143
NC
368 &res_header, (char **)&ch_inf_res);
369 if (result < 0) {
e77b8e8e
DS
370 return -1;
371 }
372
72098143
NC
373 *num = ch_inf_res->subbuf_num;
374 *size = ch_inf_res->subbuf_size;
375
376 free(ch_inf_res);
377
378 return 0;
e77b8e8e
DS
379}
380
381/**
382 * Get subbuffer num.
383 *
384 * @param channel Channel name
385 * @param pid Traced process ID
386 * @return subbuf cnf if successful, or error
387 */
8b26d56b 388int ustctl_get_subbuf_num(int sock, const char *trace, const char *channel)
e77b8e8e 389{
72098143 390 int num, size, result;
e77b8e8e 391
8b26d56b 392 result = ustctl_get_subbuf_num_size(sock, trace, channel,
72098143
NC
393 &num, &size);
394 if (result < 0) {
395 errno = -result;
08b8805e
DG
396 return -1;
397 }
e77b8e8e 398
72098143
NC
399 return num;
400}
401
402/**
403 * Get subbuffer size.
404 *
405 * @param channel Channel name
406 * @param pid Traced process ID
407 * @return subbuf size if successful, or error
408 */
8b26d56b 409int ustctl_get_subbuf_size(int sock, const char *trace, const char *channel)
72098143
NC
410{
411 int num, size, result;
412
8b26d56b 413 result = ustctl_get_subbuf_num_size(sock, trace, channel,
72098143
NC
414 &num, &size);
415 if (result < 0) {
416 errno = -result;
e77b8e8e
DS
417 return -1;
418 }
419
72098143 420 return size;
e77b8e8e 421}
763f41e5 422
8b26d56b 423static int do_trace_cmd(int sock, const char *trace, int command)
d89b8191
NC
424{
425 struct ustcomm_header req_header, res_header;
28c1bb40 426 struct ustcomm_single_field trace_inf;
d89b8191
NC
427 int result;
428
28c1bb40
NC
429 result = ustcomm_pack_single_field(&req_header,
430 &trace_inf,
431 trace);
d89b8191
NC
432 if (result < 0) {
433 errno = -result;
434 return -1;
435 }
436
437 req_header.command = command;
438
8b26d56b 439 return do_cmd(sock, &req_header, (char *)&trace_inf, &res_header, NULL);
d89b8191
NC
440}
441
ab33e65c
PP
442/**
443 * Destroys an UST trace according to a PID.
444 *
445 * @param pid Traced process ID
2298f329 446 * @return 0 if successful, or error USTCTL_ERR_GEN
ab33e65c 447 */
8b26d56b 448int ustctl_destroy_trace(int sock, const char *trace)
772030fe 449{
8b26d56b 450 return do_trace_cmd(sock, trace, DESTROY_TRACE);
ab33e65c
PP
451}
452
453/**
454 * Starts an UST trace (and setups it) according to a PID.
455 *
456 * @param pid Traced process ID
2298f329 457 * @return 0 if successful, or error USTCTL_ERR_GEN
ab33e65c 458 */
8b26d56b 459int ustctl_setup_and_start(int sock, const char *trace)
772030fe 460{
8b26d56b 461 return do_trace_cmd(sock, trace, START);
ab33e65c
PP
462}
463
62ec620f
PMF
464/**
465 * Creates an UST trace according to a PID.
466 *
467 * @param pid Traced process ID
2298f329 468 * @return 0 if successful, or error USTCTL_ERR_GEN
62ec620f 469 */
8b26d56b 470int ustctl_create_trace(int sock, const char *trace)
62ec620f 471{
8b26d56b 472 return do_trace_cmd(sock, trace, CREATE_TRACE);
62ec620f
PMF
473}
474
ab33e65c
PP
475/**
476 * Starts an UST trace according to a PID.
477 *
478 * @param pid Traced process ID
2298f329 479 * @return 0 if successful, or error USTCTL_ERR_GEN
ab33e65c 480 */
8b26d56b 481int ustctl_start_trace(int sock, const char *trace)
772030fe 482{
8b26d56b 483 return do_trace_cmd(sock, trace, START_TRACE);
ab33e65c
PP
484}
485
763f41e5
DS
486/**
487 * Alloc an UST trace according to a PID.
488 *
489 * @param pid Traced process ID
2298f329 490 * @return 0 if successful, or error USTCTL_ERR_GEN
763f41e5 491 */
8b26d56b 492int ustctl_alloc_trace(int sock, const char *trace)
763f41e5 493{
8b26d56b 494 return do_trace_cmd(sock, trace, ALLOC_TRACE);
763f41e5
DS
495}
496
e005efaa
NC
497
498int ustctl_force_switch(int sock, const char *trace)
499{
500 return do_trace_cmd(sock, trace, FORCE_SUBBUF_SWITCH);
501}
502
ab33e65c
PP
503/**
504 * Stops an UST trace according to a PID.
505 *
506 * @param pid Traced process ID
2298f329 507 * @return 0 if successful, or error USTCTL_ERR_GEN
ab33e65c 508 */
8b26d56b 509int ustctl_stop_trace(int sock, const char *trace)
772030fe 510{
8b26d56b 511 return do_trace_cmd(sock, trace, STOP_TRACE);
ab33e65c
PP
512}
513
514/**
515 * Counts newlines ('\n') in a string.
516 *
517 * @param str String to search in
518 * @return Total newlines count
519 */
2298f329 520unsigned int ustctl_count_nl(const char *str)
772030fe 521{
ab33e65c
PP
522 unsigned int i = 0, tot = 0;
523
524 while (str[i] != '\0') {
525 if (str[i] == '\n') {
526 ++tot;
527 }
528 ++i;
529 }
530
531 return tot;
532}
533
534/**
535 * Frees a CMSF array.
536 *
537 * @param cmsf CMSF array to free
2298f329 538 * @return 0 if successful, or error USTCTL_ERR_ARG
ab33e65c 539 */
b521931e 540int ustctl_free_cmsf(struct ust_marker_status *cmsf)
772030fe 541{
ab33e65c 542 if (cmsf == NULL) {
2298f329 543 return USTCTL_ERR_ARG;
ab33e65c
PP
544 }
545
546 unsigned int i = 0;
547 while (cmsf[i].channel != NULL) {
548 free(cmsf[i].channel);
b521931e 549 free(cmsf[i].ust_marker);
ab33e65c
PP
550 free(cmsf[i].fs);
551 ++i;
552 }
553 free(cmsf);
554
555 return 0;
556}
557
558/**
b521931e 559 * Gets channel/ust_marker/state/format string for a given PID.
ab33e65c
PP
560 *
561 * @param cmsf Pointer to CMSF array to be filled (callee allocates, caller
2298f329 562 * frees with `ustctl_free_cmsf')
ab33e65c 563 * @param pid Targeted PID
2a79ceeb 564 * @return 0 if successful, or -1 on error
ab33e65c 565 */
b521931e 566int ustctl_get_cmsf(int sock, struct ust_marker_status **cmsf)
772030fe 567{
72098143 568 struct ustcomm_header req_header, res_header;
08230db7 569 char *big_str = NULL;
8b26d56b 570 int result;
b521931e 571 struct ust_marker_status *tmp_cmsf = NULL;
ef290fca
PMF
572 unsigned int i = 0, cmsf_ind = 0;
573
ab33e65c 574 if (cmsf == NULL) {
2a79ceeb 575 return -1;
ab33e65c 576 }
72098143 577
72098143
NC
578 req_header.command = LIST_MARKERS;
579 req_header.size = 0;
580
8b26d56b 581 result = ustcomm_send(sock, &req_header, NULL);
72098143 582 if (result <= 0) {
b521931e 583 PERROR("error while requesting ust_marker list");
2a79ceeb 584 return -1;
ab33e65c
PP
585 }
586
8b26d56b 587 result = ustcomm_recv_alloc(sock, &res_header, &big_str);
72098143 588 if (result <= 0) {
b521931e 589 ERR("error while receiving ust_marker list");
72098143
NC
590 return -1;
591 }
592
b521931e 593 tmp_cmsf = (struct ust_marker_status *) zmalloc(sizeof(struct ust_marker_status) *
2298f329 594 (ustctl_count_nl(big_str) + 1));
ab33e65c 595 if (tmp_cmsf == NULL) {
dc46f6e6 596 ERR("Failed to allocate CMSF array");
2a79ceeb 597 return -1;
ab33e65c
PP
598 }
599
77957c95 600 /* Parse received reply string (format: "[chan]/[mark] [st] [fs]"): */
ab33e65c 601 while (big_str[i] != '\0') {
ab33e65c 602 char state;
ef290fca 603
b521931e 604 sscanf(big_str + i, "ust_marker: %a[^/]/%a[^ ] %c %a[^\n]",
72098143 605 &tmp_cmsf[cmsf_ind].channel,
b521931e 606 &tmp_cmsf[cmsf_ind].ust_marker,
72098143
NC
607 &state,
608 &tmp_cmsf[cmsf_ind].fs);
2298f329
NC
609 tmp_cmsf[cmsf_ind].state = (state == USTCTL_MS_CHR_ON ?
610 USTCTL_MS_ON : USTCTL_MS_OFF); /* Marker state */
ab33e65c
PP
611
612 while (big_str[i] != '\n') {
77957c95 613 ++i; /* Go to next '\n' */
ab33e65c 614 }
77957c95 615 ++i; /* Skip current pointed '\n' */
ab33e65c
PP
616 ++cmsf_ind;
617 }
618 tmp_cmsf[cmsf_ind].channel = NULL;
b521931e 619 tmp_cmsf[cmsf_ind].ust_marker = NULL;
ab33e65c
PP
620 tmp_cmsf[cmsf_ind].fs = NULL;
621
622 *cmsf = tmp_cmsf;
623
624 free(big_str);
625 return 0;
626}
627
a3adfb05
NC
628/**
629 * Frees a TES array.
630 *
631 * @param tes TES array to free
2298f329 632 * @return 0 if successful, or error USTCTL_ERR_ARG
a3adfb05 633 */
2298f329 634int ustctl_free_tes(struct trace_event_status *tes)
a3adfb05
NC
635{
636 if (tes == NULL) {
2298f329 637 return USTCTL_ERR_ARG;
a3adfb05
NC
638 }
639
640 unsigned int i = 0;
641 while (tes[i].name != NULL) {
642 free(tes[i].name);
643 ++i;
644 }
645 free(tes);
646
647 return 0;
648}
649
650/**
651 * Gets trace_events string for a given PID.
652 *
653 * @param tes Pointer to TES array to be filled (callee allocates, caller
2298f329 654 * frees with `ustctl_free_tes')
a3adfb05
NC
655 * @param pid Targeted PID
656 * @return 0 if successful, or -1 on error
657 */
8b26d56b 658int ustctl_get_tes(int sock, struct trace_event_status **tes)
a3adfb05 659{
72098143 660 struct ustcomm_header req_header, res_header;
a3adfb05 661 char *big_str = NULL;
8b26d56b 662 int result;
a3adfb05
NC
663 struct trace_event_status *tmp_tes = NULL;
664 unsigned int i = 0, tes_ind = 0;
665
666 if (tes == NULL) {
667 return -1;
668 }
669
72098143
NC
670 req_header.command = LIST_TRACE_EVENTS;
671 req_header.size = 0;
672
8b26d56b 673 result = ustcomm_send(sock, &req_header, NULL);
72098143
NC
674 if (result != 1) {
675 ERR("error while requesting trace_event list");
676 return -1;
677 }
678
8b26d56b 679 result = ustcomm_recv_alloc(sock, &res_header, &big_str);
a3adfb05 680 if (result != 1) {
b521931e 681 ERR("error while receiving ust_marker list");
a3adfb05
NC
682 return -1;
683 }
684
685 tmp_tes = (struct trace_event_status *)
686 zmalloc(sizeof(struct trace_event_status) *
2298f329 687 (ustctl_count_nl(big_str) + 1));
a3adfb05
NC
688 if (tmp_tes == NULL) {
689 ERR("Failed to allocate TES array");
690 return -1;
691 }
692
693 /* Parse received reply string (format: "[name]"): */
694 while (big_str[i] != '\0') {
a3adfb05 695 sscanf(big_str + i, "trace_event: %a[^\n]",
72098143 696 &tmp_tes[tes_ind].name);
a3adfb05
NC
697 while (big_str[i] != '\n') {
698 ++i; /* Go to next '\n' */
699 }
700 ++i; /* Skip current pointed '\n' */
701 ++tes_ind;
702 }
703 tmp_tes[tes_ind].name = NULL;
704
705 *tes = tmp_tes;
706
707 free(big_str);
708 return 0;
709}
710
b2fb2f91 711/**
8b26d56b 712 * Set sock path
b2fb2f91 713 *
8b26d56b 714 * @param sock_path Sock path
b2fb2f91
AH
715 * @param pid Traced process ID
716 * @return 0 if successful, or error
717 */
8b26d56b 718int ustctl_set_sock_path(int sock, const char *sock_path)
b2fb2f91 719{
28c1bb40 720 int result;
72098143 721 struct ustcomm_header req_header, res_header;
28c1bb40 722 struct ustcomm_single_field sock_path_msg;
72098143 723
28c1bb40
NC
724 result = ustcomm_pack_single_field(&req_header,
725 &sock_path_msg,
726 sock_path);
727 if (result < 0) {
728 errno = -result;
08b8805e
DG
729 return -1;
730 }
b2fb2f91 731
72098143 732 req_header.command = SET_SOCK_PATH;
b2fb2f91 733
8b26d56b 734 return do_cmd(sock, &req_header, (char *)&sock_path_msg,
72098143 735 &res_header, NULL);
b2fb2f91
AH
736}
737
738/**
8b26d56b 739 * Get sock path
b2fb2f91 740 *
8b26d56b 741 * @param sock_path Pointer to where the sock path will be returned
b2fb2f91
AH
742 * @param pid Traced process ID
743 * @return 0 if successful, or error
744 */
8b26d56b 745int ustctl_get_sock_path(int sock, char **sock_path)
b2fb2f91 746{
b2fb2f91 747 int result;
72098143 748 struct ustcomm_header req_header, res_header;
28c1bb40 749 struct ustcomm_single_field *sock_path_msg;
72098143
NC
750
751 req_header.command = GET_SOCK_PATH;
752 req_header.size = 0;
b2fb2f91 753
8b26d56b 754 result = do_cmd(sock, &req_header, NULL, &res_header,
72098143
NC
755 (char **)&sock_path_msg);
756 if (result < 0) {
757 return -1;
08b8805e 758 }
b2fb2f91 759
28c1bb40 760 result = ustcomm_unpack_single_field(sock_path_msg);
72098143
NC
761 if (result < 0) {
762 return result;
b2fb2f91
AH
763 }
764
28c1bb40 765 *sock_path = strdup(sock_path_msg->field);
b2fb2f91 766
72098143 767 free(sock_path_msg);
b9318b35
AH
768
769 return 0;
770}
This page took 0.070385 seconds and 4 git commands to generate.