<div dir="ltr">Hi Randy,<div><br></div><div>Thanks for the patches, I pushed this one to master, I will review the clang warning patches.</div><div><br></div><div>Cheers,</div><div>Anibal</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 17 Jul 2019 at 13:35, Randy MacLeod <<a href="mailto:Randy.MacLeod@windriver.com">Randy.MacLeod@windriver.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">When running the run-execscript bash ptest as a user rather than root, a warning:<br>
 bash: cannot set terminal process group (16036): Inappropriate ioctl for device<br>
 bash: no job control in this shell<br>
contaminates the bash log files causing the test to fail. This happens only<br>
when run under ptest-runner and not when interactively testing!<br>
<br>
The changes made to fix this include:<br>
1. Get the process group id (pgid) before forking,<br>
2. Set the pgid in both the parent and child to avoid a race,<br>
3. Find, open and set permission on the child tty, and<br>
4. Allow the child to attach to controlling tty.<br>
<br>
Also add '-lutil' to Makefile. This lib is from libc and provides openpty.<br>
<br>
Upstream-Status: Submitted [<a href="mailto:yocto@yoctoproject.org" target="_blank">yocto@yoctoproject.org</a>]<br>
<br>
Signed-off-by: Sakib Sajal <<a href="mailto:sakib.sajal@windriver.com" target="_blank">sakib.sajal@windriver.com</a>><br>
Signed-off-by: Randy MacLeod <<a href="mailto:Randy.MacLeod@windriver.com" target="_blank">Randy.MacLeod@windriver.com</a>><br>
---<br>
 Makefile |  2 +-<br>
 utils.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++------<br>
 2 files changed, 92 insertions(+), 12 deletions(-)<br>
<br>
diff --git a/Makefile b/Makefile<br>
index 1bde7be..439eb79 100644<br>
--- a/Makefile<br>
+++ b/Makefile<br>
@@ -29,7 +29,7 @@ TEST_DATA=$(shell echo `pwd`/tests/data)<br>
 all: $(SOURCES) $(EXECUTABLE)<br>
<br>
 $(EXECUTABLE): $(OBJECTS)<br>
-Â Â Â Â $(CC) $(LDFLAGS) $(OBJECTS) -o $@<br>
+Â Â Â Â $(CC) $(LDFLAGS) $(OBJECTS) -lutil -o $@<br>
<br>
 tests: $(TEST_SOURCES) $(TEST_EXECUTABLE)<br>
<br>
diff --git a/utils.c b/utils.c<br>
index ad737c2..f11ce39 100644<br>
--- a/utils.c<br>
+++ b/utils.c<br>
@@ -1,5 +1,6 @@<br>
 /**<br>
 * Copyright (c) 2016 Intel Corporation<br>
+ * Copyright (C) 2019 Wind River Systems, Inc.<br>
 *<br>
 * This program is free software; you can redistribute it and/or<br>
 * modify it under the terms of the GNU General Public License<br>
@@ -22,23 +23,27 @@<br>
 */<br>
<br>
 #define _GNU_SOURCE <br>
+<br>
 #include <stdio.h><br>
<br>
+#include <dirent.h><br>
+#include <errno.h><br>
+#include <fcntl.h><br>
+#include <grp.h><br>
 #include <libgen.h><br>
-#include <signal.h><br>
 #include <poll.h><br>
-#include <fcntl.h><br>
+#include <pty.h><br>
+#include <signal.h><br>
+#include <stdlib.h><br>
+#include <string.h><br>
 #include <time.h><br>
-#include <dirent.h><br>
+#include <unistd.h><br>
+<br>
+#include <sys/ioctl.h><br>
 #include <sys/resource.h><br>
+#include <sys/stat.h><br>
 #include <sys/types.h><br>
 #include <sys/wait.h><br>
-#include <sys/stat.h><br>
-#include <unistd.h><br>
-#include <string.h><br>
-#include <stdlib.h><br>
-<br>
-#include <errno.h><br>
<br>
 #include "ptest_list.h"<br>
 #include "utils.h"<br>
@@ -346,6 +351,53 @@ wait_child(const char *ptest_dir, const char *run_ptest, pid_t pid,<br>
    return status;<br>
 }<br>
