1*57718be8SEnji Cooper /* $NetBSD: t_dup.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $ */ 2*57718be8SEnji Cooper 3*57718be8SEnji Cooper /*- 4*57718be8SEnji Cooper * Copyright (c) 2011 The NetBSD Foundation, Inc. 5*57718be8SEnji Cooper * All rights reserved. 6*57718be8SEnji Cooper * 7*57718be8SEnji Cooper * This code is derived from software contributed to The NetBSD Foundation 8*57718be8SEnji Cooper * by Jukka Ruohonen. 9*57718be8SEnji Cooper * 10*57718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 11*57718be8SEnji Cooper * modification, are permitted provided that the following conditions 12*57718be8SEnji Cooper * are met: 13*57718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 14*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer. 15*57718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 16*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the 17*57718be8SEnji Cooper * documentation and/or other materials provided with the distribution. 18*57718be8SEnji Cooper * 19*57718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20*57718be8SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21*57718be8SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22*57718be8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23*57718be8SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24*57718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25*57718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26*57718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27*57718be8SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28*57718be8SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29*57718be8SEnji Cooper * POSSIBILITY OF SUCH DAMAGE. 30*57718be8SEnji Cooper */ 31*57718be8SEnji Cooper #include <sys/cdefs.h> 32*57718be8SEnji Cooper __RCSID("$NetBSD: t_dup.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $"); 33*57718be8SEnji Cooper 34*57718be8SEnji Cooper #include <sys/resource.h> 35*57718be8SEnji Cooper #include <sys/stat.h> 36*57718be8SEnji Cooper #include <sys/wait.h> 37*57718be8SEnji Cooper 38*57718be8SEnji Cooper #include <atf-c.h> 39*57718be8SEnji Cooper #include <errno.h> 40*57718be8SEnji Cooper #include <fcntl.h> 41*57718be8SEnji Cooper #include <limits.h> 42*57718be8SEnji Cooper #include <stdio.h> 43*57718be8SEnji Cooper #include <stdlib.h> 44*57718be8SEnji Cooper #include <string.h> 45*57718be8SEnji Cooper #include <unistd.h> 46*57718be8SEnji Cooper #include <sysexits.h> 47*57718be8SEnji Cooper 48*57718be8SEnji Cooper static char path[] = "dup"; 49*57718be8SEnji Cooper static void check_mode(bool, bool, bool); 50*57718be8SEnji Cooper 51*57718be8SEnji Cooper static void 52*57718be8SEnji Cooper check_mode(bool _dup, bool _dup2, bool _dup3) 53*57718be8SEnji Cooper { 54*57718be8SEnji Cooper int mode[3] = { O_RDONLY, O_WRONLY, O_RDWR }; 55*57718be8SEnji Cooper int perm[5] = { 0700, 0400, 0600, 0444, 0666 }; 56*57718be8SEnji Cooper struct stat st, st1; 57*57718be8SEnji Cooper int fd, fd1, fd2; 58*57718be8SEnji Cooper size_t i, j; 59*57718be8SEnji Cooper 60*57718be8SEnji Cooper /* 61*57718be8SEnji Cooper * Check that a duplicated descriptor 62*57718be8SEnji Cooper * retains the mode of the original file. 63*57718be8SEnji Cooper */ 64*57718be8SEnji Cooper for (i = 0; i < __arraycount(mode); i++) { 65*57718be8SEnji Cooper 66*57718be8SEnji Cooper for (j = 0; j < __arraycount(perm); j++) { 67*57718be8SEnji Cooper 68*57718be8SEnji Cooper fd1 = open(path, mode[i] | O_CREAT, perm[j]); 69*57718be8SEnji Cooper fd2 = open("/etc/passwd", O_RDONLY); 70*57718be8SEnji Cooper 71*57718be8SEnji Cooper ATF_REQUIRE(fd1 >= 0); 72*57718be8SEnji Cooper ATF_REQUIRE(fd2 >= 0); 73*57718be8SEnji Cooper 74*57718be8SEnji Cooper if (_dup != false) 75*57718be8SEnji Cooper fd = dup(fd1); 76*57718be8SEnji Cooper else if (_dup2 != false) 77*57718be8SEnji Cooper fd = dup2(fd1, fd2); 78*57718be8SEnji Cooper else if (_dup3 != false) 79*57718be8SEnji Cooper fd = dup3(fd1, fd2, O_CLOEXEC); 80*57718be8SEnji Cooper else { 81*57718be8SEnji Cooper fd = -1; 82*57718be8SEnji Cooper } 83*57718be8SEnji Cooper 84*57718be8SEnji Cooper ATF_REQUIRE(fd >= 0); 85*57718be8SEnji Cooper 86*57718be8SEnji Cooper (void)memset(&st, 0, sizeof(struct stat)); 87*57718be8SEnji Cooper (void)memset(&st1, 0, sizeof(struct stat)); 88*57718be8SEnji Cooper 89*57718be8SEnji Cooper ATF_REQUIRE(fstat(fd, &st) == 0); 90*57718be8SEnji Cooper ATF_REQUIRE(fstat(fd1, &st1) == 0); 91*57718be8SEnji Cooper 92*57718be8SEnji Cooper if (st.st_mode != st1.st_mode) 93*57718be8SEnji Cooper atf_tc_fail("invalid mode"); 94*57718be8SEnji Cooper 95*57718be8SEnji Cooper (void)close(fd); 96*57718be8SEnji Cooper (void)close(fd1); 97*57718be8SEnji Cooper (void)close(fd2); 98*57718be8SEnji Cooper (void)unlink(path); 99*57718be8SEnji Cooper } 100*57718be8SEnji Cooper } 101*57718be8SEnji Cooper } 102*57718be8SEnji Cooper 103*57718be8SEnji Cooper ATF_TC(dup2_basic); 104*57718be8SEnji Cooper ATF_TC_HEAD(dup2_basic, tc) 105*57718be8SEnji Cooper { 106*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "A basic test of dup2(2)"); 107*57718be8SEnji Cooper } 108*57718be8SEnji Cooper 109*57718be8SEnji Cooper ATF_TC_BODY(dup2_basic, tc) 110*57718be8SEnji Cooper { 111*57718be8SEnji Cooper int fd, fd1, fd2; 112*57718be8SEnji Cooper 113*57718be8SEnji Cooper fd1 = open("/etc/passwd", O_RDONLY); 114*57718be8SEnji Cooper fd2 = open("/etc/passwd", O_RDONLY); 115*57718be8SEnji Cooper 116*57718be8SEnji Cooper ATF_REQUIRE(fd1 >= 0); 117*57718be8SEnji Cooper ATF_REQUIRE(fd2 >= 0); 118*57718be8SEnji Cooper 119*57718be8SEnji Cooper fd = dup2(fd1, fd2); 120*57718be8SEnji Cooper ATF_REQUIRE(fd >= 0); 121*57718be8SEnji Cooper 122*57718be8SEnji Cooper if (fd != fd2) 123*57718be8SEnji Cooper atf_tc_fail("invalid descriptor"); 124*57718be8SEnji Cooper 125*57718be8SEnji Cooper (void)close(fd); 126*57718be8SEnji Cooper (void)close(fd1); 127*57718be8SEnji Cooper 128*57718be8SEnji Cooper ATF_REQUIRE(close(fd2) != 0); 129*57718be8SEnji Cooper } 130*57718be8SEnji Cooper 131*57718be8SEnji Cooper ATF_TC(dup2_err); 132*57718be8SEnji Cooper ATF_TC_HEAD(dup2_err, tc) 133*57718be8SEnji Cooper { 134*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test error conditions of dup2(2)"); 135*57718be8SEnji Cooper } 136*57718be8SEnji Cooper 137*57718be8SEnji Cooper ATF_TC_BODY(dup2_err, tc) 138*57718be8SEnji Cooper { 139*57718be8SEnji Cooper int fd; 140*57718be8SEnji Cooper 141*57718be8SEnji Cooper fd = open("/etc/passwd", O_RDONLY); 142*57718be8SEnji Cooper ATF_REQUIRE(fd >= 0); 143*57718be8SEnji Cooper 144*57718be8SEnji Cooper errno = 0; 145*57718be8SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, dup2(-1, -1) == -1); 146*57718be8SEnji Cooper 147*57718be8SEnji Cooper errno = 0; 148*57718be8SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, dup2(fd, -1) == -1); 149*57718be8SEnji Cooper 150*57718be8SEnji Cooper errno = 0; 151*57718be8SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, dup2(-1, fd) == -1); 152*57718be8SEnji Cooper 153*57718be8SEnji Cooper /* 154*57718be8SEnji Cooper * Note that this should not fail with EINVAL. 155*57718be8SEnji Cooper */ 156*57718be8SEnji Cooper ATF_REQUIRE(dup2(fd, fd) != -1); 157*57718be8SEnji Cooper 158*57718be8SEnji Cooper (void)close(fd); 159*57718be8SEnji Cooper } 160*57718be8SEnji Cooper 161*57718be8SEnji Cooper ATF_TC(dup2_max); 162*57718be8SEnji Cooper ATF_TC_HEAD(dup2_max, tc) 163*57718be8SEnji Cooper { 164*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test dup2(2) against limits"); 165*57718be8SEnji Cooper } 166*57718be8SEnji Cooper 167*57718be8SEnji Cooper ATF_TC_BODY(dup2_max, tc) 168*57718be8SEnji Cooper { 169*57718be8SEnji Cooper struct rlimit res; 170*57718be8SEnji Cooper 171*57718be8SEnji Cooper (void)memset(&res, 0, sizeof(struct rlimit)); 172*57718be8SEnji Cooper (void)getrlimit(RLIMIT_NOFILE, &res); 173*57718be8SEnji Cooper 174*57718be8SEnji Cooper errno = 0; 175*57718be8SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, dup2(STDERR_FILENO, res.rlim_cur + 1) == -1); 176*57718be8SEnji Cooper } 177*57718be8SEnji Cooper 178*57718be8SEnji Cooper ATF_TC_WITH_CLEANUP(dup2_mode); 179*57718be8SEnji Cooper ATF_TC_HEAD(dup2_mode, tc) 180*57718be8SEnji Cooper { 181*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "A basic test of dup2(2)"); 182*57718be8SEnji Cooper } 183*57718be8SEnji Cooper 184*57718be8SEnji Cooper ATF_TC_BODY(dup2_mode, tc) 185*57718be8SEnji Cooper { 186*57718be8SEnji Cooper check_mode(false, true, false); 187*57718be8SEnji Cooper } 188*57718be8SEnji Cooper 189*57718be8SEnji Cooper ATF_TC_CLEANUP(dup2_mode, tc) 190*57718be8SEnji Cooper { 191*57718be8SEnji Cooper (void)unlink(path); 192*57718be8SEnji Cooper } 193*57718be8SEnji Cooper 194*57718be8SEnji Cooper 195*57718be8SEnji Cooper ATF_TC(dup3_err); 196*57718be8SEnji Cooper ATF_TC_HEAD(dup3_err, tc) 197*57718be8SEnji Cooper { 198*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", 199*57718be8SEnji Cooper "Test error conditions of dup3(2) (PR lib/45148)"); 200*57718be8SEnji Cooper } 201*57718be8SEnji Cooper 202*57718be8SEnji Cooper ATF_TC_BODY(dup3_err, tc) 203*57718be8SEnji Cooper { 204*57718be8SEnji Cooper int fd; 205*57718be8SEnji Cooper 206*57718be8SEnji Cooper fd = open("/etc/passwd", O_RDONLY); 207*57718be8SEnji Cooper ATF_REQUIRE(fd >= 0); 208*57718be8SEnji Cooper 209*57718be8SEnji Cooper errno = 0; 210*57718be8SEnji Cooper ATF_REQUIRE(dup3(fd, fd, O_CLOEXEC) != -1); 211*57718be8SEnji Cooper 212*57718be8SEnji Cooper errno = 0; 213*57718be8SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, dup3(-1, -1, O_CLOEXEC) == -1); 214*57718be8SEnji Cooper 215*57718be8SEnji Cooper errno = 0; 216*57718be8SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, dup3(fd, -1, O_CLOEXEC) == -1); 217*57718be8SEnji Cooper 218*57718be8SEnji Cooper errno = 0; 219*57718be8SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, dup3(-1, fd, O_CLOEXEC) == -1); 220*57718be8SEnji Cooper 221*57718be8SEnji Cooper errno = 0; 222*57718be8SEnji Cooper ATF_REQUIRE_ERRNO(EINVAL, dup3(fd, 1, O_NOFOLLOW) == -1); 223*57718be8SEnji Cooper 224*57718be8SEnji Cooper (void)close(fd); 225*57718be8SEnji Cooper } 226*57718be8SEnji Cooper 227*57718be8SEnji Cooper ATF_TC(dup3_max); 228*57718be8SEnji Cooper ATF_TC_HEAD(dup3_max, tc) 229*57718be8SEnji Cooper { 230*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test dup3(2) against limits"); 231*57718be8SEnji Cooper } 232*57718be8SEnji Cooper 233*57718be8SEnji Cooper ATF_TC_BODY(dup3_max, tc) 234*57718be8SEnji Cooper { 235*57718be8SEnji Cooper struct rlimit res; 236*57718be8SEnji Cooper 237*57718be8SEnji Cooper (void)memset(&res, 0, sizeof(struct rlimit)); 238*57718be8SEnji Cooper (void)getrlimit(RLIMIT_NOFILE, &res); 239*57718be8SEnji Cooper 240*57718be8SEnji Cooper errno = 0; 241*57718be8SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, dup3(STDERR_FILENO, 242*57718be8SEnji Cooper res.rlim_cur + 1, O_CLOEXEC) == -1); 243*57718be8SEnji Cooper } 244*57718be8SEnji Cooper 245*57718be8SEnji Cooper ATF_TC_WITH_CLEANUP(dup3_mode); 246*57718be8SEnji Cooper ATF_TC_HEAD(dup3_mode, tc) 247*57718be8SEnji Cooper { 248*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "A basic test of dup3(2)"); 249*57718be8SEnji Cooper } 250*57718be8SEnji Cooper 251*57718be8SEnji Cooper ATF_TC_BODY(dup3_mode, tc) 252*57718be8SEnji Cooper { 253*57718be8SEnji Cooper check_mode(false, false, true); 254*57718be8SEnji Cooper } 255*57718be8SEnji Cooper 256*57718be8SEnji Cooper ATF_TC_CLEANUP(dup3_mode, tc) 257*57718be8SEnji Cooper { 258*57718be8SEnji Cooper (void)unlink(path); 259*57718be8SEnji Cooper } 260*57718be8SEnji Cooper 261*57718be8SEnji Cooper ATF_TC(dup_err); 262*57718be8SEnji Cooper ATF_TC_HEAD(dup_err, tc) 263*57718be8SEnji Cooper { 264*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test error conditions of dup(2)"); 265*57718be8SEnji Cooper } 266*57718be8SEnji Cooper 267*57718be8SEnji Cooper ATF_TC_BODY(dup_err, tc) 268*57718be8SEnji Cooper { 269*57718be8SEnji Cooper 270*57718be8SEnji Cooper errno = 0; 271*57718be8SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, dup(-1) == -1); 272*57718be8SEnji Cooper } 273*57718be8SEnji Cooper 274*57718be8SEnji Cooper ATF_TC_WITH_CLEANUP(dup_max); 275*57718be8SEnji Cooper ATF_TC_HEAD(dup_max, tc) 276*57718be8SEnji Cooper { 277*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test dup(2) against limits"); 278*57718be8SEnji Cooper } 279*57718be8SEnji Cooper 280*57718be8SEnji Cooper ATF_TC_BODY(dup_max, tc) 281*57718be8SEnji Cooper { 282*57718be8SEnji Cooper struct rlimit res; 283*57718be8SEnji Cooper int *buf, fd, sta; 284*57718be8SEnji Cooper size_t i, n; 285*57718be8SEnji Cooper pid_t pid; 286*57718be8SEnji Cooper 287*57718be8SEnji Cooper pid = fork(); 288*57718be8SEnji Cooper ATF_REQUIRE(pid >= 0); 289*57718be8SEnji Cooper 290*57718be8SEnji Cooper if (pid == 0) { 291*57718be8SEnji Cooper 292*57718be8SEnji Cooper /* 293*57718be8SEnji Cooper * Open a temporary file until the 294*57718be8SEnji Cooper * maximum number of open files is 295*57718be8SEnji Cooper * reached. Ater that dup(2) family 296*57718be8SEnji Cooper * should fail with EMFILE. 297*57718be8SEnji Cooper */ 298*57718be8SEnji Cooper (void)closefrom(0); 299*57718be8SEnji Cooper (void)memset(&res, 0, sizeof(struct rlimit)); 300*57718be8SEnji Cooper 301*57718be8SEnji Cooper n = 10; 302*57718be8SEnji Cooper res.rlim_cur = res.rlim_max = n; 303*57718be8SEnji Cooper if (setrlimit(RLIMIT_NOFILE, &res) != 0) 304*57718be8SEnji Cooper _exit(EX_OSERR); 305*57718be8SEnji Cooper 306*57718be8SEnji Cooper buf = calloc(n, sizeof(int)); 307*57718be8SEnji Cooper 308*57718be8SEnji Cooper if (buf == NULL) 309*57718be8SEnji Cooper _exit(EX_OSERR); 310*57718be8SEnji Cooper 311*57718be8SEnji Cooper buf[0] = mkstemp(path); 312*57718be8SEnji Cooper 313*57718be8SEnji Cooper if (buf[0] < 0) 314*57718be8SEnji Cooper _exit(EX_OSERR); 315*57718be8SEnji Cooper 316*57718be8SEnji Cooper for (i = 1; i < n; i++) { 317*57718be8SEnji Cooper 318*57718be8SEnji Cooper buf[i] = open(path, O_RDONLY); 319*57718be8SEnji Cooper 320*57718be8SEnji Cooper if (buf[i] < 0) 321*57718be8SEnji Cooper _exit(EX_OSERR); 322*57718be8SEnji Cooper } 323*57718be8SEnji Cooper 324*57718be8SEnji Cooper errno = 0; 325*57718be8SEnji Cooper fd = dup(buf[0]); 326*57718be8SEnji Cooper 327*57718be8SEnji Cooper if (fd != -1 || errno != EMFILE) 328*57718be8SEnji Cooper _exit(EX_DATAERR); 329*57718be8SEnji Cooper 330*57718be8SEnji Cooper _exit(EXIT_SUCCESS); 331*57718be8SEnji Cooper } 332*57718be8SEnji Cooper 333*57718be8SEnji Cooper (void)wait(&sta); 334*57718be8SEnji Cooper 335*57718be8SEnji Cooper if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) { 336*57718be8SEnji Cooper 337*57718be8SEnji Cooper if (WEXITSTATUS(sta) == EX_OSERR) 338*57718be8SEnji Cooper atf_tc_fail("system call error"); 339*57718be8SEnji Cooper 340*57718be8SEnji Cooper if (WEXITSTATUS(sta) == EX_DATAERR) 341*57718be8SEnji Cooper atf_tc_fail("dup(2) dupped more than RLIMIT_NOFILE"); 342*57718be8SEnji Cooper 343*57718be8SEnji Cooper atf_tc_fail("unknown error"); 344*57718be8SEnji Cooper } 345*57718be8SEnji Cooper 346*57718be8SEnji Cooper (void)unlink(path); 347*57718be8SEnji Cooper } 348*57718be8SEnji Cooper 349*57718be8SEnji Cooper ATF_TC_CLEANUP(dup_max, tc) 350*57718be8SEnji Cooper { 351*57718be8SEnji Cooper (void)unlink(path); 352*57718be8SEnji Cooper } 353*57718be8SEnji Cooper 354*57718be8SEnji Cooper ATF_TC_WITH_CLEANUP(dup_mode); 355*57718be8SEnji Cooper ATF_TC_HEAD(dup_mode, tc) 356*57718be8SEnji Cooper { 357*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "A basic test of dup(2)"); 358*57718be8SEnji Cooper } 359*57718be8SEnji Cooper 360*57718be8SEnji Cooper ATF_TC_BODY(dup_mode, tc) 361*57718be8SEnji Cooper { 362*57718be8SEnji Cooper check_mode(true, false, false); 363*57718be8SEnji Cooper } 364*57718be8SEnji Cooper 365*57718be8SEnji Cooper ATF_TC_CLEANUP(dup_mode, tc) 366*57718be8SEnji Cooper { 367*57718be8SEnji Cooper (void)unlink(path); 368*57718be8SEnji Cooper } 369*57718be8SEnji Cooper 370*57718be8SEnji Cooper ATF_TP_ADD_TCS(tp) 371*57718be8SEnji Cooper { 372*57718be8SEnji Cooper 373*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, dup2_basic); 374*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, dup2_err); 375*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, dup2_max); 376*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, dup2_mode); 377*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, dup3_err); 378*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, dup3_max); 379*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, dup3_mode); 380*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, dup_err); 381*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, dup_max); 382*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, dup_mode); 383*57718be8SEnji Cooper 384*57718be8SEnji Cooper return atf_no_error(); 385*57718be8SEnji Cooper } 386