/* -*- Mode: C++; tab-width: 8; c-basic-offset: 8 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * 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.
 *
 * The Original Code is the Netscape Portable Runtime (NSPR).
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998-2000
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include "primpl.h"
#include <stdio.h>
#include <signal.h>

#define _PR_SIGNALED_EXITSTATUS 256

PRProcess*
_MD_create_process (const char *path, char *const *argv,
		    char *const *envp, const PRProcessAttr *attr)
{
	PRProcess *process;
	int nEnv, idx;
	char *const *childEnvp;
	char **newEnvp = NULL;
	int flags;
	PRBool found = PR_FALSE;

	process = PR_NEW(PRProcess);
	if (!process) {
		PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
		return NULL;
	}

	childEnvp = envp;
	if (attr && attr->fdInheritBuffer) {
		if (NULL == childEnvp) {
			childEnvp = environ;
		}
		for (nEnv = 0; childEnvp[nEnv]; nEnv++) {
		}
		newEnvp = (char **) PR_MALLOC((nEnv + 2) * sizeof(char *));
		if (NULL == newEnvp) {
			PR_DELETE(process);
			PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
			return NULL;
		}
		for (idx = 0; idx < nEnv; idx++) {
			newEnvp[idx] = childEnvp[idx];
			if (!found && !strncmp(newEnvp[idx], "NSPR_INHERIT_FDS=", 17)) {
				newEnvp[idx] = attr->fdInheritBuffer;
				found = PR_TRUE;
			}
		}
		if (!found) {
			newEnvp[idx++] = attr->fdInheritBuffer;
		}
		newEnvp[idx] = NULL;
		childEnvp = newEnvp;
	}

	process->md.pid = fork();

	if ((pid_t) -1 == process->md.pid) {
		PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, errno);
		PR_DELETE(process);
		if (newEnvp) {
			PR_DELETE(newEnvp);
		}
		return NULL;
	} else if (0 == process->md.pid) {  /* the child process */
		/*
		 * If the child process needs to exit, it must call _exit().
		 * Do not call exit(), because exit() will flush and close
		 * the standard I/O file descriptors, and hence corrupt
		 * the parent process's standard I/O data structures.
		 */

		if (attr) {
			/* the osfd's to redirect stdin, stdout, and stderr to */
			int in_osfd = -1, out_osfd = -1, err_osfd = -1;

			if (attr->stdinFd
			    && attr->stdinFd->secret->md.osfd != 0) {
				in_osfd = attr->stdinFd->secret->md.osfd;
				if (dup2(in_osfd, 0) != 0) {
					_exit(1);  /* failed */
				}
				flags = fcntl(0, F_GETFL, 0);
				if (flags & O_NONBLOCK) {
					fcntl(0, F_SETFL, flags & ~O_NONBLOCK);
				}
			}
			if (attr->stdoutFd
			    && attr->stdoutFd->secret->md.osfd != 1) {
				out_osfd = attr->stdoutFd->secret->md.osfd;
				if (dup2(out_osfd, 1) != 1) {
					_exit(1);  /* failed */
				}
				flags = fcntl(1, F_GETFL, 0);
				if (flags & O_NONBLOCK) {
					fcntl(1, F_SETFL, flags & ~O_NONBLOCK);
				}
			}
			if (attr->stderrFd
			    && attr->stderrFd->secret->md.osfd != 2) {
				err_osfd = attr->stderrFd->secret->md.osfd;
				if (dup2(err_osfd, 2) != 2) {
					_exit(1);  /* failed */
				}
				flags = fcntl(2, F_GETFL, 0);
				if (flags & O_NONBLOCK) {
					fcntl(2, F_SETFL, flags & ~O_NONBLOCK);
				}
			}
			if (in_osfd != -1) {
				close(in_osfd);
			}
			if (out_osfd != -1 && out_osfd != in_osfd) {
				close(out_osfd);
			}
			if (err_osfd != -1 && err_osfd != in_osfd
			    && err_osfd != out_osfd) {
				close(err_osfd);
			}
			if (attr->currentDirectory) {
				if (chdir(attr->currentDirectory) < 0) {
					_exit(1);  /* failed */
				}
			}
		}

		if (childEnvp) {
			(void)execve(path, argv, childEnvp);
		} else {
			/* Inherit the environment of the parent. */
			(void)execv(path, argv);
		}
		/* Whoops! It returned. That's a bad sign. */
		_exit(1);
	}

	if (newEnvp) {
		PR_DELETE(newEnvp);
	}

	return process;
}

PRStatus
_MD_detach_process (PRProcess *process)
{
	/* If we kept a process table like unix does,
	 * we'd remove the entry here.
	 * Since we dont', just delete the process variable
	 */
	PR_DELETE(process);
	return PR_SUCCESS;
}

PRStatus
_MD_wait_process (PRProcess *process, PRInt32 *exitCode)
{
	PRStatus retVal = PR_SUCCESS;
	int ret, status;
	
	/* Ignore interruptions */
	do {
		ret = waitpid(process->md.pid, &status, 0);
	} while (ret == -1 && errno == EINTR);

	/*
	 * waitpid() cannot return 0 because we did not invoke it
	 * with the WNOHANG option.
	 */ 
	PR_ASSERT(0 != ret);

	if (ret < 0) {
                PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
		return PR_FAILURE;
	}

	/* If child process exited normally, return child exit code */
	if (WIFEXITED(status)) {
		*exitCode = WEXITSTATUS(status);
	} else {
		PR_ASSERT(WIFSIGNALED(status));
		*exitCode = _PR_SIGNALED_EXITSTATUS;
	}		

	PR_DELETE(process);
	return PR_SUCCESS;
}

PRStatus
_MD_kill_process (PRProcess *process)
{
	PRErrorCode prerror;
	PRInt32 oserror;
	
	if (kill(process->md.pid, SIGKILL) == 0) {
		return PR_SUCCESS;
	}
	oserror = errno;
	switch (oserror) {
        case EPERM:
		prerror = PR_NO_ACCESS_RIGHTS_ERROR;
		break;
        case ESRCH:
		prerror = PR_INVALID_ARGUMENT_ERROR;
		break;
        default:
		prerror = PR_UNKNOWN_ERROR;
		break;
	}
	PR_SetError(prerror, oserror);
	return PR_FAILURE;
}
