tools api: Add io__getline
Reads a line to allocated memory up to a newline following the getline API. Committer notes: It also adds this new function to the 'api io' 'perf test' entry: $ perf test "api io" 64: Test api io : Ok $ Signed-off-by: Ian Rogers <irogers@google.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Acked-by: Namhyung Kim <namhyung@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Nathan Chancellor <nathan@kernel.org> Cc: Nick Desaulniers <ndesaulniers@google.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Tom Rix <trix@redhat.com> Cc: llvm@lists.linux.dev Link: https://lore.kernel.org/r/20230403184033.1836023-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
98b7ce0ed8
commit
c9dc580c43
@ -7,7 +7,9 @@
|
|||||||
#ifndef __API_IO__
|
#ifndef __API_IO__
|
||||||
#define __API_IO__
|
#define __API_IO__
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
struct io {
|
struct io {
|
||||||
@ -112,4 +114,47 @@ static inline int io__get_dec(struct io *io, __u64 *dec)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read up to and including the first newline following the pattern of getline. */
|
||||||
|
static inline ssize_t io__getline(struct io *io, char **line_out, size_t *line_len_out)
|
||||||
|
{
|
||||||
|
char buf[128];
|
||||||
|
int buf_pos = 0;
|
||||||
|
char *line = NULL, *temp;
|
||||||
|
size_t line_len = 0;
|
||||||
|
int ch = 0;
|
||||||
|
|
||||||
|
/* TODO: reuse previously allocated memory. */
|
||||||
|
free(*line_out);
|
||||||
|
while (ch != '\n') {
|
||||||
|
ch = io__get_char(io);
|
||||||
|
|
||||||
|
if (ch < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (buf_pos == sizeof(buf)) {
|
||||||
|
temp = realloc(line, line_len + sizeof(buf));
|
||||||
|
if (!temp)
|
||||||
|
goto err_out;
|
||||||
|
line = temp;
|
||||||
|
memcpy(&line[line_len], buf, sizeof(buf));
|
||||||
|
line_len += sizeof(buf);
|
||||||
|
buf_pos = 0;
|
||||||
|
}
|
||||||
|
buf[buf_pos++] = (char)ch;
|
||||||
|
}
|
||||||
|
temp = realloc(line, line_len + buf_pos + 1);
|
||||||
|
if (!temp)
|
||||||
|
goto err_out;
|
||||||
|
line = temp;
|
||||||
|
memcpy(&line[line_len], buf, buf_pos);
|
||||||
|
line[line_len + buf_pos] = '\0';
|
||||||
|
line_len += buf_pos;
|
||||||
|
*line_out = line;
|
||||||
|
*line_len_out = line_len;
|
||||||
|
return line_len;
|
||||||
|
err_out:
|
||||||
|
free(line);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __API_IO__ */
|
#endif /* __API_IO__ */
|
||||||
|
@ -289,6 +289,40 @@ static int test_get_dec(void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_get_line(void)
|
||||||
|
{
|
||||||
|
char path[PATH_MAX];
|
||||||
|
struct io io;
|
||||||
|
char test_string[1024];
|
||||||
|
char *line = NULL;
|
||||||
|
size_t i, line_len = 0;
|
||||||
|
size_t buf_size = 128;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 512; i++)
|
||||||
|
test_string[i] = 'a';
|
||||||
|
test_string[512] = '\n';
|
||||||
|
for (i = 513; i < 1023; i++)
|
||||||
|
test_string[i] = 'b';
|
||||||
|
test_string[1023] = '\0';
|
||||||
|
|
||||||
|
if (setup_test(path, test_string, buf_size, &io))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
EXPECT_EQUAL((int)io__getline(&io, &line, &line_len), 513);
|
||||||
|
EXPECT_EQUAL((int)strlen(line), 513);
|
||||||
|
for (i = 0; i < 512; i++)
|
||||||
|
EXPECT_EQUAL(line[i], 'a');
|
||||||
|
EXPECT_EQUAL(line[512], '\n');
|
||||||
|
EXPECT_EQUAL((int)io__getline(&io, &line, &line_len), 510);
|
||||||
|
for (i = 0; i < 510; i++)
|
||||||
|
EXPECT_EQUAL(line[i], 'b');
|
||||||
|
|
||||||
|
free(line);
|
||||||
|
cleanup_test(path, &io);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int test__api_io(struct test_suite *test __maybe_unused,
|
static int test__api_io(struct test_suite *test __maybe_unused,
|
||||||
int subtest __maybe_unused)
|
int subtest __maybe_unused)
|
||||||
{
|
{
|
||||||
@ -300,6 +334,8 @@ static int test__api_io(struct test_suite *test __maybe_unused,
|
|||||||
ret = TEST_FAIL;
|
ret = TEST_FAIL;
|
||||||
if (test_get_dec())
|
if (test_get_dec())
|
||||||
ret = TEST_FAIL;
|
ret = TEST_FAIL;
|
||||||
|
if (test_get_line())
|
||||||
|
ret = TEST_FAIL;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user