<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-size:small">Hi Meng,</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">I made some improvements work inline below and pushed.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Nov 4, 2021 at 7:26 AM tangmeng <<a href="mailto:tangmeng@uniontech.com" target="_blank">tangmeng@uniontech.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Signed-off-by: tangmeng <<a href="mailto:tangmeng@uniontech.com" target="_blank">tangmeng@uniontech.com</a>><br>
---<br>
 runtest/syscalls                        |   2 -<br>
 testcases/kernel/syscalls/link/link04.c | 208 +++++++++++-------------<br>
 testcases/kernel/syscalls/link/link06.c | 113 -------------<br>
 testcases/kernel/syscalls/link/link07.c | 118 --------------<br>
 4 files changed, 93 insertions(+), 348 deletions(-)<br>
 delete mode 100644 testcases/kernel/syscalls/link/link06.c<br>
 delete mode 100644 testcases/kernel/syscalls/link/link07.c<br>
<br>
diff --git a/runtest/syscalls b/runtest/syscalls<br>
index b19316805..1e6d46744 100644<br>
--- a/runtest/syscalls<br>
+++ b/runtest/syscalls<br>
@@ -673,8 +673,6 @@ link02 link02<br>
 link03 link03<br>
 link04 link04<br>
 link05 link05<br>
-link06 link06<br>
-link07 link07<br></blockquote><div><br></div><div><div class="gmail_default" style="font-size:small">And we should remove them from the .gitignore file as well.</div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
 link08 link08<br>
<br>
 #linkat test cases<br>
diff --git a/testcases/kernel/syscalls/link/link04.c b/testcases/kernel/syscalls/link/link04.c<br>
index d9408845e..9a1c32859 100644<br>
--- a/testcases/kernel/syscalls/link/link04.c<br>
+++ b/testcases/kernel/syscalls/link/link04.c<br>
@@ -1,65 +1,40 @@<br>
+// SPDX-License-Identifier: GPL-2.0-or-later<br>
 /*<br>
  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.<br>
  *  AUTHOR             : Richard Logan<br>
  *  CO-PILOT           : William Roske<br>
  * Copyright (c) 2014 Cyril Hrubis <<a href="mailto:chrubis@suse.cz" target="_blank">chrubis@suse.cz</a>><br>
- *<br>
- * This program is free software; you can redistribute it and/or modify it<br>
- * under the terms of version 2 of the GNU General Public License as<br>
- * published by the Free Software Foundation.<br>
- *<br>
- * This program is distributed in the hope that it would be useful, but<br>
- * WITHOUT ANY WARRANTY; without even the implied warranty of<br>
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.<br>
- *<br>
- * Further, this software is distributed without any warranty that it is<br>
- * free of the rightful claim of any third person regarding infringement<br>
- * or the like.  Any license provided herein, whether implied or<br>
- * otherwise, applies only to this software file.  Patent licenses, if<br>
- * any, provided herein do not apply to combinations of this program with<br>
- * other software, or any other product whatsoever.<br>
- *<br>
- * You should have received a copy of the GNU General Public License along<br>
- * with this program; if not, write the Free Software Foundation, Inc.,<br>
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.<br>
- *<br>
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,<br>
- * Mountain View, CA  94043, or:<br>
- *<br>
- * <a href="http://www.sgi.com" rel="noreferrer" target="_blank">http://www.sgi.com</a><br>
- *<br>
- * For further information regarding this notice, see:<br>
- *<br>
- * <a href="http://oss.sgi.com/projects/GenInfo/NoticeExplan/" rel="noreferrer" target="_blank">http://oss.sgi.com/projects/GenInfo/NoticeExplan/</a><br>
- *<br>
  */<br>
<br>
-/*<br>
+/*\<br>
+ * [Description]<br>
+ *<br>
  * Negative test cases for link(2).<br>
  *<br>
  * This test program should contain test cases where link will fail regardless<br>
  * of who executed it (i.e. joe-user or root)<br>
  */<br>
-#include <sys/types.h><br>
-#include <fcntl.h><br>
-#include <sys/stat.h><br>
-#include <errno.h><br>
-#include <string.h><br>
-#include <signal.h><br>
+#include <pwd.h><br>
 #include <sys/param.h><br>
 #include <sys/mman.h><br>
