Commit 83764518 authored by Philip Chimento's avatar Philip Chimento

tests: Move gjs_crash_after_timeout to test utils

This function doesn't belong in libgjs.

https://bugzilla.gnome.org/show_bug.cgi?id=772386
parent 3ce20324
......@@ -98,8 +98,6 @@ libgjs_la_SOURCES = \
util/hash-x32.h \
util/glib.cpp \
util/glib.h \
util/crash.cpp \
util/crash.h \
util/log.cpp \
util/log.h \
util/misc.cpp \
......
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/*
* Copyright (c) 2008 litl, LLC
* Copyright (c) 2016 Endless Mobile, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
......@@ -77,3 +78,91 @@ gjs_unit_test_fixture_teardown(GjsUnitTestFixture *fx,
g_printerr("**\n%s\n", fx->message);
g_free(fx->message);
}
/* Fork a process that waits the given time then
* sends us ABRT
*/
void
gjs_crash_after_timeout(int seconds)
{
pid_t parent_pid;
int pipe_fds[2];
fd_set read_fds;
struct timeval term_time;
struct timeval remaining;
struct timeval now;
int old_flags;
/* We use a pipe to know in the child when the parent exited */
if (pipe(pipe_fds) != 0) {
fprintf(stderr, "Failed to create pipe to crash-in-timeout process: %s\n",
strerror(errno));
return;
}
/* We want pipe_fds[1] to only be open in the parent process; when it closes
* the child will see an EOF. Setting FD_CLOEXEC is protection in case the
* parent spawns off some process without properly closing fds.
*/
old_flags = fcntl(pipe_fds[1], F_GETFD);
if (old_flags == -1 ||
fcntl(pipe_fds[1], F_SETFD, old_flags | FD_CLOEXEC) != 0) {
fprintf(stderr, "Couldn't make crash-timeout pipe FD_CLOEXEC: %s\n",
strerror(errno));
return;
}
parent_pid = getpid();
switch (fork()) {
case -1:
fprintf(stderr, "Failed to fork crash-in-timeout process: %s\n",
strerror(errno));
return;
case 0:
/* child */
break;
default:
/* parent */
close(pipe_fds[0]);
return;
}
close (pipe_fds[1]);
gettimeofday (&now, NULL);
term_time = now;
term_time.tv_sec += seconds;
FD_ZERO(&read_fds);
FD_SET(pipe_fds[0], &read_fds);
while (true) {
remaining.tv_sec = term_time.tv_sec - now.tv_sec;
remaining.tv_usec = term_time.tv_usec - now.tv_usec;
if (remaining.tv_usec < 0) {
remaining.tv_usec += 1000;
remaining.tv_sec -= 1;
}
if (remaining.tv_sec < 0) /* expired */
break;
select(pipe_fds[0] + 1, &read_fds, NULL, NULL, &remaining);
if (FD_ISSET(pipe_fds[0], &read_fds)) {
/* The parent exited */
_exit(0);
}
gettimeofday(&now, NULL);
}
if (kill(parent_pid, 0) == 0) {
fprintf(stderr, "Timeout of %d seconds expired; aborting process %d\n",
seconds, (int) parent_pid);
kill(parent_pid, SIGABRT);
}
_exit(1);
}
......@@ -34,6 +34,8 @@ void gjs_unit_test_fixture_setup(GjsUnitTestFixture *fx,
void gjs_unit_test_fixture_teardown(GjsUnitTestFixture *fx,
gconstpointer unused);
void gjs_crash_after_timeout(int seconds);
void gjs_test_add_tests_for_coverage ();
void gjs_test_add_tests_for_parse_call_args(void);
......
......@@ -25,7 +25,6 @@
#include <glib.h>
#include <glib-object.h>
#include <util/glib.h>
#include <util/crash.h>
#include <gjs/context.h>
......
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/*
* Copyright (c) 2008 litl, LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include <config.h>
#include <glib.h>
#include "crash.h"
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
/* Fork a process that waits the given time then
* sends us ABRT
*/
void
gjs_crash_after_timeout(int seconds)
{
pid_t parent_pid;
int pipe_fds[2];
fd_set read_fds;
struct timeval term_time;
struct timeval remaining;
struct timeval now;
int old_flags;
/* We use a pipe to know in the child when the parent exited */
if (pipe(pipe_fds) != 0) {
fprintf(stderr, "Failed to create pipe to crash-in-timeout process: %s\n",
strerror(errno));
return;
}
/* We want pipe_fds[1] to only be open in the parent process; when it closes
* the child will see an EOF. Setting FD_CLOEXEC is protection in case the
* parent spawns off some process without properly closing fds.
*/
old_flags = fcntl(pipe_fds[1], F_GETFD);
if (old_flags == -1 ||
fcntl(pipe_fds[1], F_SETFD, old_flags | FD_CLOEXEC) != 0) {
fprintf(stderr, "Couldn't make crash-timeout pipe FD_CLOEXEC: %s\n",
strerror(errno));
return;
}
parent_pid = getpid();
switch (fork()) {
case -1:
fprintf(stderr, "Failed to fork crash-in-timeout process: %s\n",
strerror(errno));
return;
case 0:
/* child */
break;
default:
/* parent */
close(pipe_fds[0]);
return;
}
close (pipe_fds[1]);
gettimeofday (&now, NULL);
term_time = now;
term_time.tv_sec += seconds;
FD_ZERO(&read_fds);
FD_SET(pipe_fds[0], &read_fds);
while (true) {
remaining.tv_sec = term_time.tv_sec - now.tv_sec;
remaining.tv_usec = term_time.tv_usec - now.tv_usec;
if (remaining.tv_usec < 0) {
remaining.tv_usec += 1000;
remaining.tv_sec -= 1;
}
if (remaining.tv_sec < 0) /* expired */
break;
select(pipe_fds[0] + 1, &read_fds, NULL, NULL, &remaining);
if (FD_ISSET(pipe_fds[0], &read_fds)) {
/* The parent exited */
_exit(0);
}
gettimeofday(&now, NULL);
}
if (kill(parent_pid, 0) == 0) {
fprintf(stderr, "Timeout of %d seconds expired; aborting process %d\n",
seconds, (int) parent_pid);
kill(parent_pid, SIGABRT);
}
_exit(1);
}
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/*
* Copyright (c) 2008 litl, LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef __GJS_UTIL_CRASH_H__
#define __GJS_UTIL_CRASH_H__
#include <glib.h>
G_BEGIN_DECLS
void gjs_crash_after_timeout (int seconds);
G_END_DECLS
#endif /* __GJS_UTIL_CRASH_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment