Hi! Thank you for your reply!
On 2015/07/30 21:32, Cyril Hrubis wrote: > Hi! >> +/* >> + * Copyright (c) 2015 Fujitsu Ltd. >> + * Author: Guangwen Feng <fenggw-f...@cn.fujitsu.com> >> + * >> + * 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. >> + * >> + * You should have received a copy of the GNU General Public License along >> + * with this program. >> + */ >> + >> +/* >> + * DESCRIPTION >> + * Basic test for open(2) with the flag O_PATH. >> + * "Obtain a file descriptor that can be used to perform operations >> + * that act purely at the file descriptor level, the file itself is >> + * not opened, the operations read(2), write(2), fchmod(2), fchown(2) >> + * and fgetxattr(2) fail with the error EBADF." >> + * >> + * The operations include but is not limited to the syscalls above. >> + */ >> + >> +#define _GNU_SOURCE >> + >> +#include "config.h" >> + >> +#include <errno.h> >> +#ifdef HAVE_ATTR_XATTR_H >> +#include <sys/types.h> >> +#include <attr/xattr.h> >> +#endif >> + >> +#include "test.h" >> +#include "safe_macros.h" >> +#include "lapi/fcntl.h" >> + >> +#define TESTFILE "testfile" >> +#define FILE_MODE (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID) >> +#define EXP_ERRNO EBADF > > Defining the EXP_ERRNO as EBADF only hides what the expected error is > and it's not like the expected errno for the testcases will ever change. > So it's better to just hardcode the EBADFD there and keep the code nice > and readable. > OK, I got it, thanks. >> +static void setup(void); >> +static void verify_read(void); >> +static void verify_write(void); >> +static void verify_fchmod(void); >> +static void verify_fchown(void); >> +#ifdef HAVE_ATTR_XATTR_H >> +static void verify_fgetxattr(void); >> +#endif >> +static void cleanup(void); >> + >> +static int fd; >> + >> +static void (*test_func[])(void) = { >> + verify_read, >> + verify_write, >> + verify_fchmod, >> + verify_fchown, >> +#ifdef HAVE_ATTR_XATTR_H >> + verify_fgetxattr >> +#endif >> +}; >> + >> +char *TCID = "open13"; >> +int TST_TOTAL = ARRAY_SIZE(test_func); >> + >> +int main(int ac, char **av) >> +{ >> + int lc; >> + int tc; >> + >> + tst_parse_opts(ac, av, NULL, NULL); >> + >> + setup(); >> + >> + for (lc = 0; TEST_LOOPING(lc); lc++) { >> + tst_count = 0; >> + >> + TEST(open(TESTFILE, O_RDWR | O_PATH)); >> + if (TEST_RETURN == -1) { >> + tst_resm(TFAIL | TTERRNO, "open(2) failed"); >> + continue; >> + } >> + >> + fd = TEST_RETURN; > > Just do fd = SAFE_OPEN(TESTFILE, O_CREAT | O_RDWR | O_PATH); instead and > drop the SAFE_TOUCH() from the setup as well. > When O_PATH is specified in flags, flag bits other than O_DIRECTORY and O_NOFOLLOW are ignored. So, I think I have to do SAFE_TOUCH() in setup. >> + for (tc = 0; tc < TST_TOTAL; tc++) >> + (*test_func[tc])(); > > You have to close the fd here, otherwise the loop will leak fds with -i > or -I test parameters. > My neglect here, understand, thanks! >> + } >> + >> + cleanup(); >> + tst_exit(); >> +} >> + >> +static void setup(void) >> +{ >> + if ((tst_kvercmp(2, 6, 39)) < 0) { >> + tst_brkm(TCONF, NULL, "This test can only run on kernels " >> + "that are 2.6.39 or higher"); >> + } >> + >> + tst_sig(NOFORK, DEF_HANDLER, cleanup); >> + >> + tst_tmpdir(); >> + >> + SAFE_TOUCH(cleanup, TESTFILE, FILE_MODE, NULL); >> + >> + TEST_PAUSE; >> +} >> + >> +static void verify_read(void) >> +{ >> + char buf[255]; >> + >> + TEST(read(fd, buf, 255)); > ^ > sizeof(buf) OK. >> + >> + if (TEST_RETURN == -1 && TEST_ERRNO == EXP_ERRNO) { >> + tst_resm(TPASS, "read(2) failed as expected"); >> + } else { >> + tst_resm(TFAIL, "open(2) O_PATH flag " >> + "performed abnormally " >> + "expected error = %d : %s", >> + EXP_ERRNO, strerror(EXP_ERRNO)); > > This does not say what errno we actuall got or if > the call has succeded. Given that these all are > negative testcases we can define check result > functions as: > > static void check_result(const char *call_name) > { > if (TEST_RETURN == 0) { > tst_resm(TFAIL, "%s succeeded unexpectedly", call_name); > return; > } > > if (TEST_ERRNO != EBADF) { > tst_resm(TFAIL | TTERRNO, "%s failed unexpectedly, " > "expected EBADF", call_name); > return; > } > > tst_resm(TPASS, "%s failed with EBADF", call_name); > } > > And call it in all the test functions. > OK, I got it, thanks! Best Regards, Guangwen Feng >> + } >> +} >> + >> +static void verify_write(void) >> +{ >> + TEST(write(fd, "w", 1)); >> + >> + if (TEST_RETURN == -1 && TEST_ERRNO == EXP_ERRNO) { >> + tst_resm(TPASS, "write(2) failed as expected"); >> + } else { >> + tst_resm(TFAIL, "open(2) O_PATH flag " >> + "performed abnormally " >> + "expected error = %d : %s", >> + EXP_ERRNO, strerror(EXP_ERRNO)); >> + } >> +} >> + >> +static void verify_fchmod(void) >> +{ >> + TEST(fchmod(fd, 0666)); >> + >> + if (TEST_RETURN == -1 && TEST_ERRNO == EXP_ERRNO) { >> + tst_resm(TPASS, "fchmod(2) failed as expected"); >> + } else { >> + tst_resm(TFAIL, "open(2) O_PATH flag " >> + "performed abnormally " >> + "expected error = %d : %s", >> + EXP_ERRNO, strerror(EXP_ERRNO)); >> + } >> +} >> + >> +static void verify_fchown(void) >> +{ >> + uid_t tuid = 1000; >> + gid_t tgid = 1000; >> + >> + TEST(fchown(fd, tuid, tgid)); >> + >> + if (TEST_RETURN == -1 && TEST_ERRNO == EXP_ERRNO) { >> + tst_resm(TPASS, "fchown(2) failed as expected"); >> + } else { >> + tst_resm(TFAIL, "open(2) O_PATH flag " >> + "performed abnormally " >> + "expected error = %d : %s", >> + EXP_ERRNO, strerror(EXP_ERRNO)); >> + } >> +} >> + >> +#ifdef HAVE_ATTR_XATTR_H >> +static void verify_fgetxattr(void) >> +{ >> + TEST(fgetxattr(fd, "tkey", NULL, 1)); >> + >> + if (TEST_RETURN == -1 && TEST_ERRNO == EXP_ERRNO) { >> + tst_resm(TPASS, "fgetxattr(2) failed as expected"); >> + } else { >> + tst_resm(TFAIL, "open(2) O_PATH flag " >> + "performed abnormally " >> + "expected error = %d : %s", >> + EXP_ERRNO, strerror(EXP_ERRNO)); >> + } >> +} >> +#endif >> + >> +static void cleanup(void) >> +{ >> + if (fd > 0 && close(fd)) >> + tst_resm(TWARN | TERRNO, "failed to close file"); >> + >> + tst_rmdir(); >> +} >> -- >> 1.8.4.2 >> >> >> ------------------------------------------------------------------------------ >> _______________________________________________ >> Ltp-list mailing list >> Ltp-list@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/ltp-list > ------------------------------------------------------------------------------ _______________________________________________ Ltp-list mailing list Ltp-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ltp-list