rbb 99/09/10 07:00:49
Modified: src/lib/apr Makefile.in src/lib/apr/file_io/beos fileacc.c fileio.h open.c readwrite.c src/lib/apr/lib apr_getpass.c src/lib/apr/test htdigest.c src/lib/apr/threadproc/beos Makefile.in proc.c threadproc.h src/lib/apr/time/beos access.c Added: src/lib/apr/threadproc/beos apr_proc_stub.c procsup.c Log: More changes to bring BeOS up to the UNIX APR level. Also a few changes to some test programs to make them more portable. Lastly, a work around for a BeOS bug that makes fork potentially dangerous. Submitted by: David Reid Revision Changes Path 1.7 +0 -1 apache-2.0/src/lib/apr/Makefile.in Index: Makefile.in =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/Makefile.in,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- Makefile.in 1999/09/03 18:40:39 1.6 +++ Makefile.in 1999/09/10 14:00:42 1.7 @@ -51,7 +51,6 @@ distclean: clean -$(RM) -f Makefile - -$(RM) -f config.log config.status config.cache subdirs: @for i in $(SUBDIRS); do \ 1.2 +49 -0 apache-2.0/src/lib/apr/file_io/beos/fileacc.c Index: fileacc.c =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/beos/fileacc.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- fileacc.c 1999/08/17 15:59:35 1.1 +++ fileacc.c 1999/09/10 14:00:43 1.2 @@ -162,3 +162,52 @@ } } +ap_status_t ap_get_filetype(struct file_t *file, ap_filetype_e *type) +{ + if (file != NULL) { + if (!file->stated) { + ap_getfileinfo(file); + } + if (S_ISREG(file->protection)) + *type = APR_REG; + if (S_ISDIR(file->protection)) + *type = APR_DIR; + if (S_ISCHR(file->protection)) + *type = APR_CHR; + if (S_ISBLK(file->protection)) + *type = APR_BLK; + if (S_ISFIFO(file->protection)) + *type = APR_PIPE; + if (S_ISLNK(file->protection)) + *type = APR_LNK; + return APR_SUCCESS; + } + else { + *type = APR_REG; + return APR_ENOFILE; + } +} + +ap_status_t ap_get_filedata(struct file_t *file, void *data) +{ + if (file != NULL) { + return ap_get_userdata(file->cntxt, &data); + } + else { + data = NULL; + return APR_ENOFILE; + } +} + +ap_status_t ap_set_filedata(struct file_t *file, void *data) +{ + if (file != NULL) { + return ap_set_userdata(file->cntxt, data); + } + else { + data = NULL; + return APR_ENOFILE; + } +} + + 1.2 +4 -0 apache-2.0/src/lib/apr/file_io/beos/fileio.h Index: fileio.h =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/beos/fileio.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- fileio.h 1999/08/17 15:59:35 1.1 +++ fileio.h 1999/09/10 14:00:43 1.2 @@ -71,8 +71,12 @@ struct file_t { ap_context_t *cntxt; int filedes; + FILE *filehand; char * fname; + int oflags; int buffered; + int stated; + int eof_hit; mode_t protection; uid_t user; gid_t group; 1.3 +41 -1 apache-2.0/src/lib/apr/file_io/beos/open.c Index: open.c =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/beos/open.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- open.c 1999/09/07 13:16:26 1.2 +++ open.c 1999/09/10 14:00:43 1.3 @@ -66,6 +66,7 @@ #include "apr_file_io.h" #include "apr_general.h" #include "apr_lib.h" +#include "apr_portable.h" ap_status_t file_cleanup(void *thefile) { @@ -163,4 +164,43 @@ else { return errno; } -} +} + +ap_status_t ap_get_os_file(struct file_t *file, ap_os_file_t *thefile) +{ + if (file == NULL) { + return APR_ENOFILE; + } + thefile = &(file->filedes); + return APR_SUCCESS; +} + +ap_status_t ap_put_os_file(ap_context_t *cont, struct file_t **file, + ap_os_file_t *thefile) +{ + if (cont == NULL) { + return APR_ENOCONT; + } + if ((*file) == NULL) { + (*file) = (struct file_t *)ap_palloc(cont, sizeof(struct file_t)); + (*file)->cntxt = cont; + } + (*file)->filedes = *thefile; + return APR_SUCCESS; +} + +ap_status_t ap_eof(ap_file_t *fptr) +{ + char ch; + if (fptr->buffered) { + if (feof(fptr->filehand) == 0) { + return APR_SUCCESS; + } + return APR_EOF; + } + if (fptr->eof_hit == 1) { + return APR_EOF; + } + APR_SUCCESS; +} + 1.3 +104 -0 apache-2.0/src/lib/apr/file_io/beos/readwrite.c Index: readwrite.c =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/beos/readwrite.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- readwrite.c 1999/09/07 13:16:32 1.2 +++ readwrite.c 1999/09/10 14:00:43 1.3 @@ -59,6 +59,7 @@ #include "apr_file_io.h" #include "apr_general.h" #include "apr_errno.h" +#include "apr_lib.h" ap_status_t ap_read(struct file_t *thefile, void *buf, ap_ssize_t *nbytes) { @@ -109,4 +110,107 @@ *iocnt = bytes; return APR_SUCCESS; } +} + +ap_status_t ap_putc(ap_file_t *thefile, char ch) +{ + if (thefile->buffered) { + if (fputc(ch, thefile->filehand) == ch) { + return APR_SUCCESS; + } + return errno; + } + if (write(thefile->filedes, &ch, 1) != 1) { + return errno; + } + return APR_SUCCESS; +} + +ap_status_t ap_getc(ap_file_t *thefile, char *ch) +{ + ssize_t rv; + + if (thefile->buffered) { + if ((*ch) = fgetc(thefile->filehand)) { + return APR_SUCCESS; + } + if (feof(thefile->filehand)) { + return APR_EOF; + } + return errno; + } + rv = read(thefile->filedes, ch, 1); + if (rv == 0) { + thefile->eof_hit = TRUE; + return APR_EOF; + } + else if (rv != 1) { + return errno; + } + return APR_SUCCESS; +} + +ap_status_t ap_gets(ap_file_t *thefile, char *str, int len) +{ + ssize_t rv; + int i; + + if (thefile->buffered) { + if (fgets(str, len, thefile->filehand)) { + return APR_SUCCESS; + } + if (feof(thefile->filehand)) { + return APR_EOF; + } + return errno; + } + for (i = 0; i < len; i++) { + rv = read(thefile->filedes, &str[i], 1); + if (rv == 0) { + thefile->eof_hit = TRUE; + return APR_EOF; + } + else if (rv != 1) { + return errno; + } + if (str[i] == '\n' || str[i] == '\r') + break; + } + return APR_SUCCESS; +} + +static int printf_flush(ap_vformatter_buff_t *vbuff) +{ + /* I would love to print this stuff out to the file, but I will + * get that working later. :) For now, just return. + */ + return -1; +} + +API_EXPORT(int) ap_fprintf(struct file_t *fptr, const char *format, ...) +{ + int cc; + va_list ap; + ap_vformatter_buff_t vbuff; + char *buf; + int len; + + buf = malloc(HUGE_STRING_LEN); + if (buf == NULL) { + return 0; + } + /* save one byte for nul terminator */ + vbuff.curpos = buf; + vbuff.endpos = buf + len - 1; + va_start(ap, format); +#if 0 + cc = ap_vformatter(printf_flush, &vbuff, format, ap); + va_end(ap); + *vbuff.curpos = '\0'; +#endif + vsprintf(buf, format, ap); + len = strlen(buf); + cc = ap_write(fptr, buf, &len); + va_end(ap); + return (cc == -1) ? len : cc; } 1.5 +1 -2 apache-2.0/src/lib/apr/lib/apr_getpass.c Index: apr_getpass.c =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/lib/apr_getpass.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- apr_getpass.c 1999/09/01 14:38:37 1.4 +++ apr_getpass.c 1999/09/10 14:00:45 1.5 @@ -141,8 +141,7 @@ } password[n] = '\0'; - fprintf(stderr, "********************\n"); - + printf("\n"); if (n > (MAX_STRING_LEN - 1)) { password[MAX_STRING_LEN - 1] = '\0'; } 1.3 +3 -3 apache-2.0/src/lib/apr/test/htdigest.c Index: htdigest.c =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/test/htdigest.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- htdigest.c 1999/08/31 05:32:51 1.2 +++ htdigest.c 1999/09/10 14:00:46 1.3 @@ -69,10 +69,10 @@ #include "apr_lib.h" #include "apr_md5.h" #include <sys/types.h> -#if defined(MPE) || defined(QNX) || defined(WIN32) -#include <signal.h> -#else +#ifdef HAVE_SYS_SIGNAL_H #include <sys/signal.h> +#else +#include <signal.h> #endif #ifdef WIN32 1.3 +8 -19 apache-2.0/src/lib/apr/threadproc/beos/Makefile.in Index: Makefile.in =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/threadproc/beos/Makefile.in,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Makefile.in 1999/08/27 16:26:08 1.2 +++ Makefile.in 1999/09/10 14:00:46 1.3 @@ -19,15 +19,21 @@ thread.o \ threadcancel.o \ threadpriv.o \ - signals.o + signals.o \ + procsup.o \ + apr_proc_stub .c.o: $(CC) $(CFLAGS) -c $(INCLUDES) $< all: $(LIB) +apr_proc_stub: + $(CC) apr_proc_stub.c \ + && cp apr_proc_stub /boot/home/config/bin + clean: - $(RM) -f *.o *.a *.so + $(RM) -f *.o *.a *.so /boot/home/config/bin/apr_proc_stub apr_proc_stub distclean: clean -$(RM) -f Makefile @@ -54,20 +60,3 @@ && rm Makefile.new # DO NOT REMOVE -proc.o: proc.c threadproc.h ../../include/apr_thread_proc.h \ - ../../include/apr_file_io.h ../../include/apr_general.h \ - ../../include/apr_errno.h ../../file_io/beos/fileio.h -signals.o: signals.c threadproc.h ../../include/apr_thread_proc.h \ - ../../include/apr_file_io.h ../../include/apr_general.h \ - ../../include/apr_errno.h ../../file_io/beos/fileio.h -thread.o: thread.c threadproc.h ../../include/apr_thread_proc.h \ - ../../include/apr_file_io.h ../../include/apr_general.h \ - ../../include/apr_errno.h ../../file_io/beos/fileio.h -threadcancel.o: threadcancel.c threadproc.h \ - ../../include/apr_thread_proc.h ../../include/apr_file_io.h \ - ../../include/apr_general.h ../../include/apr_errno.h \ - ../../file_io/beos/fileio.h -threadpriv.o: threadpriv.c threadproc.h \ - ../../include/apr_thread_proc.h ../../include/apr_file_io.h \ - ../../include/apr_general.h ../../include/apr_errno.h \ - ../../file_io/beos/fileio.h 1.3 +68 -60 apache-2.0/src/lib/apr/threadproc/beos/proc.c Index: proc.c =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/threadproc/beos/proc.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- proc.c 1999/09/07 13:17:02 1.2 +++ proc.c 1999/09/10 14:00:46 1.3 @@ -62,6 +62,13 @@ #include "apr_file_io.h" #include "apr_general.h" +struct send_pipe { + int in; + int out; + int err; + char ** envp; +}; + ap_status_t ap_createprocattr_init(ap_context_t *cont, struct procattr_t **new) { (*new) = (struct procattr_t *)ap_palloc(cont, @@ -110,7 +117,16 @@ ap_status_t ap_setprocattr_dir(struct procattr_t *attr, char *dir) { - attr->currdir = (char *)ap_pstrdup(attr->cntxt, dir); + char * cwd; + if (strncmp("/",dir,1) != 0 ) { + cwd = (char*)malloc(sizeof(char) * PATH_MAX); + getcwd(cwd, PATH_MAX); + strncat(cwd,"/\0",2); + strcat(cwd,dir); + attr->currdir = (char *)ap_pstrdup(attr->cntxt, cwd); + } else { + attr->currdir = (char *)ap_pstrdup(attr->cntxt, dir); + } if (attr->currdir) { return APR_SUCCESS; } @@ -149,79 +165,71 @@ return APR_INPARENT; } + ap_status_t ap_create_process(ap_context_t *cont, char *progname, char *const args[], char **env, struct procattr_t *attr, struct proc_t **new) { - int i; - char **newargs; + int i=0,nargs=0; + char **newargs = NULL; + thread_id newproc, sender; + char * buffer = NULL; + size_t bufsize = 0; + struct send_pipe *sp; + char * dir = NULL; + (*new) = (struct proc_t *)ap_palloc(cont, sizeof(struct proc_t)); + sp = (struct send_pipe *)ap_palloc(cont, sizeof(struct send_pipe)); if ((*new) == NULL){ return APR_ENOMEM; } (*new)->cntxt = cont; - if (((*new)->pid = fork()) < 0) { + + sp->in = attr->child_in?attr->child_in->filedes:-1; + sp->out = attr->child_out?attr->child_out->filedes:-1; + sp->err = attr->child_err?attr->child_err->filedes:-1; + sp->envp = env; + + i = 0; + while (args[i]) { + i++; + } + + newargs = (char**)malloc(sizeof(char *) * (i + 3)); + newargs[0] = strdup("/boot/home/config/bin/apr_proc_stub"); + if (attr->currdir == NULL) { + /* we require the directory ! */ + dir = malloc(sizeof(char) * PATH_MAX); + getcwd(dir, PATH_MAX); + newargs[1] = strdup(dir); + free(dir); + } else { + newargs[1] = attr->currdir; + } + newargs[2] = strdup(progname); + i=0;nargs = 3; + while (args[i]) { + newargs[nargs] = args[i]; + i++;nargs++; + } + newargs[nargs] = NULL; + + newproc = load_image(nargs, newargs, env); + free(newargs); + if ( newproc < B_NO_ERROR) { return errno; } - else if ((*new)->pid == 0) { - /* child process */ - if (attr->child_in) { - ap_close(attr->parent_in); - dup2(attr->child_in->filedes, STDIN_FILENO); - ap_close(attr->child_in); - } - if (attr->child_out) { - ap_close(attr->parent_out); - dup2(attr->child_out->filedes, STDOUT_FILENO); - ap_close(attr->child_out); - } - if (attr->child_err) { - ap_close(attr->parent_err); - dup2(attr->child_err->filedes, STDERR_FILENO); - ap_close(attr->child_err); - } - - signal(SIGCHLD, SIG_DFL); /*not sure if this is needed or not */ + resume_thread(newproc); + send_data(newproc, 0, (void*)sp, sizeof(struct send_pipe)); + + (*new)->pid = newproc; - if (attr->currdir != NULL) { - if (chdir(attr->currdir) == -1) { - exit(-1); /* We have big problems, the child should exit. */ - } - } - if (attr->cmdtype == APR_SHELLCMD) { - i = 0; - while (args[i]) { - i++; - } - newargs = (char **)ap_palloc(cont, sizeof (char *) * (i + 3)); - newargs[0] = strdup(SHELL_PATH); - newargs[1] = strdup("-c"); - i = 0; - while (args[i]) { - newargs[i + 2] = strdup(args[i]); - i++; - } - newargs[i + 3] = NULL; - execve(SHELL_PATH, newargs, env); - } - else { - execve(progname, args, env); - } - exit(-1); /* if we get here, there is a problem, so exit with an */ - /* error code. */ - } - /* Parent process */ - if (attr->child_in) { - ap_close(attr->child_in); - } - if (attr->child_out) { - ap_close(attr->child_out); - } - if (attr->child_err) { - ap_close(attr->child_err); - } + /* before we go charging on we need the new process to get to a + * certain point. When it gets there it'll let us know and we + * can carry on. */ + receive_data(&sender, (void*)NULL,0); (*new)->attr = attr; return APR_SUCCESS; 1.3 +3 -0 apache-2.0/src/lib/apr/threadproc/beos/threadproc.h Index: threadproc.h =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/threadproc/beos/threadproc.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- threadproc.h 1999/09/07 13:17:03 1.2 +++ threadproc.h 1999/09/10 14:00:47 1.3 @@ -121,5 +121,8 @@ struct procattr_t *attr; }; +/* we need a structure to pass off to the thread that will run any + * new process we create */ + #endif /* ! THREAD_PROC_H */ 1.1 apache-2.0/src/lib/apr/threadproc/beos/apr_proc_stub.c Index: apr_proc_stub.c =================================================================== #include <kernel/OS.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> struct pipefd { int in; int out; int err; char ** envp; }; int main(int argc, char *argv[]) { /* we expect the following... * * argv[0] = this stub * argv[1] = directory to run in... * argv[2] = progname to execute * rest of arguments to be passed to program */ char *progname = argv[2]; char *directory = argv[1]; struct pipefd *pfd; thread_id sender; void *buffer; int indes[2]; int outdes[2]; int errdes[2]; char ** newargs; int i = 0; char * readbuffer; size_t readbuf = 100; readbuffer = (char*)malloc(sizeof(char) * readbuf); newargs = (char**)malloc(sizeof(char) * (argc - 1)); buffer = (void*)malloc(sizeof(struct pipefd)); /* this will block until we get the data */ receive_data(&sender, buffer, sizeof(struct pipefd)); pfd = (struct pipefd*)buffer; if (pfd->in > STDERR_FILENO) { if (pipe(indes) == -1)return (-1); if (dup2(pfd->in, indes[0]) != indes[0]) return (-1); if (dup2(indes[0], STDIN_FILENO) != STDIN_FILENO) return (-1); } if (pfd->out > STDERR_FILENO) { if (pipe(outdes) == -1)return (-1); if (dup2(pfd->out, outdes[1]) != outdes[1]) return (-1); if (dup2(outdes[1], STDOUT_FILENO) != STDOUT_FILENO) return (-1); } if (pfd->err > STDERR_FILENO) { if (pipe(errdes) == -1)return (-1); if (dup2(pfd->err, errdes[1]) != errdes[1]) return (-1); if (dup2(errdes[1], STDERR_FILENO) != STDERR_FILENO) return (-1); } for (i=3;i<=argc;i++){ newargs[i-3] = argv[i]; } /* tell the caller we're OK to start */ send_data(sender,1,NULL,0); if (directory != NULL) chdir(directory); execve (progname, newargs, pfd->envp); return (-1); } 1.1 apache-2.0/src/lib/apr/threadproc/beos/procsup.c Index: procsup.c =================================================================== /* ==================================================================== * Copyright (c) 1999 The Apache Group. 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 the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * 4. The names "Apache Server" and "Apache Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``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 GROUP 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 Group. * For more information on the Apache Group and the Apache HTTP server * project, please see <http://www.apache.org/>. * */ #include "threadproc.h" #include "fileio.h" #include "apr_config.h" #include "apr_thread_proc.h" #include "apr_file_io.h" #include "apr_general.h" #include "apr_lib.h" ap_status_t ap_detach(ap_context_t *cont, struct proc_t **new) { int x; (*new) = (struct proc_t *)ap_palloc(cont, sizeof(struct proc_t)); (*new)->cntxt = cont; (*new)->attr = NULL; chdir("/"); if (((*new)->pid = setsid()) == -1) { return errno; } /* close out the standard file descriptors */ if (freopen("/dev/null", "r", stdin) == NULL) { return APR_ALLSTD; /* 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 APR_STDOUT; } /* 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 APR_STDERR; } } ap_status_t ap_get_procdata(struct proc_t *proc, void *data) { if (proc != NULL) { return ap_get_userdata(proc->cntxt, &data); } else { data = NULL; return APR_ENOPROC; } } ap_status_t ap_set_procdata(struct proc_t *proc, void *data) { if (proc != NULL) { return ap_set_userdata(proc->cntxt, data); } else { data = NULL; return APR_ENOPROC; } } 1.2 +1 -1 apache-2.0/src/lib/apr/time/beos/access.c Index: access.c =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/time/beos/access.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- access.c 1999/08/17 15:59:51 1.1 +++ access.c 1999/09/10 14:00:49 1.2 @@ -63,7 +63,7 @@ ap_status_t ap_get_curtime(struct atime_t *time, ap_int64_t *rv) { if (time) { - (*rv) = time->currtime; + (*rv) = time->currtime->tv_sec; return APR_SUCCESS; } return APR_ENOTIME;