<br>
+/* Returns an integer file descriptor.<br>
+ * If it returns < 0, an error has occurred.<br>
+ * Otherwise, it has returned the slave pty file descriptor.<br>
+ * fp should be writable, likely stdout/err.<br>
+ */<br>
+static int<br>
+setup_slave_pty(FILE *fp) { <br>
+Â Â Â Â int pty_master = -1;<br>
+Â Â Â Â int pty_slave = -1;<br>
+Â Â Â Â char pty_name[256];<br>
+Â Â Â Â struct group *gptr;<br>
+Â Â Â Â gid_t gid;<br>
+Â Â Â Â int slave = -1;<br>
+<br>
+Â Â Â Â if (openpty(&pty_master, &pty_slave, pty_name, NULL, NULL) < 0) {<br>
+Â Â Â Â Â Â Â Â fprintf(fp, "ERROR: openpty() failed with: %s.\n", strerror(errno));<br>
+Â Â Â Â Â Â Â Â return -1;<br>
+Â Â Â Â }<br>
+<br>
+Â Â Â Â if ((gptr = getgrnam(pty_name)) != 0) {<br>
+Â Â Â Â Â Â Â Â gid = gptr->gr_gid;<br>
+Â Â Â Â } else {<br>
+Â Â Â Â Â Â Â Â /* If the tty group does not exist, don't change the<br>
+Â Â Â Â Â Â Â Â * group on the slave pty, only the owner<br>
+Â Â Â Â Â Â Â Â */<br>
+Â Â Â Â Â Â Â Â gid = -1;<br>
+Â Â Â Â }<br>
+<br>
+Â Â Â Â /* chown/chmod the corresponding pty, if possible.<br>
+Â Â Â Â * This will only work if the process has root permissions.<br>
+Â Â Â Â */<br>
+Â Â Â Â if (chown(pty_name, getuid(), gid) != 0) {<br>
+Â Â Â Â Â Â Â Â fprintf(fp, "ERROR; chown() failed with: %s.\n", strerror(errno));<br>
+Â Â Â Â }<br>
+<br>
+Â Â Â Â /* Makes the slave read/writeable for the user. */<br>
+Â Â Â Â if (chmod(pty_name, S_IRUSR|S_IWUSR) != 0) {<br>
+Â Â Â Â Â Â Â Â fprintf(fp, "ERROR: chmod() failed with: %s.\n", strerror(errno));<br>
+Â Â Â Â }<br>
+<br>
+Â Â Â Â if ((slave = open(pty_name, O_RDWR)) == -1) {<br>
+Â Â Â Â Â Â Â Â fprintf(fp, "ERROR: open() failed with: %s.\n", strerror(errno));<br>
+Â Â Â Â }<br>
+Â Â Â Â return (slave);<br>
+}<br>
+<br>
+<br>
 int<br>
 run_ptests(struct ptest_list *head, const struct ptest_options opts,<br>
        const char *progname, FILE *fp, FILE *fp_stderr)<br>
@@ -362,6 +414,8 @@ run_ptests(struct ptest_list *head, const struct ptest_options opts,<br>
    int timeouted;<br>
    time_t sttime, entime;<br>
    int duration;<br>
+Â Â Â Â int slave;<br>
+Â Â Â Â int pgid = -1;<br>
<br>
    if (opts.xml_filename) {<br>
        xh = xml_create(ptest_list_length(head), opts.xml_filename);<br>
@@ -379,7 +433,6 @@ run_ptests(struct ptest_list *head, const struct ptest_options opts,<br>
            close(pipefd_stdout[1]);<br>
            break;<br>
        }<br>
-<br>
        fprintf(fp, "START: %s\n", progname);<br>
        PTEST_LIST_ITERATE_START(head, p);<br>
            char *ptest_dir = strdup(p->run_ptest);<br>
@@ -388,6 +441,13 @@ run_ptests(struct ptest_list *head, const struct ptest_options opts,<br>
                break;<br>
            }<br>
            dirname(ptest_dir);<br>
+Â Â Â Â Â Â Â Â Â Â Â Â if (ioctl(0, TIOCNOTTY) == -1) {<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â fprintf(fp, "ERROR: Unable to detach from controlling tty, %s\n", strerror(errno));<br>
+Â Â Â Â Â Â Â Â Â Â Â Â }<br>
+<br>
+Â Â Â Â Â Â Â Â Â Â Â Â if ((pgid = getpgid(0)) == -1) {<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â fprintf(fp, "ERROR: getpgid() failed, %s\n", strerror(errno));<br>
+Â Â Â Â Â Â Â Â Â Â Â Â }<br>
<br>
            child = fork();<br>
            if (child == -1) {<br>
@@ -395,13 +455,33 @@ run_ptests(struct ptest_list *head, const struct ptest_options opts,<br>
                rc = -1;<br>
                break;<br>
            } else if (child == 0) {<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â setsid();<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â close(0);<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if ((slave = setup_slave_pty(fp)) < 0) {<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â fprintf(fp, "ERROR: could not setup pty (%d).", slave);<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if (setpgid(0,pgid) == -1) {<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â fprintf(fp, "ERROR: setpgid() failed, %s\n", strerror(errno));<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }<br>
+<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if (setsid() ==Â -1) {<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â fprintf(fp, "ERROR: setsid() failed, %s\n", strerror(errno));<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }<br>
+<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if (ioctl(0, TIOCSCTTY, NULL) == -1) {<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â fprintf(fp, "ERROR: Unable to attach to controlling tty, %s\n", strerror(errno));<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }<br>
+<br>
                run_child(p->run_ptest, pipefd_stdout[1], pipefd_stderr[1]);<br>
+<br>
            } else {<br>
                int status;<br>
                int fds[2]; fds[0] = pipefd_stdout[0]; fds[1] = pipefd_stderr[0];<br>
                FILE *fps[2]; fps[0] = fp; fps[1] = fp_stderr;<br>
<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if (setpgid(child, pgid) == -1) {<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â fprintf(fp, "ERROR: setpgid() failed, %s\n", strerror(errno));<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }<br>
+<br>
                sttime = time(NULL);<br>
                fprintf(fp, "%s\n", get_stime(stime, GET_STIME_BUF_SIZE, sttime));<br>
                fprintf(fp, "BEGIN: %s\n", ptest_dir);<br>
-- <br>
2.17.0<br>
<br>
</blockquote></div>