⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os.c

📁 apache 安装教程 apache 安装教程
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * This file will include OS specific functions which are not inlineable. * Any inlineable functions should be defined in os-inline.c instead. */#include "httpd.h"#include "http_core.h"#include "os.h"#include "scoreboard.h"#include "http_log.h"#include "http_conf_globals.h"#ifdef TPF41#ifdef __PIPE_#include <ipc.h>#include <shm.h>static TPF_FD_LIST *tpf_fds = NULL;#endif /* __PIPE_ */#else#include <sys/ipc.h>  #include <sys/shm.h>static TPF_FD_LIST *tpf_fds = NULL;#endif /* TPF41 */void *tpf_shm_static_ptr = NULL;unsigned short zinet_model;char *argv_ptr = NULL;static FILE *sock_fp;static int   sock_sd;int tpf_select(int maxfds, fd_set *reads, fd_set *writes, fd_set *excepts,               struct timeval *tv){/* We're going to force our way through select.  We're only interested reads   and TPF allows 2billion+ socket descriptors for we don't want an fd_set   that big.  Just assume that maxfds-1 contains the socket descriptor we're   interested in.  If it's 0, leave it alone. */    int sockets[1];    int no_reads = 0;    int no_writes = 0;    int no_excepts = 0;    int timeout_seconds = 0;    int timeout_millisec = 0;    int rv = 0;        if(maxfds) {        if(tv)            timeout_millisec = tv->tv_sec * 1000 + tv->tv_usec;        sockets[0] = maxfds-1;        no_reads++;    }        else        sockets[0] = 0;            ap_check_signals();    if ((no_reads + no_writes + no_excepts == 0) &&        (tv) && (tv->tv_sec + tv->tv_usec != 0)) {        /* TPF's select immediately returns if the sum of           no_reads, no_writes, and no_excepts is zero.           The following code makes TPF's select work a little closer           to everyone else's select:        */#ifdef TPF_HAVE_SAWNC        struct ev0bk evnblock;#endif        /* event processing uses seconds, select uses milliseconds */        timeout_seconds = tv->tv_sec;        if (tv->tv_usec) {            timeout_seconds++;  /* round up to seconds (like TPF's select does) */        }        if (timeout_seconds > 0) { /* paranoid check for valid timeout */#ifdef TPF_HAVE_SAWNC            evnblock.evnpstinf.evnbkc1 = 1; /* nbr of posts needed */            evntc(&evnblock, EVENT_CNT, 'N', timeout_seconds, EVNTC_1052);            tpf_sawnc(&evnblock, EVENT_CNT);#else            sleep(timeout_seconds);#endif        }    } else {        if (timeout_millisec < 0) { /* paranoid check for valid timeout */            timeout_millisec = 0;        }        if (timeout_millisec != 0)            timeout_millisec += 1000;         rv = select(sockets, no_reads, no_writes, no_excepts, timeout_millisec);    }    ap_check_signals();        return rv;}int tpf_accept(int sockfd, struct sockaddr *peer, int *paddrlen){    extern pid_t tpf_parent_pid;    int socks[1];    int rv;    socks[0] = sockfd;    rv = select(socks, 1, 0, 0, 1 * 1000);    ap_check_signals();    if ((rv == 0) && (errno == 0)) {       /* select timed out */       errno = EINTR; /* make errno look like accept was interruped */       /* now's a good time to make sure our parent didn't abnormally exit */       if (getppid() == 1) {          /* our parent is gone... close the socket so Apache can restart             (it shouldn't still be open but we're taking no chances) */          closesocket(sockfd);          ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, NULL,                       "child %d closing the socket because getppid()"                       " returned 1 instead of parent pid %d",                       getpid(), tpf_parent_pid);          errno = 0;       }       return -1;    }    /* paranoid check for rv == 0 and errno != 0, should never happen */    if (rv == 0) {       rv = -1;    }    if(rv>0) {        rv = accept(sockfd, peer, paddrlen);        errno = sock_errno();    }        return rv;}   /* the getpass function is not usable on TPF */char *getpass(const char* prompt){    errno = EIO;    return((char *)NULL);}/* fork and exec functions are not defined on   TPF due to the implementation of tpf_fork() */ pid_t fork(void){    errno = ENOSYS;    return(-1);}int execl(const char *path, const char *arg0, ...){    errno = ENOSYS;    return(-1);}int execle(const char *path, const char *arg0, ...){    errno = ENOSYS;    return(-1);}int execve(const char *path, char *const argv[], char *const envp[]){    errno = ENOSYS;    return(-1);}int execvp(const char *file, char *const argv[]){    errno = ENOSYS;    return(-1);}int ap_tpf_spawn_child(pool *p, int (*func) (void *, child_info *),                       void *data, enum kill_conditions kill_how,                       int *pipe_in, int *pipe_out, int *pipe_err,                       int out_fds[], int in_fds[], int err_fds[]){   int                      i, temp_out=0, temp_in=0, temp_err=0, save_errno, pid, result=0;   int                      fd_flags_out=0, fd_flags_in=0, fd_flags_err=0;   struct tpf_fork_input    fork_input;   TPF_FORK_CHILD           *cld = (TPF_FORK_CHILD *) data;#ifdef TPF_FORK_EXTENDED#define WHITE " \t\n"#define MAXARGC 49   char                     *arguments;   char                     *args[MAXARGC + 1];   char                     **envp = NULL;   pool                     *subpool = NULL;#include "util_script.h"#else   array_header             *env_arr = ap_table_elts ((array_header *) cld->subprocess_env);   table_entry              *elts = (table_entry *) env_arr->elts;#endif /* TPF_FORK_EXTENDED */    if (func) {      if ((result=func(data, NULL))) {          return 0;                    /* error from child function */      }   }   if (pipe_out) {      fd_flags_out = fcntl(out_fds[0], F_GETFD);      fcntl(out_fds[0], F_SETFD, FD_CLOEXEC);      temp_out = dup(STDOUT_FILENO);      fcntl(temp_out, F_SETFD, FD_CLOEXEC);      dup2(out_fds[1], STDOUT_FILENO);   }   if (pipe_in) {      fd_flags_in = fcntl(in_fds[1], F_GETFD);      fcntl(in_fds[1], F_SETFD, FD_CLOEXEC);      temp_in = dup(STDIN_FILENO);      fcntl(temp_in, F_SETFD, FD_CLOEXEC);      dup2(in_fds[0], STDIN_FILENO);   }   if (pipe_err) {      fd_flags_err = fcntl(err_fds[0], F_GETFD);      fcntl(err_fds[0], F_SETFD, FD_CLOEXEC);      temp_err = dup(STDERR_FILENO);      fcntl(temp_err, F_SETFD, FD_CLOEXEC);      dup2(err_fds[1], STDERR_FILENO);   }/* set up environment variables for the tpf_fork */   if (cld->subprocess_env) {#ifdef TPF_FORK_EXTENDED   /* with extended tpf_fork( ) we pass the pointer to a list of pointers */   /* that point to "key=value" strings for each env variable             */       subpool = ap_make_sub_pool(p);      envp = ap_create_environment(subpool, cld->subprocess_env);#else   /* without extended tpf_fork( ) we setenv( ) each env variable */   /* so the child inherits them                                  */      for (i = 0; i < env_arr->nelts; ++i) {           if (!elts[i].key)               continue;           setenv (elts[i].key, elts[i].val, 1);       }#endif /* TPF_FORK_EXTENDED */   }   fork_input.program = (const char*) cld->filename;   fork_input.prog_type = cld->prog_type;   fork_input.istream = TPF_FORK_IS_BALANCE;   fork_input.ebw_data_length = 0;   fork_input.ebw_data = NULL;   fork_input.parm_data = NULL;#ifdef TPF_FORK_EXTENDED   /* use a copy of cld->filename because strtok is destructive */   arguments = ap_pstrdup(p, cld->filename);   args[0] = strtok(arguments, WHITE);   for (i = 0; i < MAXARGC && args[i] ; i++) {       args[i + 1] = strtok(NULL, WHITE);   }   args[MAXARGC] = NULL;   if ((pid = tpf_fork(&fork_input,                       (const char **)args,                       (const char **)envp)) < 0) {#else   if ((pid = tpf_fork(&fork_input)) < 0) {#endif /* TPF_FORK_EXTENDED */       save_errno = errno;       if (pipe_out) {           close(out_fds[0]);       }       if (pipe_in) {           close(in_fds[1]);       }       if (pipe_err) {           close(err_fds[0]);       }       errno = save_errno;       pid = 0;   }#ifdef TPF_FORK_EXTENDED   if (subpool) {       ap_destroy_pool(subpool);   }#else    if (cld->subprocess_env) {       for (i = 0; i < env_arr->nelts; ++i) {            if (!elts[i].key)                continue;            unsetenv (elts[i].key);       }   }#endif /* TPF_FORK_EXTENDED */   if (pipe_out) {       close(out_fds[1]);       dup2(temp_out, STDOUT_FILENO);       close(temp_out);       fcntl(out_fds[0], F_SETFD, fd_flags_out);   }   if (pipe_in) {       close(in_fds[0]);       dup2(temp_in, STDIN_FILENO);       close(temp_in);       fcntl(in_fds[1], F_SETFD, fd_flags_in);   }   if (pipe_err) {       close(err_fds[1]);       dup2(temp_err, STDERR_FILENO);       close(temp_err);       fcntl(err_fds[0], F_SETFD, fd_flags_err);   }   if (pid) {       ap_note_subprocess(p, pid, kill_how);       if (pipe_out) {          *pipe_out = out_fds[0];       }       if (pipe_in) {          *pipe_in = in_fds[1];       }       if (pipe_err) {          *pipe_err = err_fds[0];       }   }   return pid;}pid_t os_fork(server_rec *s, int slot){    struct tpf_fork_input fork_input;    APACHE_TPF_INPUT input_parms;    int count;    listen_rec *lr;    input_parms.generation = ap_my_generation;#ifdef USE_SHMGET_SCOREBOARD    input_parms.scoreboard_heap = ap_scoreboard_image;#endif    lr = ap_listeners;    count = 0;    do {        input_parms.listeners[count] = lr->fd;        lr = lr->next;        count++;    } while(lr != ap_listeners);    input_parms.slot = slot;    input_parms.restart_time = ap_restart_time;    input_parms.shm_static_ptr = tpf_shm_static_ptr;    input_parms.tpf_fds = tpf_fds;    fork_input.ebw_data = &input_parms;    fork_input.program = ap_server_argv0;    fork_input.prog_type = TPF_FORK_NAME;    fork_input.istream = TPF_FORK_IS_BALANCE;    fork_input.ebw_data_length = sizeof(input_parms);    fork_input.parm_data = argv_ptr;#ifdef TPF_FORK_EXTENDED    return tpf_fork(&fork_input, NULL, NULL);#else    return tpf_fork(&fork_input);#endif /* TPF_FORK_EXTENDED */}void ap_tpf_zinet_checks(int standalone,                        const char *servername,                        server_rec *s) {    INETD_IDCT_ENTRY_PTR idct;    /* explicitly disallow "ServerType inetd" on TPF */    if (!standalone) {        ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, s,                     TPF_SERVERTYPE_MSG);        exit(1); /* abort start-up of server */    }    /* figure out zinet model for our server from the idct slot */    idct = inetd_getServer(servername);    if (idct) {        zinet_model = idct->model;        free(idct);    } else {        ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, s,                     TPF_UNABLE_TO_DETERMINE_ZINET_MODEL, servername);        exit(1); /* abort start-up of server */    }    /* check for valid zinet models */    if (zinet_model != INETD_IDCF_MODEL_DAEMON &&        zinet_model != INETD_IDCF_MODEL_NOLISTEN) {        ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, s,                     TPF_STANDALONE_CONFLICT_MSG);        exit(1); /* abort start-up of server */    }#ifdef TPF_NOLISTEN_WARNING/* nag about switching to DAEMON model */    if (zinet_model == INETD_IDCF_MODEL_NOLISTEN) {        ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, s,                     TPF_NOLISTEN_WARNING);    }#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -