From: Alexey K. <ale...@or...> - 2013-06-26 15:07:57
|
vfork() + execvp() specified program. Signed-off-by: Alexey Kodanev <ale...@or...> --- include/test.h | 9 +++++++++ lib/tst_run_cmd.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 0 deletions(-) create mode 100644 lib/tst_run_cmd.c diff --git a/include/test.h b/include/test.h index c922230..e85a783 100644 --- a/include/test.h +++ b/include/test.h @@ -282,6 +282,15 @@ int tst_get_path(const char *prog_name, char *buf, size_t buf_len); long tst_ncpus(void); long tst_ncpus_max(void); +/* lib/tst_run_cmd.c + * + * vfork() + execvp() specified program. + * @argv: a list of two (at least program name + NULL) or more pointers that + * represent the argument list to the new program. The array of pointers + * should be terminated by a NULL pointer. + */ +void tst_run_cmd(void (cleanup_fn)(void), char *const argv[]); + #ifdef TST_USE_COMPAT16_SYSCALL #define TCID_BIT_SUFFIX "_16" #elif TST_USE_NEWER64_SYSCALL diff --git a/lib/tst_run_cmd.c b/lib/tst_run_cmd.c new file mode 100644 index 0000000..9a7f426 --- /dev/null +++ b/lib/tst_run_cmd.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Alexey Kodanev <ale...@or...> + * + */ + +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include "test.h" + +void tst_run_cmd(void (cleanup_fn)(void), char *const argv[]) +{ + if (argv == NULL || argv[0] == NULL) { + tst_brkm(TBROK, cleanup_fn, + "argument list is empty at %s:%d", __FILE__, __LINE__); + } + + pid_t pid = vfork(); + if (pid == -1) { + tst_brkm(TBROK | TERRNO, cleanup_fn, "vfork failed at %s:%d", + __FILE__, __LINE__); + } + if (!pid) + _exit(execvp(argv[0], argv)); + + int ret = -1; + waitpid(pid, &ret, 0); + + if (ret != 0) { + tst_brkm(TBROK, cleanup_fn, "failed to exec cmd '%s' at %s:%d", + argv[0], __FILE__, __LINE__); + } +} -- 1.7.1 |
From: Alexey K. <ale...@or...> - 2013-06-27 14:53:02
|
vfork() + execvp() specified program. Signed-off-by: Alexey Kodanev <ale...@or...> --- include/test.h | 9 +++++++++ lib/tst_run_cmd.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 0 deletions(-) create mode 100644 lib/tst_run_cmd.c diff --git a/include/test.h b/include/test.h index e68ae60..ee3efc3 100644 --- a/include/test.h +++ b/include/test.h @@ -206,6 +206,15 @@ int tst_get_path(const char *prog_name, char *buf, size_t buf_len); long tst_ncpus(void); long tst_ncpus_max(void); +/* lib/tst_run_cmd.c + * + * vfork() + execvp() specified program. + * @argv: a list of two (at least program name + NULL) or more pointers that + * represent the argument list to the new program. The array of pointers + * must be terminated by a NULL pointer. + */ +void tst_run_cmd(void (cleanup_fn)(void), char *const argv[]); + #ifdef TST_USE_COMPAT16_SYSCALL #define TCID_BIT_SUFFIX "_16" #elif TST_USE_NEWER64_SYSCALL diff --git a/lib/tst_run_cmd.c b/lib/tst_run_cmd.c new file mode 100644 index 0000000..93fe2d6 --- /dev/null +++ b/lib/tst_run_cmd.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Alexey Kodanev <ale...@or...> + * + */ + +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include "test.h" + +void tst_run_cmd(void (cleanup_fn)(void), char *const argv[]) +{ + if (argv == NULL || argv[0] == NULL) { + tst_brkm(TBROK, cleanup_fn, + "argument list is empty at %s:%d", __FILE__, __LINE__); + } + + pid_t pid = vfork(); + if (pid == -1) { + tst_brkm(TBROK | TERRNO, cleanup_fn, "vfork failed at %s:%d", + __FILE__, __LINE__); + } + if (!pid) + _exit(execvp(argv[0], argv)); + + int ret = -1; + if (waitpid(pid, &ret, 0) != pid) { + tst_brkm(TBROK, cleanup_fn, "waitpid failed at %s:%d", + __FILE__, __LINE__); + } + + if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) { + tst_brkm(TBROK, cleanup_fn, "failed to exec cmd '%s' at %s:%d", + argv[0], __FILE__, __LINE__); + } +} -- 1.7.1 |
From: <ch...@su...> - 2013-06-27 15:01:22
|
Hi! > vfork() + execvp() specified program. > > Signed-off-by: Alexey Kodanev <ale...@or...> > --- > include/test.h | 9 +++++++++ > lib/tst_run_cmd.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 61 insertions(+), 0 deletions(-) > create mode 100644 lib/tst_run_cmd.c This one looks fine to me. Let's wait a day or two to give other people chance to look at the code. And if nobody object I will start pushing the patches in the order. -- Cyril Hrubis ch...@su... |
From: Caspar Z. <ca...@ca...> - 2013-06-28 03:15:08
|
On 06/27/2013 10:52 PM, Alexey Kodanev wrote: > vfork() + execvp() specified program. > > Signed-off-by: Alexey Kodanev <ale...@or...> > --- > include/test.h | 9 +++++++++ > lib/tst_run_cmd.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 61 insertions(+), 0 deletions(-) > create mode 100644 lib/tst_run_cmd.c > > diff --git a/include/test.h b/include/test.h > index e68ae60..ee3efc3 100644 > --- a/include/test.h > +++ b/include/test.h > @@ -206,6 +206,15 @@ int tst_get_path(const char *prog_name, char *buf, size_t buf_len); > long tst_ncpus(void); > long tst_ncpus_max(void); > > +/* lib/tst_run_cmd.c > + * > + * vfork() + execvp() specified program. > + * @argv: a list of two (at least program name + NULL) or more pointers that > + * represent the argument list to the new program. The array of pointers > + * must be terminated by a NULL pointer. > + */ > +void tst_run_cmd(void (cleanup_fn)(void), char *const argv[]); > + > #ifdef TST_USE_COMPAT16_SYSCALL > #define TCID_BIT_SUFFIX "_16" > #elif TST_USE_NEWER64_SYSCALL > diff --git a/lib/tst_run_cmd.c b/lib/tst_run_cmd.c > new file mode 100644 > index 0000000..93fe2d6 > --- /dev/null > +++ b/lib/tst_run_cmd.c > @@ -0,0 +1,52 @@ > +/* > + * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of > + * the License, or (at your option) any later version. > + * > + * 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. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write the Free Software Foundation, > + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > + * > + * Author: Alexey Kodanev <ale...@or...> > + * > + */ > + > +#include <sys/types.h> > +#include <sys/wait.h> > +#include <unistd.h> > +#include "test.h" > + > +void tst_run_cmd(void (cleanup_fn)(void), char *const argv[]) > +{ > + if (argv == NULL || argv[0] == NULL) { > + tst_brkm(TBROK, cleanup_fn, > + "argument list is empty at %s:%d", __FILE__, __LINE__); > + } > + > + pid_t pid = vfork(); > + if (pid == -1) { > + tst_brkm(TBROK | TERRNO, cleanup_fn, "vfork failed at %s:%d", > + __FILE__, __LINE__); > + } > + if (!pid) > + _exit(execvp(argv[0], argv)); > + > + int ret = -1; > + if (waitpid(pid, &ret, 0) != pid) { > + tst_brkm(TBROK, cleanup_fn, "waitpid failed at %s:%d", > + __FILE__, __LINE__); > + } > + > + if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) { > + tst_brkm(TBROK, cleanup_fn, "failed to exec cmd '%s' at %s:%d", > + argv[0], __FILE__, __LINE__); > + } > +} > LGTM Reviewed-by: Caspar Zhang <ca...@ca...> |
From: Wanlong G. <gao...@cn...> - 2013-06-28 03:18:20
|
On 06/27/2013 10:52 PM, Alexey Kodanev wrote: > vfork() + execvp() specified program. > > Signed-off-by: Alexey Kodanev <ale...@or...> LGTM Reviewed-by: Wanlong Gao <gao...@cn...> > --- > include/test.h | 9 +++++++++ > lib/tst_run_cmd.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 61 insertions(+), 0 deletions(-) > create mode 100644 lib/tst_run_cmd.c > > diff --git a/include/test.h b/include/test.h > index e68ae60..ee3efc3 100644 > --- a/include/test.h > +++ b/include/test.h > @@ -206,6 +206,15 @@ int tst_get_path(const char *prog_name, char *buf, size_t buf_len); > long tst_ncpus(void); > long tst_ncpus_max(void); > > +/* lib/tst_run_cmd.c > + * > + * vfork() + execvp() specified program. > + * @argv: a list of two (at least program name + NULL) or more pointers that > + * represent the argument list to the new program. The array of pointers > + * must be terminated by a NULL pointer. > + */ > +void tst_run_cmd(void (cleanup_fn)(void), char *const argv[]); > + > #ifdef TST_USE_COMPAT16_SYSCALL > #define TCID_BIT_SUFFIX "_16" > #elif TST_USE_NEWER64_SYSCALL > diff --git a/lib/tst_run_cmd.c b/lib/tst_run_cmd.c > new file mode 100644 > index 0000000..93fe2d6 > --- /dev/null > +++ b/lib/tst_run_cmd.c > @@ -0,0 +1,52 @@ > +/* > + * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of > + * the License, or (at your option) any later version. > + * > + * 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. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write the Free Software Foundation, > + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > + * > + * Author: Alexey Kodanev <ale...@or...> > + * > + */ > + > +#include <sys/types.h> > +#include <sys/wait.h> > +#include <unistd.h> > +#include "test.h" > + > +void tst_run_cmd(void (cleanup_fn)(void), char *const argv[]) > +{ > + if (argv == NULL || argv[0] == NULL) { > + tst_brkm(TBROK, cleanup_fn, > + "argument list is empty at %s:%d", __FILE__, __LINE__); > + } > + > + pid_t pid = vfork(); > + if (pid == -1) { > + tst_brkm(TBROK | TERRNO, cleanup_fn, "vfork failed at %s:%d", > + __FILE__, __LINE__); > + } > + if (!pid) > + _exit(execvp(argv[0], argv)); > + > + int ret = -1; > + if (waitpid(pid, &ret, 0) != pid) { > + tst_brkm(TBROK, cleanup_fn, "waitpid failed at %s:%d", > + __FILE__, __LINE__); > + } > + > + if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) { > + tst_brkm(TBROK, cleanup_fn, "failed to exec cmd '%s' at %s:%d", > + argv[0], __FILE__, __LINE__); > + } > +} > |
From: Wanlong G. <gao...@cn...> - 2013-07-01 09:01:04
|
On 06/27/2013 10:52 PM, Alexey Kodanev wrote: > vfork() + execvp() specified program. > > Signed-off-by: Alexey Kodanev <ale...@or...> Applied, thank you. Wanlong Gao |
From: <ch...@su...> - 2013-06-27 13:54:14
|
Hi! > vfork() + execvp() specified program. > > Signed-off-by: Alexey Kodanev <ale...@or...> > --- > include/test.h | 9 +++++++++ > lib/tst_run_cmd.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 58 insertions(+), 0 deletions(-) > create mode 100644 lib/tst_run_cmd.c > > diff --git a/include/test.h b/include/test.h > index c922230..e85a783 100644 > --- a/include/test.h > +++ b/include/test.h > @@ -282,6 +282,15 @@ int tst_get_path(const char *prog_name, char *buf, size_t buf_len); > long tst_ncpus(void); > long tst_ncpus_max(void); > > +/* lib/tst_run_cmd.c > + * > + * vfork() + execvp() specified program. > + * @argv: a list of two (at least program name + NULL) or more pointers that > + * represent the argument list to the new program. The array of pointers > + * should be terminated by a NULL pointer. must be terminaled by a NULL pointer. (if it's not, the program will crash) > + */ > +void tst_run_cmd(void (cleanup_fn)(void), char *const argv[]); > + > #ifdef TST_USE_COMPAT16_SYSCALL > #define TCID_BIT_SUFFIX "_16" > #elif TST_USE_NEWER64_SYSCALL > diff --git a/lib/tst_run_cmd.c b/lib/tst_run_cmd.c > new file mode 100644 > index 0000000..9a7f426 > --- /dev/null > +++ b/lib/tst_run_cmd.c > @@ -0,0 +1,49 @@ > +/* > + * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of > + * the License, or (at your option) any later version. > + * > + * 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. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write the Free Software Foundation, > + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > + * > + * Author: Alexey Kodanev <ale...@or...> > + * > + */ > + > +#include <sys/types.h> > +#include <sys/wait.h> > +#include <unistd.h> > +#include "test.h" > + > +void tst_run_cmd(void (cleanup_fn)(void), char *const argv[]) > +{ > + if (argv == NULL || argv[0] == NULL) { > + tst_brkm(TBROK, cleanup_fn, > + "argument list is empty at %s:%d", __FILE__, __LINE__); > + } > + > + pid_t pid = vfork(); > + if (pid == -1) { > + tst_brkm(TBROK | TERRNO, cleanup_fn, "vfork failed at %s:%d", > + __FILE__, __LINE__); > + } > + if (!pid) > + _exit(execvp(argv[0], argv)); > + > + int ret = -1; > + waitpid(pid, &ret, 0); > + > + if (ret != 0) { > + tst_brkm(TBROK, cleanup_fn, "failed to exec cmd '%s' at %s:%d", > + argv[0], __FILE__, __LINE__); > + } > +} This version looks nearly fine. I would check the return value from waitpid() too, just for the sake of completness. And looking at the waitpid() documentation it states that it uses only two bytes from ret (in reality it's cleared to zero but that is not promised in specification). I would change the last condition to: if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) { } After these minor changes it's fine. -- Cyril Hrubis ch...@su... |
From: <ale...@or...> - 2013-06-27 14:18:53
|
Hi! On 06/27/2013 05:55 PM, ch...@su... wrote: > >> +/* lib/tst_run_cmd.c >> + * >> + * vfork() + execvp() specified program. >> + * @argv: a list of two (at least program name + NULL) or more pointers that >> + * represent the argument list to the new program. The array of pointers >> + * should be terminated by a NULL pointer. > must be terminaled by a NULL pointer. > > (if it's not, the program will crash) > OK >> + >> + pid_t pid = vfork(); >> + if (pid == -1) { >> + tst_brkm(TBROK | TERRNO, cleanup_fn, "vfork failed at %s:%d", >> + __FILE__, __LINE__); >> + } >> + if (!pid) >> + _exit(execvp(argv[0], argv)); >> + >> + int ret = -1; >> + waitpid(pid,&ret, 0); >> + >> + if (ret != 0) { >> + tst_brkm(TBROK, cleanup_fn, "failed to exec cmd '%s' at %s:%d", >> + argv[0], __FILE__, __LINE__); >> + } >> +} > This version looks nearly fine. I would check the return value from > waitpid() too, just for the sake of completness. > So, something like this is ok: if (waitpid(pid, &ret, 0) != pid) tst_brkm(..."waitpid failed at ...") > And looking at the waitpid() documentation it states that it uses only > two bytes from ret (in reality it's cleared to zero but that is not > promised in specification). > > I would change the last condition to: > > if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) { > > } But the waitpid() manual says that WEXITSTATUS should only be employed if WIFEXITED returned true, so may be change it to: if (!WIFEXITED(ret) || (WIFEXITED(ret) && WEXITSTATUS(ret) != 0)) { ... } Thanks, Alexey |
From: <ch...@su...> - 2013-06-27 14:26:47
|
Hi! > > This version looks nearly fine. I would check the return value from > > waitpid() too, just for the sake of completness. > > > So, something like this is ok: > if (waitpid(pid, &ret, 0) != pid) > tst_brkm(..."waitpid failed at ...") Yes. > > And looking at the waitpid() documentation it states that it uses only > > two bytes from ret (in reality it's cleared to zero but that is not > > promised in specification). > > > > I would change the last condition to: > > > > if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) { > > > > } > But the waitpid() manual says that WEXITSTATUS should only be employed > if WIFEXITED returned true, so may be change it to: > if (!WIFEXITED(ret) || (WIFEXITED(ret) && WEXITSTATUS(ret) != 0)) { > ... > } The short circuit evaluation will take care of that. -- Cyril Hrubis ch...@su... |