/*
* Automated Testing Framework (atf)
*
* Copyright (c) 2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "process.h"
#include "sanity.h"
/* This prototype is not in the header file because this is a private
* function; however, we need to access it during testing. */
/* ---------------------------------------------------------------------
* The "stream_prepare" auxiliary type.
* --------------------------------------------------------------------- */
struct stream_prepare {
bool m_pipefds_ok;
};
static
{
sp->m_pipefds_ok = false;
if (type == atf_process_stream_type_capture) {
else {
err = atf_no_error();
sp->m_pipefds_ok = true;
}
} else
err = atf_no_error();
return err;
}
static
void
{
if (sp->m_pipefds_ok) {
}
}
/* ---------------------------------------------------------------------
* The "atf_process_stream" type.
* --------------------------------------------------------------------- */
static
bool
{
}
{
return atf_no_error();
}
{
return atf_no_error();
}
{
return atf_no_error();
}
const int fd)
{
return atf_no_error();
}
const atf_fs_path_t *path)
{
return atf_no_error();
}
void
{
}
int
{
}
/* ---------------------------------------------------------------------
* The "atf_process_status" type.
* --------------------------------------------------------------------- */
{
return atf_no_error();
}
void
{
}
bool
{
return WIFEXITED(mutable_status);
}
int
{
return WEXITSTATUS(mutable_status);
}
bool
{
return WIFSIGNALED(mutable_status);
}
int
{
return WTERMSIG(mutable_status);
}
bool
{
#if defined(WCOREDUMP)
return WCOREDUMP(mutable_status);
#else
return false;
#endif
}
/* ---------------------------------------------------------------------
* The "atf_process_child" type.
* --------------------------------------------------------------------- */
static
{
c->m_pid = 0;
c->m_stdout = -1;
c->m_stderr = -1;
return atf_no_error();
}
static
void
{
if (c->m_stdout != -1)
if (c->m_stderr != -1)
}
{
int status;
c->m_pid);
else {
}
return err;
}
{
return c->m_pid;
}
int
{
return c->m_stdout;
}
int
{
return c->m_stderr;
}
/* ---------------------------------------------------------------------
* Free functions.
* --------------------------------------------------------------------- */
static
{
} else {
err = atf_no_error();
}
} else
err = atf_no_error();
return err;
}
static
{
if (type == atf_process_stream_type_capture) {
} else if (type == atf_process_stream_type_connect) {
else
err = atf_no_error();
} else if (type == atf_process_stream_type_inherit) {
err = atf_no_error();
} else if (type == atf_process_stream_type_redirect_fd) {
} else if (type == atf_process_stream_type_redirect_path) {
if (aux == -1)
else {
if (atf_is_error(err))
}
} else {
err = atf_no_error();
}
return err;
}
static
void
{
if (type == atf_process_stream_type_capture) {
} else if (type == atf_process_stream_type_connect) {
/* Do nothing. */
} else if (type == atf_process_stream_type_inherit) {
/* Do nothing. */
} else if (type == atf_process_stream_type_redirect_fd) {
/* Do nothing. */
} else if (type == atf_process_stream_type_redirect_path) {
/* Do nothing. */
} else {
}
}
static
const stream_prepare_t *outsp,
const stream_prepare_t *errsp)
{
err = atf_process_child_init(c);
if (atf_is_error(err))
goto out;
out:
return err;
}
static
void
do_child(void (*)(void *),
void *,
const stream_prepare_t *,
const stream_prepare_t *) ATF_DEFS_ATTRIBUTE_NORETURN;
static
void
void *v,
const stream_prepare_t *outsp,
const stream_prepare_t *errsp)
{
if (atf_is_error(err))
goto out;
if (atf_is_error(err))
goto out;
start(v);
out:
if (atf_is_error(err)) {
} else
}
static
void (*start)(void *),
const atf_process_stream_t *outsb,
const atf_process_stream_t *errsb,
void *v)
{
if (atf_is_error(err))
goto out;
if (atf_is_error(err))
goto err_outpipe;
if (pid == -1) {
goto err_errpipe;
}
if (pid == 0) {
abort();
err = atf_no_error();
} else {
if (atf_is_error(err))
goto err_errpipe;
}
goto out;
out:
return err;
}
static
const atf_process_stream_t **realsb)
{
if (!atf_is_error(err))
} else {
err = atf_no_error();
}
return err;
}
void (*start)(void *),
const atf_process_stream_t *outsb,
const atf_process_stream_t *errsb,
void *v)
{
if (atf_is_error(err))
goto out;
if (atf_is_error(err))
goto out_out;
out:
return err;
}
static
int
{
#define UNCONST(a) ((void *)(unsigned long)(const void *)(a))
}
static
{
const char **a;
if (a == NULL)
err = atf_no_memory_error();
else {
const char **aiter;
aiter = a;
aiter++;
}
err = atf_no_error();
*ap = a;
}
return err;
}
struct exec_args {
const char *const *m_argv;
void (*m_prehook)(void);
};
static
void
do_exec(void *v)
{
}
const atf_fs_path_t *prog,
const char *const *argv,
const atf_process_stream_t *outsb,
const atf_process_stream_t *errsb,
void (*prehook)(void))
{
if (atf_is_error(err))
goto out;
err = atf_process_child_wait(&c, s);
if (atf_is_error(err)) {
goto again;
}
out:
return err;
}
const atf_fs_path_t *prog,
const atf_list_t *argv,
const atf_process_stream_t *outsb,
const atf_process_stream_t *errsb,
void (*prehook)(void))
{
const char **argv2;
if (atf_is_error(err))
goto out;
out:
return err;
}