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.

> +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.

> +             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.

> +     }
> +
> +     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)
> +
> +     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.

> +     }
> +}
> +
> +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

-- 
Cyril Hrubis
chru...@suse.cz

------------------------------------------------------------------------------
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to