---
name: "tracefs_filter_string_append"
section: "3"
platform: "linux"
package: "libtracefs"
version: "1.8.4-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/tracefs_filter_string_append"
---

# tracefs\_filter\_string\_append(3)

Add, verify and apply event filters

## NAME

tracefs\_filter\_string\_append, tracefs\_filter\_string\_verify, tracefs\_event\_filter\_apply, tracefs\_event\_filter\_clear - Add, verify and apply event filters

## SYNOPSIS

```
#include <tracefs.h>
int tracefs_filter_string_append(struct tep_event *event, char **filter,
                                 struct tracefs_filter type, const char *field,
                                 enum tracefs_synth_compare compare, const char *val);
int tracefs_filter_string_verify(struct tep_event *event, const char *filter, char **err);
int tracefs_event_filter_apply(struct tracefs_instance *instance, struct tep_event *event, const char *filter);
int tracefs_event_filter_clear(struct tracefs_instance *instance, struct tep_event *event);
```

## DESCRIPTION

**tracefs\_filter\_string\_append**() is a way to create and verify event filters for a given event. It will verify that the *field* belongs to the event and that the *compare* option that is used is valid for the type of the field, as well as *val*. For the *type* that is not of **TRACEFS\_FILTER\_COMPARE**, it will build the logical string and also make sure that the syntax is correct. For example, there are no more close parenthesis than open parenthesis. An AND (&&) or OR (\|\|) is not misplaced, etc.

**tracefs\_synth\_append\_start\_filter**() creates a filter or appends to it for the starting event. Depending on *type*, it will build a string of tokens for parenthesis or logic statemens, or it may add a comparison of *field* to *val* based on *compare*.

If *type* is: **TRACEFS\_FILTER\_COMPARE** - See below **TRACEFS\_FILTER\_AND** - Append "&&" to the filter **TRACEFS\_FILTER\_OR** - Append "\|\|" to the filter **TRACEFS\_FILTER\_NOT** - Append "!" to the filter **TRACEFS\_FILTER\_OPEN\_PAREN** - Append "(" to the filter **TRACEFS\_FILTER\_CLOSE\_PAREN** - Append ")" to the filter

*field*, *compare*, and *val* are ignored unless *type* is equal to **TRACEFS\_FILTER\_COMPARE**, then \_compare will be used for the following:

**TRACEFS\_COMPARE\_EQ** - *field* == *val*

**TRACEFS\_COMPARE\_NE** - *field* != *val*

**TRACEFS\_COMPARE\_GT** - *field* \> *val*

**TRACEFS\_COMPARE\_GE** - *field* \>= *val*

**TRACEFS\_COMPARE\_LT** - *field* \< *val*

**TRACEFS\_COMPARE\_LE** - *field* \<= *val*

**TRACEFS\_COMPARE\_RE** - *field* ~ "*val*" : where *field* is a string.

**TRACEFS\_COMPARE\_AND** - *field* & *val* : where *field* is a flags field.

**tracefs\_filter\_string\_verify**() will parse *filter* to make sure that the fields are for the *event*, and that the syntax is correct. If there’s an error in the syntax, and *err* is not NULL, then it will be allocated with an error message stating what was found wrong with the filter. *err* must be freed with **free**().

**tracefs\_event\_filter\_apply**() applies given *filter* string on *event* in given *instance*.

**tracefs\_event\_filter\_clear**() clear all filters on *event* in given *instance*.

## RETURN VALUE

**tracefs\_filter\_string\_append**() returns 0 on success and -1 on error.

**tracefs\_filter\_string\_verify**() returns 0 on success and -1 on error. if there is an error, and *errno* is not **ENOMEM**, then *err* is allocated and will contain a string describing what was found wrong with *filter*. *err* must be freed with **free**().

**tracefs\_event\_filter\_apply**() returns 0 on success and -1 on error.

**tracefs\_event\_filter\_clear**() returns 0 on success and -1 on error.

## EXAMPLE