-#include "test.h"<br>
-#include "safe_macros.h"<br>
+#include "tst_test.h"<br>
+<br>
+#define NOBODY_USER     99<br>
+#define MODE_TO1 S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IXOTH|S_IROTH<br>
+#define MODE_TO2 S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IXOTH|S_IROTH|S_IWOTH<br>
+#define MODE_TE S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH<br>
+#define MODE_RWX        S_IRWXU | S_IRWXG | S_IRWXO<br>
+#define DIR_TEMP        "dir2/testdir_1"<br>
<br>
 static char longpath[PATH_MAX + 2];<br>
<br>
-struct test_case_t {<br>
+static struct tcase {<br>
        char *file1;<br>
        char *desc1;<br>
        char *file2;<br>
        char *desc2;<br>
        int exp_errno;<br>
-} test_cases[] = {<br>
+} tcases[] = {<br>
        /* first path is invalid */<br>
        {"nonexistfile", "non-existent file", "nefile", "nefile", ENOENT},<br>
        {"", "path is empty string", "nefile", "nefile", ENOENT},<br>
@@ -79,92 +54,95 @@ struct test_case_t {<br>
        {"regfile", "regfile", NULL, "invalid address", EFAULT},<br>
        /* two existing files */<br>
        {"regfile", "regfile", "regfile2", "regfile2", EEXIST},<br>
+       {"dir1/oldpath", "Write access diretory", "dir1/newpath", "newpath", EACCES},<br>
+       {"dir2/testdir_1/tfile_2", "Search access diretory", "dir2/testdir_1/new_tfile_2",<br>
+       "dir2/testdir_1/new_tfile_2", EACCES},<br></blockquote><div><br></div><div><div class="gmail_default" style="font-size:small">Reset the layout for more readable.</div></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
 };<br>
<br>
-char *TCID = "link04";<br>
-int TST_TOTAL = ARRAY_SIZE(test_cases);<br>
-<br>
-static void setup(void);<br>
-static void cleanup(void);<br>
-<br>
-int main(int ac, char **av)<br>
+static void verify_link(unsigned int i)<br>
 {<br>
-       int lc;<br>
-       char *fname1, *fname2;<br>
-       char *desc1, *desc2;<br>
-       int i;<br>
-<br>
-       tst_parse_opts(ac, av, NULL, NULL);<br>
-<br>
-       setup();<br>
-<br>
-       for (lc = 0; TEST_LOOPING(lc); lc++) {<br>
-<br>
-               tst_count = 0;<br>
-<br>
-               for (i = 0; i < TST_TOTAL; i++) {<br>
-<br>
-                       fname1 = test_cases[i].file1;<br>
-                       desc1 = test_cases[i].desc1;<br>
-                       fname2 = test_cases[i].file2;<br>
-                       desc2 = test_cases[i].desc2;<br>
-<br>
-                       TEST(link(fname1, fname2));<br>
-<br>
-                       if (TEST_RETURN == -1) {<br>
-                               if (TEST_ERRNO == test_cases[i].exp_errno) {<br>
-                                       tst_resm(TPASS | TTERRNO,<br>
-                                                "link(<%s>, <%s>)",<br>
-                                                desc1, desc2);<br>
-                               } else {<br>
-                                       tst_resm(TFAIL | TTERRNO,<br>
-                                                "link(<%s>, <%s>) Failed "<br>
-                                                "expected errno: %d",<br>
-                                                desc1, desc2,<br>
-                                                test_cases[i].exp_errno);<br>
-                               }<br>
-                       } else {<br>
-                               tst_resm(TFAIL,<br>
-                                        "link(<%s>, <%s>) returned %ld, "<br>
-                                        "expected -1, errno:%d",<br>
-                                        desc1, desc2, TEST_RETURN,<br>
-                                        test_cases[i].exp_errno);<br>
-                       }<br>
+       struct tcase *tc = &tcases[i];<br>
+<br>
+       TEST(link(tc->file1, tc->file2));<br>
+<br>
+       if (TST_RET == -1) {<br>
+               if (TST_ERR == tc->exp_errno) {<br>
+                       tst_res(TPASS | TTERRNO,<br>
+                       "link(<%s>, <%s>)",<br>
+                       tc->desc1, tc->desc2);<br>
+       } else {<br>
+               tst_res(TFAIL | TTERRNO,<br>
+                       "link(<%s>, <%s>) Failed "<br>
+                       "expected errno: %d",<br>
+                       tc->desc1, tc->desc2,<br>
+                       tc->exp_errno);<br>
                }<br>
-<br>
+       } else {<br>
+               tst_res(TFAIL,<br>
+                        "link(<%s>, <%s>) returned %ld, "<br>
+                       "expected -1, errno:%d",<br>
+                       tc->desc1, tc->desc2, TST_RET,<br>
+                       tc->exp_errno);<br>
        }<br>
-<br>
-       cleanup();<br>
-       tst_exit();<br>
 }<br>
<br>
 static void setup(void)<br>
 {<br>
-       int n;<br>
-<br>
-       tst_sig(NOFORK, DEF_HANDLER, cleanup);<br>
-<br>
-       TEST_PAUSE;<br>
-<br>
-       tst_tmpdir();<br>
-<br>
        memset(longpath, 'a', PATH_MAX+1);<br>
-       SAFE_TOUCH(cleanup, "regfile", 0777, NULL);<br>
-       SAFE_TOUCH(cleanup, "regfile2", 0777, NULL);<br>
-       SAFE_MKDIR(cleanup, "dir", 0777);<br>
-<br>
-       void *bad_addr = tst_get_bad_addr(cleanup);<br>
<br>
-       for (n = 0; n < TST_TOTAL; n++) {<br>
-               if (!test_cases[n].file1)<br>
-                       test_cases[n].file1 = bad_addr;<br>
-<br>
-               if (!test_cases[n].file2)<br>
-                       test_cases[n].file2 = bad_addr;<br>
+       SAFE_TOUCH("regfile", 0777, NULL);<br>
+       SAFE_TOUCH("regfile2", 0777, NULL);<br>
+       SAFE_MKDIR("dir", 0777);<br>
+<br>
+       unsigned int i;<br>
+       struct passwd *nobody_pwd;<br>
+<br>
+       for (i = 0; i < ARRAY_SIZE(tcases); i++) {<br>
+               struct tcase *tc = &tcases[i];<br>
+<br>
+               switch (tc->exp_errno) {<br>
+               case EACCES:<br>
+                       if (tc->desc1 == "Write access diretory") {<br></blockquote><div><br></div><div><div class="gmail_default" style="font-size:small">"==" is not a suggested way to compare strings in C programming.</div></div><div><div class="gmail_default" style="font-size:small">We should use strcmp() for instead.<br></div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+                               SAFE_SETEUID(0);<br>
+                               SAFE_MKDIR("dir1", MODE_RWX);<br>
+                               /* Modify mode permissions on test directory */<br>
+                               SAFE_CHMOD("dir1", MODE_TO1);<br>
+                               SAFE_TOUCH(tc->file1, 0777, NULL);<br>
+                               nobody_pwd = SAFE_GETPWNAM("nobody");<br>
+                               SAFE_SETEUID(nobody_pwd->pw_uid);<br>
+                       } else if (tc->desc1 == "Search access diretory") {<br>
+                               SAFE_SETEUID(0);<br>
+                               SAFE_MKDIR("dir2", MODE_RWX);<br>
+                               /* Modify mode permissions on test directory */<br>
+                               SAFE_CHMOD("dir2", MODE_TO2);<br>
+                               SAFE_MKDIR(DIR_TEMP, MODE_RWX);<br>
+                               SAFE_TOUCH(tc->file1, 0666, NULL);<br>
+<br>
+                               /* Modify mode permissions on test directory - test conditions */<br>
+                               SAFE_CHMOD(DIR_TEMP, MODE_TE);<br>
+                               nobody_pwd = SAFE_GETPWNAM("nobody");<br>
+                               SAFE_SETEUID(nobody_pwd->pw_uid);<br></blockquote><div><br></div><div><div class="gmail_default" style="font-size:small">I help reduce some duplicated code and move this part to the main thread.</div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+                       }<br>
+                       break;<br>
+               case ENOENT:<br>
+               case ENOTDIR:<br>
+               case ENAMETOOLONG:<br>
+               case EFAULT:<br>
+               case EEXIST:<br>
+                       if (!tc->file1)<br>
+                               tc->file1 = tst_get_bad_addr(NULL);<br>
+<br>
+                       if (!tc->file2)<br>
+                               tc->file2 = tst_get_bad_addr(NULL);<br>
+                       break;<br>
+               }<br>
        }<br>
 }<br>
<br>
-static void cleanup(void)<br>
-{<br>
-       tst_rmdir();<br>
-}<br>
+static struct tst_test test = {<br>
+       .tcnt = ARRAY_SIZE(tcases),<br>
+       .test = verify_link,<br>
+       .setup = setup,<br>
+       .needs_tmpdir = 1,<br>
+       .needs_root = 1,<br>
+};<br></blockquote></div><div><br></div>-- <br><div dir="ltr"><div dir="ltr"><div>Regards,<br></div><div>Li Wang<br></div></div></div></div>