/*-
 * Copyright (c) 2003 Seth Kingsley.  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
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgment:
 *    This product includes software developed by Seth Kingsley and
 *    contributors.
 * 4. Neither the author's name, nor any of the contributors names may be
 *    used to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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    <sys/cdefs.h>
#include    <sys/stat.h>
#include    <sys/wait.h>
#include    <sys/errno.h>

#include    <signal.h>
#include    <unistd.h>
#include    <stdlib.h>
#ifdef DEBUG
#include    <stdio.h>
#endif /* DEBUG */
#include    <err.h>

#include    "support.h"
#include    "util.h"

#include    <xmk-gtk.h>

__RCSID("$Id: util.c,v 1.7 2004/06/07 23:14:26 sethk Exp $");

static void
_util_reap(int sig __unused)
{
    int	s;

    if (waitpid(-1, &s, WNOHANG) == -1)
    {
#ifdef DEBUG
	warn("waitpid");
#endif /* DEBUG */
	return;
    }

    if (WIFEXITED(s) && WEXITSTATUS(s) > 127)
    {
	errno = WEXITSTATUS(s) - 127;
#ifdef DEBUG
	/*xmk_warning("Terminal failed");*/
#endif /* DEBUG */
    }
}

guint
util_numstrv(gchar **strv)
{
    guint   i;

    for (i = 0; strv[i]; ++i)
	;

    return i;
}

pid_t
util_spawn(const char *desc,
	const char *dir,
	char *progs[],
	char *av[])
{
    pid_t   pid;

    signal(SIGCHLD, _util_reap);

    switch ((pid = vfork()))
    {
	u_int	i;

	case -1:
	    xmk_warning(NULL, TRUE, _("Couldn't fork for %s"), desc);
	    return -1;

	case 0:
	    if (dir)
	    {
		if (chdir(dir) == -1)
		    exit(127 + errno);
	    }

	    for (i = 0; progs[i]; ++i)
	    {
		av[0] = progs[i];

#ifdef DEBUG
		{
		    u_int   j;

		    fprintf(stderr, "%s: spawn %s", getprogname(), progs[i]);
		    for (j = 1; av[j]; ++j)
			fprintf(stderr, " %s", av[j]);
		    fputc('\n', stderr);
		}
#endif /* DEBUG */

		if (execvp(progs[i], av) == -1 && errno != ENOENT)
		{
#ifdef DEBUG
		    warn(_("Exec %s failed"), progs[i]);
#endif /* DEBUG */
		    _exit(127 + errno);
		}
	    }
	    warn(_("No %s program found"), desc);
	    _exit(1);

	    /* NOTREACHED */
	    return -1;

	default:
	    return pid;
    }
}

