libustctl: cleanup ustctl_get_online_pids functions
[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;
8b6984b8 113 long 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
8b6984b8
NC
124 errno = 0;
125 read_pid = strtol(dirent->d_name, NULL, 10);
126 if (errno) {
127 continue;
128 }
dde0eeef 129
8b6984b8
NC
130 /*
131 * FIXME: Here we previously called pid_is_online, which
dde0eeef
NC
132 * always returned 1, now I replaced it with just 1.
133 * We need to figure out an intelligent way of solving
134 * this, maybe connect-disconnect.
135 */
136 if (1) {
8b6984b8
NC
137
138 (*pid_list)[(*pid_list_index)++] = read_pid;
139
140 if (*pid_list_index == *pid_list_size) {
141 if (realloc_pid_list(pid_list, pid_list_size)) {
142 return -1;
143 }
144 }
ab33e65c
PP
145 }
146 }
147
8b6984b8
NC
148 (*pid_list)[*pid_list_index] = 0; /* Array end */
149
150 return 0;
dde0eeef 151}
ab33e65c 152
1031eea2 153static pid_t *get_pids_non_root(void)
dde0eeef
NC
154{
155 char *dir_name;
156 DIR *dir;
8b6984b8 157 unsigned int pid_list_index = 0, pid_list_size = 1;
dde0eeef
NC
158 pid_t *pid_list = NULL;
159
160 dir_name = ustcomm_user_sock_dir();
161 if (!dir_name) {
ab33e65c
PP
162 return NULL;
163 }
164
dde0eeef
NC
165 dir = opendir(dir_name);
166 if (!dir) {
167 goto free_dir_name;
168 }
169
170 pid_list = malloc(pid_list_size * sizeof(pid_t));
1031eea2
NC
171 if (!pid_list) {
172 goto close_dir;
173 }
dde0eeef 174
8b6984b8
NC
175 if (get_pids_in_dir(dir, &pid_list, &pid_list_index, &pid_list_size)) {
176 /* if any errors are encountered, force freeing of the list */
177 pid_list[0] = 0;
dde0eeef
NC
178 }
179
180close_dir:
ab33e65c 181 closedir(dir);
dde0eeef
NC
182
183free_dir_name:
184 free(dir_name);
185
186 return pid_list;
ab33e65c
PP
187}
188
1031eea2
NC
189static pid_t *get_pids_root(void)
190{
191 char *dir_name;
192 DIR *tmp_dir, *dir;
8b6984b8 193 unsigned int pid_list_index = 0, pid_list_size = 1;
1031eea2
NC
194 pid_t *pid_list = NULL;
195 struct dirent *dirent;
8b6984b8 196 int result;
1031eea2
NC
197
198 tmp_dir = opendir(USER_TMP_DIR);
199 if (!tmp_dir) {
200 return NULL;
201 }
202
203 pid_list = malloc(pid_list_size * sizeof(pid_t));
204 if (!pid_list) {
205 goto close_tmp_dir;
206 }
207
208 while ((dirent = readdir(tmp_dir))) {
209 /* Compare the dir to check for the USER_SOCK_DIR_BASE prefix */
210 if (!strncmp(dirent->d_name, USER_SOCK_DIR_BASE,
211 strlen(USER_SOCK_DIR_BASE))) {
212
8b6984b8
NC
213 if (asprintf(&dir_name, USER_TMP_DIR "/%s",
214 dirent->d_name) < 0) {
1031eea2
NC
215 goto close_tmp_dir;
216 }
217
218 dir = opendir(dir_name);
219
220 free(dir_name);
221
222 if (!dir) {
223 continue;
224 }
225
8b6984b8
NC
226 result = get_pids_in_dir(dir, &pid_list, &pid_list_index,
227 &pid_list_size);
1031eea2
NC
228
229 closedir(dir);
8b6984b8
NC
230
231 if (result) {
232 /*
233 * if any errors are encountered,
234 * force freeing of the list
235 */
236 pid_list[0] = 0;
237 break;
238 }
1031eea2
NC
239 }
240 }
241
242close_tmp_dir:
243 closedir(tmp_dir);
244
245 return pid_list;
246}
247
248pid_t *ustctl_get_online_pids(void)
249{
8b6984b8
NC
250 pid_t *pid_list;
251
1031eea2 252 if (geteuid()) {
8b6984b8 253 pid_list = get_pids_non_root();
1031eea2 254 } else {
8b6984b8
NC
255 pid_list = get_pids_root();
256 }
257
258 if (pid_list && pid_list[0] == 0) {
259 /* No PID at all */
260 free(pid_list);
261 pid_list = NULL;
1031eea2 262 }
8b6984b8
NC
263
264 return pid_list;
1031eea2
NC
265}
266
ab33e65c 267/**
2298f329 268 * Sets marker state (USTCTL_MS_ON or USTCTL_MS_OFF).
ab33e65c
PP
269 *
270 * @param mn Marker name
271 * @param state Marker's new state
272 * @param pid Traced process ID
2298f329 273 * @return 0 if successful, or errors {USTCTL_ERR_GEN, USTCTL_ERR_ARG}
ab33e65c 274 */
8b26d56b
NC
275int ustctl_set_marker_state(int sock, const char *trace, const char *channel,
276 const char *marker, int state)
ef290fca 277{
72098143
NC
278 struct ustcomm_header req_header, res_header;
279 struct ustcomm_marker_info marker_inf;
ef290fca
PMF
280 int result;
281
72098143
NC
282 result = ustcomm_pack_marker_info(&req_header,
283 &marker_inf,
d89b8191 284 trace,
72098143
NC
285 channel,
286 marker);
287 if (result < 0) {
288 errno = -result;
289 return -1;
08b8805e 290 }
ab33e65c 291
72098143 292 req_header.command = state ? ENABLE_MARKER : DISABLE_MARKER;
ab33e65c 293
8b26d56b 294 return do_cmd(sock, &req_header, (char *)&marker_inf,
72098143 295 &res_header, NULL);
ab33e65c
PP
296}
297
763f41e5
DS
298/**
299 * Set subbuffer size.
300 *
301 * @param channel_size Channel name and size
302 * @param pid Traced process ID
303 * @return 0 if successful, or error
304 */
8b26d56b
NC
305int ustctl_set_subbuf_size(int sock, const char *trace, const char *channel,
306 unsigned int subbuf_size)
763f41e5 307{
72098143
NC
308 struct ustcomm_header req_header, res_header;
309 struct ustcomm_channel_info ch_inf;
763f41e5
DS
310 int result;
311
72098143
NC
312 result = ustcomm_pack_channel_info(&req_header,
313 &ch_inf,
d89b8191 314 trace,
72098143
NC
315 channel);
316 if (result < 0) {
317 errno = -result;
08b8805e
DG
318 return -1;
319 }
763f41e5 320
72098143
NC
321 req_header.command = SET_SUBBUF_SIZE;
322 ch_inf.subbuf_size = subbuf_size;
763f41e5 323
8b26d56b 324 return do_cmd(sock, &req_header, (char *)&ch_inf,
72098143 325 &res_header, NULL);
763f41e5
DS
326}
327
328/**
329 * Set subbuffer num.
330 *
331 * @param channel_num Channel name and num
332 * @param pid Traced process ID
333 * @return 0 if successful, or error
334 */
8b26d56b
NC
335int ustctl_set_subbuf_num(int sock, const char *trace, const char *channel,
336 unsigned int num)
763f41e5 337{
72098143
NC
338 struct ustcomm_header req_header, res_header;
339 struct ustcomm_channel_info ch_inf;
763f41e5
DS
340 int result;
341
72098143
NC
342 result = ustcomm_pack_channel_info(&req_header,
343 &ch_inf,
d89b8191 344 trace,
72098143
NC
345 channel);
346 if (result < 0) {
347 errno = -result;
08b8805e
DG
348 return -1;
349 }
763f41e5 350
72098143
NC
351 req_header.command = SET_SUBBUF_NUM;
352 ch_inf.subbuf_num = num;
353
8b26d56b 354 return do_cmd(sock, &req_header, (char *)&ch_inf,
72098143 355 &res_header, NULL);
763f41e5 356
763f41e5
DS
357}
358
8b26d56b
NC
359
360static int ustctl_get_subbuf_num_size(int sock, const char *trace, const char *channel,
361 int *num, int *size)
e77b8e8e 362{
72098143
NC
363 struct ustcomm_header req_header, res_header;
364 struct ustcomm_channel_info ch_inf, *ch_inf_res;
e77b8e8e
DS
365 int result;
366
72098143
NC
367
368 result = ustcomm_pack_channel_info(&req_header,
369 &ch_inf,
d89b8191 370 trace,
72098143
NC
371 channel);
372 if (result < 0) {
373 errno = -result;
08b8805e
DG
374 return -1;
375 }
e77b8e8e 376
72098143
NC
377 req_header.command = GET_SUBBUF_NUM_SIZE;
378
8b26d56b 379 result = do_cmd(sock, &req_header, (char *)&ch_inf,
72098143
NC
380 &res_header, (char **)&ch_inf_res);
381 if (result < 0) {
e77b8e8e
DS
382 return -1;
383 }
384
72098143
NC
385 *num = ch_inf_res->subbuf_num;
386 *size = ch_inf_res->subbuf_size;
387
388 free(ch_inf_res);
389
390 return 0;
e77b8e8e
DS
391}
392
393/**
394 * Get subbuffer num.
395 *
396 * @param channel Channel name
397 * @param pid Traced process ID
398 * @return subbuf cnf if successful, or error
399 */
8b26d56b 400int ustctl_get_subbuf_num(int sock, const char *trace, const char *channel)
e77b8e8e 401{
72098143 402 int num, size, result;
e77b8e8e 403
8b26d56b 404 result = ustctl_get_subbuf_num_size(sock, trace, channel,
72098143
NC
405 &num, &size);
406 if (result < 0) {
407 errno = -result;
08b8805e
DG
408 return -1;
409 }
e77b8e8e 410
72098143
NC
411 return num;
412}
413
414/**
415 * Get subbuffer size.
416 *
417 * @param channel Channel name
418 * @param pid Traced process ID
419 * @return subbuf size if successful, or error
420 */
8b26d56b 421int ustctl_get_subbuf_size(int sock, const char *trace, const char *channel)
72098143
NC
422{
423 int num, size, result;
424
8b26d56b 425 result = ustctl_get_subbuf_num_size(sock, trace, channel,
72098143
NC
426 &num, &size);
427 if (result < 0) {
428 errno = -result;
e77b8e8e
DS
429 return -1;
430 }
431
72098143 432 return size;
e77b8e8e 433}
763f41e5 434
8b26d56b 435static int do_trace_cmd(int sock, const char *trace, int command)
d89b8191
NC
436{
437 struct ustcomm_header req_header, res_header;
28c1bb40 438 struct ustcomm_single_field trace_inf;
d89b8191
NC
439 int result;
440
28c1bb40
NC
441 result = ustcomm_pack_single_field(&req_header,
442 &trace_inf,
443 trace);
d89b8191
NC
444 if (result < 0) {
445 errno = -result;
446 return -1;
447 }
448
449 req_header.command = command;
450
8b26d56b 451 return do_cmd(sock, &req_header, (char *)&trace_inf, &res_header, NULL);
d89b8191
NC
452}
453
ab33e65c
PP
454/**
455 * Destroys an UST trace according to a PID.
456 *
457 * @param pid Traced process ID
2298f329 458 * @return 0 if successful, or error USTCTL_ERR_GEN
ab33e65c 459 */
8b26d56b 460int ustctl_destroy_trace(int sock, const char *trace)
772030fe 461{
8b26d56b 462 return do_trace_cmd(sock, trace, DESTROY_TRACE);
ab33e65c
PP
463}
464
465/**
466 * Starts an UST trace (and setups it) according to a PID.
467 *
468 * @param pid Traced process ID
2298f329 469 * @return 0 if successful, or error USTCTL_ERR_GEN
ab33e65c 470 */
8b26d56b 471int ustctl_setup_and_start(int sock, const char *trace)
772030fe 472{
8b26d56b 473 return do_trace_cmd(sock, trace, START);
ab33e65c
PP
474}
475
62ec620f
PMF
476/**
477 * Creates an UST trace according to a PID.
478 *
479 * @param pid Traced process ID
2298f329 480 * @return 0 if successful, or error USTCTL_ERR_GEN
62ec620f 481 */
8b26d56b 482int ustctl_create_trace(int sock, const char *trace)
62ec620f 483{
8b26d56b 484 return do_trace_cmd(sock, trace, CREATE_TRACE);
62ec620f
PMF
485}
486
ab33e65c
PP
487/**
488 * Starts an UST trace according to a PID.
489 *
490 * @param pid Traced process ID
2298f329 491 * @return 0 if successful, or error USTCTL_ERR_GEN
ab33e65c 492 */
8b26d56b 493int ustctl_start_trace(int sock, const char *trace)
772030fe 494{
8b26d56b 495 return do_trace_cmd(sock, trace, START_TRACE);
ab33e65c
PP
496}
497
763f41e5
DS
498/**
499 * Alloc an UST trace according to a PID.
500 *
501 * @param pid Traced process ID
2298f329 502 * @return 0 if successful, or error USTCTL_ERR_GEN
763f41e5 503 */
8b26d56b 504int ustctl_alloc_trace(int sock, const char *trace)
763f41e5 505{
8b26d56b 506 return do_trace_cmd(sock, trace, ALLOC_TRACE);
763f41e5
DS
507}
508
e005efaa
NC
509
510int ustctl_force_switch(int sock, const char *trace)
511{
512 return do_trace_cmd(sock, trace, FORCE_SUBBUF_SWITCH);
513}
514
ab33e65c
PP
515/**
516 * Stops an UST trace according to a PID.
517 *
518 * @param pid Traced process ID
2298f329 519 * @return 0 if successful, or error USTCTL_ERR_GEN
ab33e65c 520 */
8b26d56b 521int ustctl_stop_trace(int sock, const char *trace)
772030fe 522{
8b26d56b 523 return do_trace_cmd(sock, trace, STOP_TRACE);
ab33e65c
PP
524}
525
526/**
527 * Counts newlines ('\n') in a string.
528 *
529 * @param str String to search in
530 * @return Total newlines count
531 */
2298f329 532unsigned int ustctl_count_nl(const char *str)
772030fe 533{
ab33e65c
PP
534 unsigned int i = 0, tot = 0;
535
536 while (str[i] != '\0') {
537 if (str[i] == '\n') {
538 ++tot;
539 }
540 ++i;
541 }
542
543 return tot;
544}
545
546/**
547 * Frees a CMSF array.
548 *
549 * @param cmsf CMSF array to free
2298f329 550 * @return 0 if successful, or error USTCTL_ERR_ARG
ab33e65c 551 */
2298f329 552int ustctl_free_cmsf(struct marker_status *cmsf)
772030fe 553{
ab33e65c 554 if (cmsf == NULL) {
2298f329 555 return USTCTL_ERR_ARG;
ab33e65c
PP
556 }
557
558 unsigned int i = 0;
559 while (cmsf[i].channel != NULL) {
560 free(cmsf[i].channel);
561 free(cmsf[i].marker);
562 free(cmsf[i].fs);
563 ++i;
564 }
565 free(cmsf);
566
567 return 0;
568}
569
570/**
571 * Gets channel/marker/state/format string for a given PID.
572 *
573 * @param cmsf Pointer to CMSF array to be filled (callee allocates, caller
2298f329 574 * frees with `ustctl_free_cmsf')
ab33e65c 575 * @param pid Targeted PID
2a79ceeb 576 * @return 0 if successful, or -1 on error
ab33e65c 577 */
8b26d56b 578int ustctl_get_cmsf(int sock, struct marker_status **cmsf)
772030fe 579{
72098143 580 struct ustcomm_header req_header, res_header;
08230db7 581 char *big_str = NULL;
8b26d56b 582 int result;
08230db7 583 struct marker_status *tmp_cmsf = NULL;
ef290fca
PMF
584 unsigned int i = 0, cmsf_ind = 0;
585
ab33e65c 586 if (cmsf == NULL) {
2a79ceeb 587 return -1;
ab33e65c 588 }
72098143 589
72098143
NC
590 req_header.command = LIST_MARKERS;
591 req_header.size = 0;
592
8b26d56b 593 result = ustcomm_send(sock, &req_header, NULL);
72098143 594 if (result <= 0) {
8b26d56b 595 PERROR("error while requesting markers list");
2a79ceeb 596 return -1;
ab33e65c
PP
597 }
598
8b26d56b 599 result = ustcomm_recv_alloc(sock, &res_header, &big_str);
72098143
NC
600 if (result <= 0) {
601 ERR("error while receiving markers list");
602 return -1;
603 }
604
72098143 605 tmp_cmsf = (struct marker_status *) zmalloc(sizeof(struct marker_status) *
2298f329 606 (ustctl_count_nl(big_str) + 1));
ab33e65c 607 if (tmp_cmsf == NULL) {
dc46f6e6 608 ERR("Failed to allocate CMSF array");
2a79ceeb 609 return -1;
ab33e65c
PP
610 }
611
77957c95 612 /* Parse received reply string (format: "[chan]/[mark] [st] [fs]"): */
ab33e65c 613 while (big_str[i] != '\0') {
ab33e65c 614 char state;
ef290fca 615
264f6231 616 sscanf(big_str + i, "marker: %a[^/]/%a[^ ] %c %a[^\n]",
72098143
NC
617 &tmp_cmsf[cmsf_ind].channel,
618 &tmp_cmsf[cmsf_ind].marker,
619 &state,
620 &tmp_cmsf[cmsf_ind].fs);
2298f329
NC
621 tmp_cmsf[cmsf_ind].state = (state == USTCTL_MS_CHR_ON ?
622 USTCTL_MS_ON : USTCTL_MS_OFF); /* Marker state */
ab33e65c
PP
623
624 while (big_str[i] != '\n') {
77957c95 625 ++i; /* Go to next '\n' */
ab33e65c 626 }
77957c95 627 ++i; /* Skip current pointed '\n' */
ab33e65c
PP
628 ++cmsf_ind;
629 }
630 tmp_cmsf[cmsf_ind].channel = NULL;
631 tmp_cmsf[cmsf_ind].marker = NULL;
632 tmp_cmsf[cmsf_ind].fs = NULL;
633
634 *cmsf = tmp_cmsf;
635
636 free(big_str);
637 return 0;
638}
639
a3adfb05
NC
640/**
641 * Frees a TES array.
642 *
643 * @param tes TES array to free
2298f329 644 * @return 0 if successful, or error USTCTL_ERR_ARG
a3adfb05 645 */
2298f329 646int ustctl_free_tes(struct trace_event_status *tes)
a3adfb05
NC
647{
648 if (tes == NULL) {
2298f329 649 return USTCTL_ERR_ARG;
a3adfb05
NC
650 }
651
652 unsigned int i = 0;
653 while (tes[i].name != NULL) {
654 free(tes[i].name);
655 ++i;
656 }
657 free(tes);
658
659 return 0;
660}
661
662/**
663 * Gets trace_events string for a given PID.
664 *
665 * @param tes Pointer to TES array to be filled (callee allocates, caller
2298f329 666 * frees with `ustctl_free_tes')
a3adfb05
NC
667 * @param pid Targeted PID
668 * @return 0 if successful, or -1 on error
669 */
8b26d56b 670int ustctl_get_tes(int sock, struct trace_event_status **tes)
a3adfb05 671{
72098143 672 struct ustcomm_header req_header, res_header;
a3adfb05 673 char *big_str = NULL;
8b26d56b 674 int result;
a3adfb05
NC
675 struct trace_event_status *tmp_tes = NULL;
676 unsigned int i = 0, tes_ind = 0;
677
678 if (tes == NULL) {
679 return -1;
680 }
681
72098143
NC
682 req_header.command = LIST_TRACE_EVENTS;
683 req_header.size = 0;
684
8b26d56b 685 result = ustcomm_send(sock, &req_header, NULL);
72098143
NC
686 if (result != 1) {
687 ERR("error while requesting trace_event list");
688 return -1;
689 }
690
8b26d56b 691 result = ustcomm_recv_alloc(sock, &res_header, &big_str);
a3adfb05 692 if (result != 1) {
72098143 693 ERR("error while receiving markers list");
a3adfb05
NC
694 return -1;
695 }
696
697 tmp_tes = (struct trace_event_status *)
698 zmalloc(sizeof(struct trace_event_status) *
2298f329 699 (ustctl_count_nl(big_str) + 1));
a3adfb05
NC
700 if (tmp_tes == NULL) {
701 ERR("Failed to allocate TES array");
702 return -1;
703 }
704
705 /* Parse received reply string (format: "[name]"): */
706 while (big_str[i] != '\0') {
a3adfb05 707 sscanf(big_str + i, "trace_event: %a[^\n]",
72098143 708 &tmp_tes[tes_ind].name);
a3adfb05
NC
709 while (big_str[i] != '\n') {
710 ++i; /* Go to next '\n' */
711 }
712 ++i; /* Skip current pointed '\n' */
713 ++tes_ind;
714 }
715 tmp_tes[tes_ind].name = NULL;
716
717 *tes = tmp_tes;
718
719 free(big_str);
720 return 0;
721}
722
b2fb2f91 723/**
8b26d56b 724 * Set sock path
b2fb2f91 725 *
8b26d56b 726 * @param sock_path Sock path
b2fb2f91
AH
727 * @param pid Traced process ID
728 * @return 0 if successful, or error
729 */
8b26d56b 730int ustctl_set_sock_path(int sock, const char *sock_path)
b2fb2f91 731{
28c1bb40 732 int result;
72098143 733 struct ustcomm_header req_header, res_header;
28c1bb40 734 struct ustcomm_single_field sock_path_msg;
72098143 735
28c1bb40
NC
736 result = ustcomm_pack_single_field(&req_header,
737 &sock_path_msg,
738 sock_path);
739 if (result < 0) {
740 errno = -result;
08b8805e
DG
741 return -1;
742 }
b2fb2f91 743
72098143 744 req_header.command = SET_SOCK_PATH;
b2fb2f91 745
8b26d56b 746 return do_cmd(sock, &req_header, (char *)&sock_path_msg,
72098143 747 &res_header, NULL);
b2fb2f91
AH
748}
749
750/**
8b26d56b 751 * Get sock path
b2fb2f91 752 *
8b26d56b 753 * @param sock_path Pointer to where the sock path will be returned
b2fb2f91
AH
754 * @param pid Traced process ID
755 * @return 0 if successful, or error
756 */
8b26d56b 757int ustctl_get_sock_path(int sock, char **sock_path)
b2fb2f91 758{
b2fb2f91 759 int result;
72098143 760 struct ustcomm_header req_header, res_header;
28c1bb40 761 struct ustcomm_single_field *sock_path_msg;
72098143
NC
762
763 req_header.command = GET_SOCK_PATH;
764 req_header.size = 0;
b2fb2f91 765
8b26d56b 766 result = do_cmd(sock, &req_header, NULL, &res_header,
72098143
NC
767 (char **)&sock_path_msg);
768 if (result < 0) {
769 return -1;
08b8805e 770 }
b2fb2f91 771
28c1bb40 772 result = ustcomm_unpack_single_field(sock_path_msg);
72098143
NC
773 if (result < 0) {
774 return result;
b2fb2f91
AH
775 }
776
28c1bb40 777 *sock_path = strdup(sock_path_msg->field);
b2fb2f91 778
72098143 779 free(sock_path_msg);
b9318b35
AH
780
781 return 0;
782}
This page took 0.069725 seconds and 4 git commands to generate.