📄 os.c
字号:
}int os_check_server(char *server) { int *current_acn; ap_check_signals(); /* check our InetD status */ if (inetd_getServerStatus(server) != INETD_SERVER_STATUS_ACTIVE) { return 1; /* shutdown */ } /* if DAEMON model, make sure CLTZ parent is still around */ if (zinet_model == INETD_IDCF_MODEL_DAEMON) { if (getppid() == 1) { return 1; /* shutdown */ } } else { /* this is the NOLISTEN model (INETD_IDCF_MODEL_NOLISTEN) */ /* check that the program activation number hasn't changed */ current_acn = (int *)cinfc_fast(CINFC_CMMACNUM); if (ecbp2()->ce2acn != *current_acn) { return 1; /* shutdown */ } } return 0; /* keep on running... */}void os_note_additional_cleanups(pool *p, int sd) { char sockfilename[50]; /* write the socket to file so that TPF socket device driver will close socket in case we happen to abend. */ sprintf(sockfilename, "/dev/tpf.socket.file/%.8X", sd); sock_fp = fopen(sockfilename, "r+"); /* we don't want the children to inherit this fd */ fcntl(fileno(sock_fp), F_SETFD, FD_CLOEXEC); sock_sd = sd;}void ap_tpf_save_argv(int argc, char **argv) { int i, len = 3; /* 3 for "-x " */ for (i = 1; i < argc; i++) { /* find len for calloc */ len += strlen (argv[i]); ++len; /* 1 for blank */ } argv_ptr = malloc(len + 1); strcpy(argv_ptr, "-x"); for (i = 1; i < argc; i++) { strcat(argv_ptr, " "); strcat(argv_ptr, argv[i]); }}void os_tpf_child(APACHE_TPF_INPUT *input_parms) { extern pid_t tpf_parent_pid; extern char tpf_mutex_key[TPF_MUTEX_KEY_SIZE]; tpf_child = 1; ap_my_generation = input_parms->generation; ap_restart_time = input_parms->restart_time; tpf_fds = input_parms->tpf_fds; tpf_shm_static_ptr = input_parms->shm_static_ptr; tpf_parent_pid = getppid(); sprintf(tpf_mutex_key, "%.*x", (int) TPF_MUTEX_KEY_SIZE - 1, tpf_parent_pid);}#if defined(TPF41) && !defined(__PIPE_)int pipe(int fildes[2]){ errno = ENOSYS; return(-1);}API_EXPORT(piped_log *) ap_open_piped_log(pool *p, const char *program){ fprintf(stderr, "Pipes not supported on this TPF system\n"); exit (1);}#elsevoid ap_tpf_detach_shared_mem(void *address){ if (*((void **)address)) { shmdt(*((void **)address)); *((void **)address) = NULL; }}static void *ap_tpf_get_shared_mem(size_t size){ key_t shmkey = IPC_PRIVATE; int shmid = -1; static void *result; if ((shmid = shmget(shmkey, size, IPC_CREAT | SHM_R | SHM_W)) == -1) { perror("shmget failed in ap_tpf_get_shared_mem function"); exit(1); }#define BADSHMAT ((void *)(-1)) if ((result = shmat(shmid, 0, 0)) == BADSHMAT) { perror("shmat failed in ap_tpf_get_shared_mem"); } if (shmctl(shmid, IPC_RMID, NULL) != 0) { perror("shmctl(IPC_RMID) failed in ap_tpf_get_shared_mem"); } if (result == BADSHMAT) { /* now bailout */ exit(1); } return result;}int ap_tpf_fd_lookup(enum FILE_TYPE file_type, const char *fname)/* lookup a fd in the fd inheritance table */{ if (tpf_fds) { int i; TPF_FD_ITEM *fd_item = &tpf_fds->first_item; for (i = 1; i <= tpf_fds->nbr_of_items; i++, fd_item++) { /* check for an fd with the same type and name */ if ((file_type == fd_item->file_type) && (strcmp(fname, fd_item->fname) == 0) ) { /* we've got a match, check that fd is still open */ struct stat stbuf; if (fstat(fd_item->fd, &stbuf) == 0) { return(fd_item->fd); } else { /* fd is not open - the entire fd table is suspect */ fprintf(stderr, "fstat failed in ap_tpf_fd_lookup " "for fd %i (filename/pipe to %s): %s\n", fd_item->fd, fname, strerror(errno)); ap_tpf_detach_shared_mem(&tpf_fds); return(-1); } } } } return(-1);}void ap_tpf_add_fd(pool *p, int fd, enum FILE_TYPE file_type, const char *fname)/* add a newly opened fd to the fd inheritance table */{ int fname_size; if (tpf_child) { return; /* no kids allowed */ } if (tpf_fds == NULL) { /* get shared memory if necessary */ tpf_fds = ap_tpf_get_shared_mem((size_t)TPF_FD_LIST_SIZE); if (tpf_fds) { ap_register_cleanup(p, (void *)&tpf_fds, ap_tpf_detach_shared_mem, ap_null_cleanup); tpf_fds->nbr_of_items = 0; tpf_fds->next_avail_byte = &tpf_fds->first_item; tpf_fds->last_avail_byte = (char *)tpf_fds + TPF_FD_LIST_SIZE; } } /* add fd */ if (tpf_fds) { TPF_FD_ITEM *fd_item; /* make sure there's room */ fname_size = strlen(fname) + 1; if (sizeof(TPF_FD_ITEM) + fname_size > (char *)tpf_fds->last_avail_byte - (char *)tpf_fds->next_avail_byte) { fprintf(stderr, "fd inheritance table out of room, increase " "TPF_FD_LIST_SIZE in os.h and recompile Apache\n"); exit(1); } /* add the new item */ fd_item = tpf_fds->next_avail_byte; tpf_fds->next_avail_byte = fd_item + 1; tpf_fds->last_avail_byte = (char *)tpf_fds->last_avail_byte - fname_size; fd_item->fname = tpf_fds->last_avail_byte; strcpy(fd_item->fname, fname); fd_item->fd = fd; fd_item->file_type = file_type; tpf_fds->nbr_of_items++; }}API_EXPORT(piped_log *) ap_open_piped_log(pool *p, const char *program){ int log_fd; piped_log *pl; /* check fd inheritance table to see if this log is already open */ log_fd = ap_tpf_fd_lookup(PIPE_OUT, program); if (log_fd < 0) { /* this is a new log - open it */ FILE *dummy; TPF_FORK_CHILD cld; cld.filename = (char *)program; cld.subprocess_env = NULL; cld.prog_type = FORK_NAME; if (ap_spawn_child(p, NULL, &cld, kill_after_timeout, &dummy, NULL, NULL)) { log_fd = fileno(dummy); /* add this log to the fd inheritance table */ ap_tpf_add_fd(p, log_fd, PIPE_OUT, program); } else { perror("ap_spawn_child"); fprintf(stderr, "Couldn't fork child for piped log process\n"); exit (1); } } pl = ap_palloc(p, sizeof (*pl)); pl->p = p; pl->fds[1] = log_fd; return pl;}#endif /* TPF41 && ndef __PIPE_ *//* The following functions are used for the tpf specific module called mod_tpf_shm_static. This module is a clone of Apache's mod_mmap_static. Because TPF doesn't support the system call mmap(), it is replaced by shared memory, but uses the mmap directives, etc. */union align{ /* Types which are likely to have the longest RELEVANT alignment * restrictions... */ char *cp; void (*f) (void); long l; FILE *fp; double d;};#define CLICK_SZ (sizeof(union align))union block_hdr { union align a; /* Actual header... */ struct { char *endp; union block_hdr *next; char *first_avail; #ifdef POOL_DEBUG union block_hdr *global_next; struct pool *owning_pool; #endif } h;};struct pool { union block_hdr *first; union block_hdr *last; struct cleanup *cleanups; struct process_chain *subprocesses; struct pool *sub_pools; struct pool *sub_next; struct pool *sub_prev; struct pool *parent; char *free_first_avail;#ifdef ALLOC_USE_MALLOC void *allocation_list;#endif#ifdef POOL_DEBUG struct pool *joined;#endif};#include "ap_alloc.h"#define POOL_HDR_CLICKS (1 + ((sizeof(struct pool) - 1) / CLICK_SZ))#define POOL_HDR_BYTES (POOL_HDR_CLICKS * CLICK_SZ)pool * ap_get_shared_mem_pool(size_t size){ pool *new_pool; union block_hdr *blok; blok = (union block_hdr *) ap_tpf_get_shared_mem(size); /* if shm fails, it will exit blok will be valid here */ memset((char *) blok, '\0', size); blok->h.next = NULL; blok->h.first_avail = (char *) (blok + 1); blok->h.endp = size + blok->h.first_avail; new_pool = (pool *) blok->h.first_avail; blok->h.first_avail += POOL_HDR_BYTES; new_pool->free_first_avail = blok->h.first_avail; new_pool->first = new_pool->last = blok; return new_pool;}int ap_check_shm_space(struct pool *a, int size){ union block_hdr *blok = a->last; char *first_avail = blok->h.first_avail; char *new_first_avail; new_first_avail = first_avail + size; if (new_first_avail <= blok->h.endp) { return (1); } else return (0);}/* This function serves as an interim killpg for Apache shutdown purposes. TPF won't have an actual killpg for a very long time, if ever. (And kill with a negative pid doesn't work on TPF either.)*/int killpg(pid_t pgrp, int sig){ struct ev0bk evnblock; struct timeval tv; int i; ap_sync_scoreboard_image(); for (i = 0; i < HARD_SERVER_LIMIT; ++i) { int pid = ap_scoreboard_image->parent[i].pid; /* the pgrp check is so that we don't kill ourself: */ if (pid && pid != pgrp) { kill(pid, sig); } } /* Allow time for the signals to get to the children. Note that ap_select is signal interruptable, so we use evnwc instead. */ i = TPF_SHUTDOWN_SIGNAL_DELAY; evnblock.evnpstinf.evnbkc1 = 1; /* nbr of posts needed */ evntc(&evnblock, EVENT_CNT, 'N', i, EVNTC_1052); evnwc(&evnblock, EVENT_CNT); if (sig == SIGTERM) { /* get idle children's attention by closing the socket */ closesocket(sock_sd); /* and close the /dev/tpf.socket.file special file */ fclose(sock_fp); /* Allow the children some more time. Note that ap_select is signal interruptable, so we use evnwc instead. */ i = TPF_SHUTDOWN_CLOSING_DELAY; evnblock.evnpstinf.evnbkc1 = 1; /* nbr of posts needed */ evntc(&evnblock, EVENT_CNT, 'N', i, EVNTC_1052); evnwc(&evnblock, EVENT_CNT); } return(0);}/* This function augments http_main's show_compile_settings function. This way definitions that are only shown on TPF won't clutter up main line code.*/void show_os_specific_compile_settings(void){int i;#ifdef USE_TPF_SCOREBOARD #error "USE_TPF_SCOREBOARD (system heap scoreboard)" #error "is no longer supported." #error "Replace with USE_SHMGET_SCOREBOARD to use" #error "shared memory or remove entirely to use" #error "scoreboard on file for pre-TPF41 PUT10 systems"#endif#ifdef TPF_FORK_EXTENDED printf(" -D TPF_FORK_EXTENDED\n"); #endif#ifdef TPF_HAVE_NONSOCKET_SELECT printf(" -D TPF_HAVE_NONSOCKET_SELECT\n"); #endif#ifdef TPF_NO_NONSOCKET_SELECT printf(" -D TPF_NO_NONSOCKET_SELECT\n"); #endif#ifdef TPF_HAVE_SAWNC printf(" -D TPF_HAVE_SAWNC\n"); #endif#ifdef TPF_NO_SAWNC printf(" -D TPF_NO_SAWNC\n"); #endif #ifdef TPF_HAVE_NSD printf(" -D TPF_HAVE_NSD\n");#endif #ifdef HAVE_SYSLOG printf(" -D HAVE_SYSLOG\n");#endif /* round SCOREBOARD_MAINTENANCE_INTERVAL up to seconds */ i = (SCOREBOARD_MAINTENANCE_INTERVAL + 999999) / 1000000; if (i == 1) { printf(" -D SCOREBOARD_MAINTENANCE_INTERVAL=1 SECOND\n"); } else { printf(" -D SCOREBOARD_MAINTENANCE_INTERVAL=%i SECONDS\n", i); }#ifdef TPF_HAVE_SIGACTION printf(" -D TPF_HAVE_SIGACTION\n");#endif#ifdef NO_USE_SIGACTION printf(" -D NO_USE_SIGACTION\n");#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -