TRERRNO outputs errno information stored in TEST_RETURN. For example, this can be used for pthread-style API, where functions do not set errno on error, but return error code directly.
Signed-off-by: Jan Stancek <jstan...@redhat.com> --- .gitignore | 1 + include/tst_res_flags.h | 2 +- lib/tests/trerrno.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++ lib/tst_res.c | 12 ++++++ 4 files changed, 105 insertions(+), 1 deletions(-) create mode 100644 lib/tests/trerrno.c diff --git a/.gitignore b/.gitignore index 352ca23..1256236 100644 --- a/.gitignore +++ b/.gitignore @@ -67,3 +67,4 @@ logfile.* /lib/tests/tst_fs_fill_hardlinks /lib/tests/tst_device /lib/tests/tst_record_childstatus +/lib/tests/trerrno diff --git a/include/tst_res_flags.h b/include/tst_res_flags.h index 1f3d06d..b79d69a 100644 --- a/include/tst_res_flags.h +++ b/include/tst_res_flags.h @@ -23,7 +23,7 @@ #define TERRNO 0x100 /* Append errno information to output */ #define TTERRNO 0x200 /* Append TEST_ERRNO information to output */ -#define TRERRNO 0x300 /* Capture errno information from TEST_RETURN to +#define TRERRNO 0x400 /* Capture errno information from TEST_RETURN to output; useful for pthread-like APIs :). */ #endif /* TST_RES_FLAGS_H */ diff --git a/lib/tests/trerrno.c b/lib/tests/trerrno.c new file mode 100644 index 0000000..0c72328 --- /dev/null +++ b/lib/tests/trerrno.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2014 Linux Test Project, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + */ + +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include "test.h" +#include "safe_macros.h" +#include "usctest.h" + +#define OUTPUT_FNAME "output" + +char *TCID = "trerrno"; +int TST_TOTAL = 1; + +static void setup(void) +{ + tst_tmpdir(); +} + +static void cleanup(void) +{ + tst_rmdir(); +} + +int main(void) +{ + int fd, stdout_fd; + char msg[4096], *pos; + FILE *f; + + setup(); + + /* redirect stdout to file */ + stdout_fd = dup(fileno(stdout)); + fd = SAFE_OPEN(NULL, OUTPUT_FNAME, O_RDWR | O_CREAT, 0666); + TEST(dup2(fd, fileno(stdout))); + if (TEST_RETURN == -1) + tst_brkm(TBROK | TTERRNO, cleanup, "dup2"); + + errno = EPERM; + TEST_ERRNO = EPERM; + TEST_RETURN = EINVAL; + tst_resm(TINFO | TRERRNO, "test"); + tst_flush(); + + /* restore stdout */ + TEST(dup2(stdout_fd, fileno(stdout))); + if (TEST_RETURN == -1) + tst_brkm(TBROK | TTERRNO, cleanup, "dup2"); + + /* read file and verify that output is as expected */ + SAFE_LSEEK(cleanup, fd, 0, SEEK_SET); + f = fdopen(fd, "r"); + if (!f) + tst_brkm(TBROK | TERRNO, cleanup, "fdopen"); + if (!fgets(msg, sizeof(msg), f)) + tst_brkm(TBROK, cleanup, "fgets"); + fclose(f); + + pos = strchr(msg, '\n'); + if (pos != NULL) + *pos = '\0'; + + tst_resm(TINFO, "%s", msg); + if (strstr(msg, "EPERM")) + tst_resm(TFAIL, "EPERM shouldn't be in TRERRNO output"); + if (strstr(msg, "EINVAL")) + tst_resm(TPASS, "EINVAL should be in TRERRNO output"); + else + tst_resm(TFAIL, "EINVAL not found in TRERRNO output"); + + cleanup(); + tst_exit(); +} diff --git a/lib/tst_res.c b/lib/tst_res.c index 569bfe2..7619ea2 100644 --- a/lib/tst_res.c +++ b/lib/tst_res.c @@ -456,6 +456,18 @@ static void tst_print(const char *tcid, int tnum, int ttype, const char *tmesg) strerror(TEST_ERRNO)); } + if (size >= sizeof(message)) { + printf("%s: %i: line too long\n", __func__, __LINE__); + abort(); + } + + if (ttype & TRERRNO) { + size += snprintf(message + size, sizeof(message) - size, + ": TEST_RETURN=%s(%i): %s", + tst_strerrno(TEST_RETURN), (int)TEST_RETURN, + strerror(TEST_RETURN)); + } + if (size + 1 >= sizeof(message)) { printf("%s: %i: line too long\n", __func__, __LINE__); abort(); -- 1.7.1 ------------------------------------------------------------------------------ Want excitement? Manually upgrade your production database. When you want reliability, choose Perforce Perforce version control. Predictably reliable. http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk _______________________________________________ Ltp-list mailing list Ltp-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ltp-list