```
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <tracefs.h>
static void usage(char **argv)
{
        fprintf(stderr, "usage: %s [system] event filter\n", argv[0]);
        exit(-1);
}
int main (int argc, char **argv)
{
        struct tep_handle *tep;
        struct tep_event *event;
        const char *system = NULL;
        const char *event_name;
        const char *filter;
        char *new_filter = NULL;
        char *err = NULL;
        int i;
        if (argc < 3)
                usage(argv);
        if (argc < 4) {
                event_name = argv[1];
                filter = argv[2];
        } else {
                system = argv[1];
                event_name = argv[2];
                filter = argv[3];
        }
        /* Load all events from the system */
        tep = tracefs_local_events(NULL);
        if (!tep) {
                perror("tep");
                exit(-1);
        }
        event = tep_find_event_by_name(tep, system, event_name);
        if (!event) {
                fprintf(stderr, "Event %s%s%s not found\n",
                        system ? system : "" , system ? " " : "",
                        event_name);
                exit(-1);
        }
        if (tracefs_filter_string_verify(event, filter, &err) < 0) {
                perror("tracecfs_event_verify_filter");
                if (err)
                        fprintf(stderr, "%s", err);
                free(err);
                exit(-1);
        }
        for (i = 0; filter[i]; i++) {
                char buf[strlen(filter)];
                char *field = NULL;
                char *val = NULL;
                enum tracefs_filter type;
                enum tracefs_compare compare = 0;
                int start_i, n;
                int quote;
                bool backslash;
                while (isspace(filter[i]))
                        i++;
                switch(filter[i]) {
                case '(':
                        type = TRACEFS_FILTER_OPEN_PAREN;
                        break;
                case ')':
                        type = TRACEFS_FILTER_CLOSE_PAREN;
                        break;
                case '!':
                        type = TRACEFS_FILTER_NOT;
                        break;
                case '&':
                        type = TRACEFS_FILTER_AND;
                        i++;
                        break;
                case '|':
                        type = TRACEFS_FILTER_OR;
                        i++;
                        break;
                default:
                        type = TRACEFS_FILTER_COMPARE;
                        while (isspace(filter[i]))
                                i++;
                        start_i = i;
                        for (; filter[i]; i++) {
                                switch(filter[i]) {
                                case 'a' ... 'z':
                                case 'A' ... 'Z':
                                case '0' ... '9':
                                case '_':
                                        continue;
                                }
                                break;
                        }
                        n = i - start_i;
                        field = buf;
                        strncpy(field, filter + start_i, n);
                        field[n++] = '\0';
                        val = buf + n;
                        while (isspace(filter[i]))
                                i++;
                        start_i = i;
                        switch(filter[i++]) {
                        case '>':
                                compare = TRACEFS_COMPARE_GT;
                                if (filter[i] == '=') {
                                        i++;
                                        compare = TRACEFS_COMPARE_GE;
                                }
                                break;
                        case '<':
                                compare = TRACEFS_COMPARE_LT;
                                if (filter[i] == '=') {
                                        i++;
                                        compare = TRACEFS_COMPARE_LE;
                                }
                                break;
                        case '=':
                                compare = TRACEFS_COMPARE_EQ;
                                i++;
                                break;
                        case '!':
                                compare = TRACEFS_COMPARE_NE;
                                i++;
                                break;
                        case '~':
                                compare = TRACEFS_COMPARE_RE;
                                break;
                        case '&':
                                compare = TRACEFS_COMPARE_AND;
                                break;
                        }
                        while (isspace(filter[i]))
                                i++;
                        quote = 0;
                        backslash = false;
                        start_i = i;
                        for (; filter[i]; i++) {
                                if (quote) {
                                        if (backslash)
                                                backslash = false;
                                        else if (filter[i] == '\\')
                                                backslash = true;
                                        else if (filter[i] == quote)
                                                quote = 0;
                                        continue;
                                }
                                switch(filter[i]) {
                                case '"': case '\'':
                                        quote = filter[i];
                                        continue;
                                case 'a' ... 'z':
                                case 'A' ... 'Z':
                                case '0' ... '9':
                                case '_':
                                        continue;
                                }
                                break;
                        }
                        n = i - start_i;
                        strncpy(val, filter + start_i, n);
                        val[n] = '\0';
                        break;
                }
                n = tracefs_filter_string_append(event, &new_filter, type,
                                                field, compare, val);
                if (n < 0) {
                        fprintf(stderr, "Failed making new filter:\n'%s'\n",
                                new_filter ? new_filter : "(null)");
                        exit(-1);
                }
        }
        if (tracefs_event_filter_apply(NULL, event, new_filter))
                fprintf(stderr, "Failed to apply filter on event");
        tep_free(tep);
        printf("Created new filter: '%s'\n", new_filter);
        free(new_filter);
        exit(0);
}
```

## FILES

```
tracefs.h
        Header file to include in order to have access to the library APIs.
-ltracefs
        Linker switch to add when building a program that uses the library.
```

## SEE ALSO

[**libtracefs**(3)](/libtracefs/3.md), [**libtraceevent**(3)](/libtraceevent/3.md), [**trace-cmd**(1)](/trace-cmd/1.md), [**tracefs\_hist\_alloc**(3)](/tracefs_hist_alloc/3.md), [**tracefs\_hist\_alloc\_2d**(3)](/tracefs_hist_alloc_2d/3.md), [**tracefs\_hist\_alloc\_nd**(3)](/tracefs_hist_alloc_nd/3.md), [**tracefs\_hist\_free**(3)](/tracefs_hist_free/3.md), [**tracefs\_hist\_add\_key**(3)](/tracefs_hist_add_key/3.md), [**tracefs\_hist\_add\_value**(3)](/tracefs_hist_add_value/3.md), [**tracefs\_hist\_add\_name**(3)](/tracefs_hist_add_name/3.md), [**tracefs\_hist\_start**(3)](/tracefs_hist_start/3.md), **tracefs\_hist\_destory**(3), [**tracefs\_hist\_add\_sort\_key**(3)](/tracefs_hist_add_sort_key/3.md), [**tracefs\_hist\_sort\_key\_direction**(3)](/tracefs_hist_sort_key_direction/3.md)

## AUTHOR

```
Steven Rostedt <rostedt@goodmis.org[1]>
Tzvetomir Stoyanov <tz.stoyanov@gmail.com[2]>
sameeruddin shaik <sameeruddin.shaik8@gmail.com[3]>
```

## REPORTING BUGS

Report bugs to \<**linux-trace-devel@vger.kernel.org**\[4\]\>

## LICENSE

libtracefs is Free Software licensed under the GNU LGPL 2.1

## RESOURCES

**https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/**

## COPYING

Copyright (C) 2020 VMware, Inc. Free use of this software is granted under the terms of the GNU Public License (GPL).

## NOTES

- 1\.

  rostedt@goodmis.org

  mailto:rostedt@goodmis.org

- 2\.

  tz.stoyanov@gmail.com

  mailto:tz.stoyanov@gmail.com

- 3\.

  sameeruddin.shaik8@gmail.com

  mailto:sameeruddin.shaik8@gmail.com

- 4\.

  linux-trace-devel@vger.kernel.org

  mailto:linux-trace-devel@vger.kernel.org
