aboutsummaryrefslogtreecommitdiffstats
path: root/erts/test/erlexec_SUITE_data/erlexec_tests.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/test/erlexec_SUITE_data/erlexec_tests.c')
-rw-r--r--erts/test/erlexec_SUITE_data/erlexec_tests.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/erts/test/erlexec_SUITE_data/erlexec_tests.c b/erts/test/erlexec_SUITE_data/erlexec_tests.c
new file mode 100644
index 0000000000..a49a0b21a8
--- /dev/null
+++ b/erts/test/erlexec_SUITE_data/erlexec_tests.c
@@ -0,0 +1,110 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2008-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+/* Used by test case otp_7461 to spawn a child process with a given
+ * command line. Child process group is killed by order received on stdin.
+ *
+ * Author: Sverker Eriksson
+ */
+
+#if defined (__WIN32__) || defined(VXWORKS) || defined(_OSE_)
+int main() {return 0;}
+
+#else /* UNIX only */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define TRY(cmd) if ((cmd) < 0) bail_out(#cmd " failed")
+
+static void bail_out(const char* msg)
+{
+ perror(msg);
+ exit(-1);
+}
+
+static void alarm_handler(int signo)
+{
+ fprintf(stderr, __FILE__" self terminating after timeout\n");
+ exit(1);
+}
+
+int main(int argc, char* argv[])
+{
+ pid_t child;
+ int ret;
+ char cmd;
+ int child_exit;
+
+ if (argc < 2) {
+ fprintf(stderr, "Must specify command to run in background\n");
+ exit(-1);
+ }
+ TRY(child=fork());
+
+ if (child == 0) { /* child */
+ pid_t gchild;
+ TRY(setpgid(getpid(), getpid())); /* create process group */
+
+ TRY(gchild=fork());
+ if (gchild == 0) { /* grandchild */
+ TRY(execvp(argv[1],&argv[1]));
+ }
+ exit(0);
+ }
+ /* parent */
+
+ signal(SIGALRM, alarm_handler);
+ alarm(10*60); /* suicide in case nothing happens */
+
+ TRY(wait(&child_exit));
+ if (!WIFEXITED(child_exit) || WEXITSTATUS(child_exit)!=0) {
+ fprintf(stderr, "child did not exit normally (status=%d)\n", child_exit);
+ exit(-1);
+ }
+
+ for (;;)
+ {
+ TRY(ret=read(STDIN_FILENO, &cmd, 1));
+ if (ret == 0) break; /* eof -> exit */
+ switch (cmd)
+ {
+ case 'K':
+ ret = kill(-child, SIGINT); /* child process _group_ */
+ if (ret < 0 && errno != ESRCH) {
+ bail_out("kill failed");
+ }
+ write(STDOUT_FILENO, &cmd, 1); /* echo ack */
+ break;
+ case '\n':
+ break;/* ignore (for interactive testing) */
+ default:
+ fprintf(stderr, "Unknown command '%c'\n", cmd);
+ exit(-1);
+ }
+ }
+
+ return 0;
+}
+
+#endif /* UNIX */