You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by bn...@apache.org on 2001/08/02 22:29:14 UTC
cvs commit: apr/threadproc/NetWare threadpriv.c thread.c signals.c procsup.c proc.c
bnicholes 01/08/02 13:29:14
Added: threadproc/NetWare threadpriv.c thread.c signals.c procsup.c
proc.c
Log:
NetWare port of the threadproc functions
Revision Changes Path
1.1 apr/threadproc/NetWare/threadpriv.c
Index: threadpriv.c
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 The Apache Software Foundation. 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. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
* ITS 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
#include "apr_portable.h"
#include "threadproc.h"
apr_status_t apr_threadkey_private_create(apr_threadkey_t **key,
void (*dest)(void *), apr_pool_t *cont)
{
apr_status_t stat;
(*key) = (apr_threadkey_t *)apr_palloc(cont, sizeof(apr_threadkey_t));
if ((*key) == NULL) {
return APR_ENOMEM;
}
(*key)->cntxt = cont;
if ((stat = NXKeyCreate(NULL, dest, &(*key)->key)) == 0) {
return stat;
}
return stat;
}
apr_status_t apr_threadkey_private_get(void **new, apr_threadkey_t *key)
{
apr_status_t stat;
if ((stat = NXKeyGetValue(key->key, new)) == 0) {
return APR_SUCCESS;
}
else {
return stat;
}
}
apr_status_t apr_threadkey_private_set(void *priv, apr_threadkey_t *key)
{
apr_status_t stat;
if ((stat = NXKeySetValue(key->key, priv)) == 0) {
return APR_SUCCESS;
}
else {
return stat;
}
}
apr_status_t apr_threadkey_private_delete(apr_threadkey_t *key)
{
apr_status_t stat;
if ((stat = NXKeyDelete(key->key)) == 0) {
return APR_SUCCESS;
}
return stat;
}
apr_status_t apr_threadkey_data_get(void **data, const char *key, apr_threadkey_t *threadkey)
{
return apr_pool_userdata_get(data, key, threadkey->cntxt);
}
apr_status_t apr_threadkey_data_set(void *data,
const char *key, apr_status_t (*cleanup) (void *),
apr_threadkey_t *threadkey)
{
return apr_pool_userdata_set(data, key, cleanup, threadkey->cntxt);
}
apr_status_t apr_os_threadkey_get(apr_os_threadkey_t *thekey,
apr_threadkey_t *key)
{
thekey = &(key->key);
return APR_SUCCESS;
}
apr_status_t apr_os_threadkey_put(apr_threadkey_t **key,
apr_os_threadkey_t *thekey, apr_pool_t *cont)
{
if (cont == NULL) {
return APR_ENOPOOL;
}
if ((*key) == NULL) {
(*key) = (apr_threadkey_t *)apr_palloc(cont, sizeof(apr_threadkey_t));
(*key)->cntxt = cont;
}
(*key)->key = *thekey;
return APR_SUCCESS;
}
1.1 apr/threadproc/NetWare/thread.c
Index: thread.c
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 The Apache Software Foundation. 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. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
* ITS 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
#include "apr.h"
#include "apr_portable.h"
#include "threadproc.h"
apr_status_t apr_threadattr_create(apr_threadattr_t **new,
apr_pool_t *cont)
{
(*new) = (apr_threadattr_t *)apr_palloc(cont,
sizeof(apr_threadattr_t));
if ((*new) == NULL) {
return APR_ENOMEM;
}
(*new)->cntxt = cont;
return APR_SUCCESS;
}
apr_status_t apr_threadattr_detach_set(apr_threadattr_t *attr,apr_int32_t on)
{
attr->detach = on;
return APR_SUCCESS;
}
apr_status_t apr_threadattr_detach_get(apr_threadattr_t *attr)
{
if (attr->detach == 1)
return APR_DETACH;
return APR_NOTDETACH;
}
apr_status_t apr_thread_create(apr_thread_t **new,
apr_threadattr_t *attr,
apr_thread_start_t func,
void *data,
apr_pool_t *cont)
{
apr_status_t stat;
size_t stacksize;
long flags = NX_CTX_AUTO_CLEANUP;
char threadName[NX_MAX_OBJECT_NAME_LEN+1];
//srj added for nks giving the threads names
sprintf(threadName, "Apache-2.0 %003ld",data);
(*new) = (apr_thread_t *)apr_palloc(cont, sizeof(apr_thread_t));
if ((*new) == NULL) {
return APR_ENOMEM;
}
(*new)->cntxt = cont;
stat = apr_pool_create(&(*new)->cntxt, cont);
if (stat != APR_SUCCESS) {
return stat;
}
if (attr) {
stacksize = attr->stack_size;
if (attr->detach)
flags |= NX_THR_DETACHED;
else
flags |= NX_THR_JOINABLE;
}
else {
stacksize = APR_DEFAULT_STACK_SIZE;
flags |= NX_THR_JOINABLE;
}
(*new)->ctx = NXContextAlloc(
/* void(*start_routine)(void *arg)*/(void (*)(void *)) func,
/* void *arg */ data,
/* int priority */ NX_PRIO_MED,
/* NXSize_t stackSize */ stacksize,
/* long flags */ NX_CTX_NORMAL,
/* int *error */ &stat);
stat = NXContextSetName(
/* NXContext_t ctx */ (*new)->ctx,
/* const char *name */ threadName);
stat = NXThreadCreate(
/* NXContext_t context */ (*new)->ctx,
/* long flags */ flags,
/* NXThreadId_t *thread_id */ &(*new)->td);
if(stat==0)
return APR_SUCCESS;
return(stat);// if error
}
apr_os_thread_t apr_os_thread_current()
{
return NXThreadGetId();
}
int apr_os_thread_equal(apr_os_thread_t tid1, apr_os_thread_t tid2)
{
return (tid1 == tid2);
}
apr_status_t apr_thread_yield()
{
NXThreadYield();
return APR_SUCCESS;
}
apr_status_t apr_thread_exit(apr_thread_t *thd,
apr_status_t *retval)
{
apr_pool_destroy(thd->cntxt);
NXThreadExit((void *)*retval);
return APR_SUCCESS;
}
apr_status_t apr_thread_join(apr_status_t *retval,
apr_thread_t *thd)
{
apr_status_t stat;
NXThreadId_t dthr;
if ((stat = NXThreadJoin(thd->td, &dthr, (void *)&retval)) == 0) {
return APR_SUCCESS;
}
else {
return stat;
}
}
apr_status_t apr_thread_detach(apr_thread_t *thd)
{
return APR_SUCCESS;
}
apr_status_t apr_thread_data_get(void **data, const char *key,
apr_thread_t *thread)
{
if (thread != NULL) {
return apr_pool_userdata_get(data, key, thread->cntxt);
}
else {
data = NULL;
return APR_ENOTHREAD;
}
}
apr_status_t apr_thread_data_set(void *data, const char *key,
apr_status_t (*cleanup) (void *),
apr_thread_t *thread)
{
if (thread != NULL) {
return apr_pool_userdata_set(data, key, cleanup, thread->cntxt);
}
else {
data = NULL;
return APR_ENOTHREAD;
}
}
/*SRJ Need to resolve
APR_DECLARE(apr_status_t) apr_os_thread_get(apr_os_thread_t **thethd,
apr_thread_t *thd)
{
if (thd == NULL) {
return APR_ENOTHREAD;
}
*thethd = thd->td;
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_os_thread_put(apr_thread_t **thd,
apr_os_thread_t *thethd,
apr_pool_t *cont)
{
if (cont == NULL) {
return APR_ENOPOOL;
}
if ((*thd) == NULL) {
(*thd) = (apr_thread_t *)apr_palloc(cont, sizeof(apr_thread_t));
(*thd)->cntxt = cont;
}
(*thd)->td = thethd;
return APR_SUCCESS;
}
*/
1.1 apr/threadproc/NetWare/signals.c
Index: signals.c
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 The Apache Software Foundation. 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. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
* ITS 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
#include "threadproc.h"
#include <nks/thread.h>
#include "apr_private.h"
#include "apr_pools.h"
#include "apr_signal.h"
#include "apr_strings.h"
#define APR_WANT_SIGNAL
#include "apr_want.h"
#include <assert.h>
#if APR_HAS_THREADS && APR_HAVE_PTHREAD_H
#include <pthread.h>
#endif
apr_status_t apr_proc_kill(apr_proc_t *proc, int signum)
{
#ifndef NETWARE
if (kill(proc->pid, signum) == -1) {
return errno;
}
#endif
//srj need to find equal to kill or use sigterm in nks
//srj windows is using TerminateProcess here
//srj if ( NXThreadExit(proc->pid) != 0) {
//srj return errno;
//srj }
return APR_SUCCESS;
}
void apr_signal_init(apr_pool_t *pglobal)
{
}
const char *apr_signal_get_description(int signum)
{
return "unknown signal (not supported)";
}
static void *signal_thread_func(void *signal_handler)
{
return NULL;
}
apr_status_t apr_setup_signal_thread(void)
{
int rv = 0;
return rv;
}
1.1 apr/threadproc/NetWare/procsup.c
Index: procsup.c
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 The Apache Software Foundation. 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. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
* ITS 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
#include "threadproc.h"
apr_status_t apr_proc_detach(void)
{
#if 0
int x;
pid_t pgrp;
chdir("/");
#if !defined(MPE) && !defined(OS2) && !defined(TPF) && !defined(BEOS)
/* Don't detach for MPE because child processes can't survive the death of
the parent. */
if ((x = fork()) > 0)
exit(0);
else if (x == -1) {
perror("fork");
fprintf(stderr, "unable to fork new process\n");
exit(1); /* we can't do anything here, so just exit. */
}
/* RAISE_SIGSTOP(DETACH);*/
#endif
#if APR_HAVE_SETSID
if ((pgrp = setsid()) == -1) {
return errno;
}
#elif defined(NEXT) || defined(NEWSOS)
if (setpgrp(0, getpid()) == -1 || (pgrp = getpgrp(0)) == -1) {
return errno;
}
#elif defined(OS2) || defined(TPF)
/* OS/2 don't support process group IDs */
pgrp = getpid();
#elif defined(MPE)
/* MPE uses negative pid for process group */
pgrp = -getpid();
#else
if ((pgrp = setpgid(0, 0)) == -1) {
return errno;
}
#endif
/* close out the standard file descriptors */
if (freopen("/dev/null", "r", stdin) == NULL) {
return errno;
/* continue anyhow -- note we can't close out descriptor 0 because we
* have nothing to replace it with, and if we didn't have a descriptor
* 0 the next file would be created with that value ... leading to
* havoc.
*/
}
if (freopen("/dev/null", "w", stdout) == NULL) {
return errno;
}
/* We are going to reopen this again in a little while to the error
* log file, but better to do it twice and suffer a small performance
* hit for consistancy than not reopen it here.
*/
if (freopen("/dev/null", "w", stderr) == NULL) {
return errno;
}
#endif
return APR_SUCCESS;
}
#if 0
#if (!HAVE_WAITPID)
/* From ikluft@amdahl.com
* this is not ideal but it works for SVR3 variants
* Modified by dwd@bell-labs.com to call wait3 instead of wait because
* apache started to use the WNOHANG option.
*/
int waitpid(pid_t pid, int *statusp, int options)
{
int tmp_pid;
if (kill(pid, 0) == -1) {
errno = ECHILD;
return -1;
}
while (((tmp_pid = wait3(statusp, options, 0)) != pid) &&
(tmp_pid != -1) && (tmp_pid != 0) && (pid != -1))
;
return tmp_pid;
}
#endif
#endif
1.1 apr/threadproc/NetWare/proc.c
Index: proc.c
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 The Apache Software Foundation. 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. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
* ITS 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
#include "threadproc.h"
#include "fileio.h"
#include "apr_strings.h"
#include "apr_portable.h"
/*
* some of the ideas expressed herein are based off of Microsoft
* Knowledge Base article: Q190351
*
*/
apr_status_t apr_procattr_create(apr_procattr_t **new,apr_pool_t *cont)
{
(*new) = (apr_procattr_t *)apr_pcalloc(cont, sizeof(apr_procattr_t));
if ((*new) == NULL) {
return APR_ENOMEM;
}
(*new)->cntxt = cont;
(*new)->cmdtype = APR_PROGRAM;
return APR_SUCCESS;
}
apr_status_t apr_procattr_io_set(apr_procattr_t *attr, apr_int32_t in,
apr_int32_t out, apr_int32_t err)
{
apr_status_t status;
if (in != 0) {
if ((status = apr_file_pipe_create(&attr->child_in, &attr->parent_in,
attr->cntxt)) != APR_SUCCESS) {
return status;
}
switch (in) {
case APR_FULL_BLOCK:
break;
case APR_PARENT_BLOCK:
apr_file_pipe_timeout_set(attr->child_in, 0);
break;
case APR_CHILD_BLOCK:
apr_file_pipe_timeout_set(attr->parent_in, 0);
break;
default:
apr_file_pipe_timeout_set(attr->child_in, 0);
apr_file_pipe_timeout_set(attr->parent_in, 0);
}
}
if (out) {
if ((status = apr_file_pipe_create(&attr->parent_out, &attr->child_out,
attr->cntxt)) != APR_SUCCESS) {
return status;
}
switch (out) {
case APR_FULL_BLOCK:
break;
case APR_PARENT_BLOCK:
apr_file_pipe_timeout_set(attr->child_out, 0);
break;
case APR_CHILD_BLOCK:
apr_file_pipe_timeout_set(attr->parent_out, 0);
break;
default:
apr_file_pipe_timeout_set(attr->child_out, 0);
apr_file_pipe_timeout_set(attr->parent_out, 0);
}
}
if (err) {
if ((status = apr_file_pipe_create(&attr->parent_err, &attr->child_err,
attr->cntxt)) != APR_SUCCESS) {
return status;
}
switch (err) {
case APR_FULL_BLOCK:
break;
case APR_PARENT_BLOCK:
apr_file_pipe_timeout_set(attr->child_err, 0);
break;
case APR_CHILD_BLOCK:
apr_file_pipe_timeout_set(attr->parent_err, 0);
break;
default:
apr_file_pipe_timeout_set(attr->child_err, 0);
apr_file_pipe_timeout_set(attr->parent_err, 0);
}
}
return APR_SUCCESS;
}
apr_status_t apr_procattr_child_in_set(apr_procattr_t *attr, apr_file_t *child_in,
apr_file_t *parent_in)
{
if (attr->child_in == NULL && attr->parent_in == NULL)
apr_file_pipe_create(&attr->child_in, &attr->parent_in, attr->cntxt);
if (child_in != NULL)
apr_file_dup(&attr->child_in, child_in, attr->cntxt);
if (parent_in != NULL)
apr_file_dup(&attr->parent_in, parent_in, attr->cntxt);
return APR_SUCCESS;
}
apr_status_t apr_procattr_child_out_set(apr_procattr_t *attr, apr_file_t *child_out,
apr_file_t *parent_out)
{
if (attr->child_out == NULL && attr->parent_out == NULL)
apr_file_pipe_create(&attr->child_out, &attr->parent_out, attr->cntxt);
if (child_out != NULL)
apr_file_dup(&attr->child_out, child_out, attr->cntxt);
if (parent_out != NULL)
apr_file_dup(&attr->parent_out, parent_out, attr->cntxt);
return APR_SUCCESS;
}
apr_status_t apr_procattr_child_err_set(apr_procattr_t *attr, apr_file_t *child_err,
apr_file_t *parent_err)
{
if (attr->child_err == NULL && attr->parent_err == NULL)
apr_file_pipe_create(&attr->child_err, &attr->parent_err, attr->cntxt);
if (child_err != NULL)
apr_file_dup(&attr->child_err, child_err, attr->cntxt);
if (parent_err != NULL)
apr_file_dup(&attr->parent_err, parent_err, attr->cntxt);
return APR_SUCCESS;
}
apr_status_t apr_procattr_dir_set(apr_procattr_t *attr,
const char *dir)
{
attr->currdir = apr_pstrdup(attr->cntxt, dir);
if (attr->currdir) {
return APR_SUCCESS;
}
return APR_ENOMEM;
}
apr_status_t apr_procattr_cmdtype_set(apr_procattr_t *attr,
apr_cmdtype_e cmd)
{
attr->cmdtype = cmd;
return APR_SUCCESS;
}
apr_status_t apr_procattr_detach_set(apr_procattr_t *attr, apr_int32_t detach)
{
attr->detached = detach;
return APR_SUCCESS;
}
apr_status_t apr_proc_fork(apr_proc_t *proc, apr_pool_t *cont)
{
#if 0
int pid;
if ((pid = fork()) < 0) {
return errno;
}
else if (pid == 0) {
proc->pid = pid;
proc->in = NULL;
proc->out = NULL;
proc->err = NULL;
return APR_INCHILD;
}
proc->pid = pid;
proc->in = NULL;
proc->out = NULL;
proc->err = NULL;
#endif
return APR_INPARENT;
}
static apr_status_t limit_proc(apr_procattr_t *attr)
{
#if APR_HAVE_STRUCT_RLIMIT && APR_HAVE_SETRLIMIT
#ifdef RLIMIT_CPU
if (attr->limit_cpu != NULL) {
if ((setrlimit(RLIMIT_CPU, attr->limit_cpu)) != 0) {
return errno;
}
}
#endif
#ifdef RLIMIT_NPROC
if (attr->limit_nproc != NULL) {
if ((setrlimit(RLIMIT_NPROC, attr->limit_nproc)) != 0) {
return errno;
}
}
#endif
#if defined(RLIMIT_AS)
if (attr->limit_mem != NULL) {
if ((setrlimit(RLIMIT_AS, attr->limit_mem)) != 0) {
return errno;
}
}
#elif defined(RLIMIT_DATA)
if (attr->limit_mem != NULL) {
if ((setrlimit(RLIMIT_DATA, attr->limit_mem)) != 0) {
return errno;
}
}
#elif defined(RLIMIT_VMEM)
if (attr->limit_mem != NULL) {
if ((setrlimit(RLIMIT_VMEM, attr->limit_mem)) != 0) {
return errno;
}
}
#endif
#else
/*
* Maybe make a note in error_log that setrlimit isn't supported??
*/
#endif
return APR_SUCCESS;
}
apr_status_t apr_proc_create(apr_proc_t *new,
const char *progname,
const char * const *args,
const char * const *env,
apr_procattr_t *attr,
apr_pool_t *cont)
{
#if 0
int i;
const char **newargs;
new->in = attr->parent_in;
new->err = attr->parent_err;
new->out = attr->parent_out;
if ((new->pid = fork()) < 0) {
return errno;
}
else if (new->pid == 0) {
int status;
/* child process */
if (attr->child_in) {
apr_file_close(attr->parent_in);
dup2(attr->child_in->filedes, STDIN_FILENO);
apr_file_close(attr->child_in);
}
if (attr->child_out) {
apr_file_close(attr->parent_out);
dup2(attr->child_out->filedes, STDOUT_FILENO);
apr_file_close(attr->child_out);
}
if (attr->child_err) {
apr_file_close(attr->parent_err);
dup2(attr->child_err->filedes, STDERR_FILENO);
apr_file_close(attr->child_err);
}
apr_signal(SIGCHLD, SIG_DFL); /*not sure if this is needed or not */
if (attr->currdir != NULL) {
if (chdir(attr->currdir) == -1) {
exit(-1); /* We have big problems, the child should exit. */
}
}
apr_pool_cleanup_for_exec();
if ((status = limit_proc(attr)) != APR_SUCCESS) {
return status;
}
if (attr->cmdtype == APR_SHELLCMD) {
i = 0;
while (args[i]) {
i++;
}
newargs =
(const char **) apr_palloc(cont, sizeof (char *) * (i + 3));
newargs[0] = SHELL_PATH;
newargs[1] = "-c";
i = 0;
while (args[i]) {
newargs[i + 2] = args[i];
i++;
}
newargs[i + 2] = NULL;
if (attr->detached) {
apr_proc_detach();
}
execve(SHELL_PATH, (char * const *) newargs, (char * const *)env);
}
else {
if (attr->detached) {
apr_proc_detach();
}
execve(progname, (char * const *)args, (char * const *)env);
}
exit(-1); /* if we get here, there is a problem, so exit with an */
/* error code. */
}
/* Parent process */
if (attr->child_in) {
apr_file_close(attr->child_in);
}
if (attr->child_out) {
apr_file_close(attr->child_out);
}
if (attr->child_err) {
apr_file_close(attr->child_err);
}
#endif
return APR_SUCCESS;
}
apr_status_t apr_proc_wait_all_procs(apr_proc_t *proc, apr_wait_t *status,
apr_wait_how_e waithow, apr_pool_t *p)
{
#if 0
int waitpid_options = WUNTRACED;
if (waithow != APR_WAIT) {
waitpid_options |= WNOHANG;
}
if ((proc->pid = waitpid(-1, status, waitpid_options)) > 0) {
return APR_CHILD_DONE;
}
else if (proc->pid == 0) {
return APR_CHILD_NOTDONE;
}
#endif
return errno;
}
apr_status_t apr_proc_wait(apr_proc_t *proc,
apr_wait_how_e waithow)
{
#if 0
pid_t status;
if (waithow == APR_WAIT) {
if ((status = waitpid(proc->pid, NULL, WUNTRACED)) > 0) {
return APR_CHILD_DONE;
}
else if (status == 0) {
return APR_CHILD_NOTDONE;
}
return errno;
}
if ((status = waitpid(proc->pid, NULL, WUNTRACED | WNOHANG)) > 0) {
return APR_CHILD_DONE;
}
else if (status == 0) {
return APR_CHILD_NOTDONE;
}
#endif
return errno;
}
apr_status_t apr_procattr_limit_set(apr_procattr_t *attr, apr_int32_t what,
struct rlimit *limit)
{
switch(what) {
case APR_LIMIT_CPU:
#ifdef RLIMIT_CPU
attr->limit_cpu = limit;
break;
#else
return APR_ENOTIMPL;
#endif
case APR_LIMIT_MEM:
#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)
attr->limit_mem = limit;
break;
#else
return APR_ENOTIMPL;
#endif
case APR_LIMIT_NPROC:
#ifdef RLIMIT_NPROC
attr->limit_nproc = limit;
break;
#else
return APR_ENOTIMPL;
#endif
}
return APR_SUCCESS;
}