コード例 #1
0
ファイル: tmux.c プロジェクト: MarvinZhuang/tmate
__dead void
shell_exec(const char *shell, const char *shellcmd)
{
	const char	*shellname, *ptr;
	char		*argv0;

	ptr = strrchr(shell, '/');
	if (ptr != NULL && *(ptr + 1) != '\0')
		shellname = ptr + 1;
	else
		shellname = shell;
	if (login_shell)
		xasprintf(&argv0, "-%s", shellname);
	else
		xasprintf(&argv0, "%s", shellname);
	setenv("SHELL", shell, 1);

	setblocking(STDIN_FILENO, 1);
	setblocking(STDOUT_FILENO, 1);
	setblocking(STDERR_FILENO, 1);
	closefrom(STDERR_FILENO + 1);

	execl(shell, argv0, "-c", shellcmd, (char *) NULL);
	fatal("execl failed");
}
コード例 #2
0
static int on_ssh_channel_read(__unused ssh_session _session,
			       __unused ssh_channel channel,
			       void *_data, uint32_t total_len,
			       __unused int is_stderr, void *userdata)
{
	struct tmate_session *session = userdata;
	char *data = _data;
	size_t written = 0;
	ssize_t len;

	if (session->readonly)
		return total_len;

	setblocking(session->pty, 1);
	while (total_len) {
		len = write(session->pty, data, total_len);
		if (len < 0)
			tmate_fatal("Error writing to pty");

		total_len -= len;
		written += len;
		data += len;
	}
	setblocking(session->pty, 0);

	return written;
}
コード例 #3
0
ファイル: tcp_socket.cpp プロジェクト: bobrippling/stick
TCPSocket::TCPSocket(
				TCPSocket& (connreq)(),
				void (*disconnected)(),
				void (*received)(void *, size_t),
				void (*error)(),
				int bs
		):
	fd(socket(DOMAIN, TYPE, PROTOCOL)), addr(),
	lerr(NULL), buffer(new char[bs]), buffersize(bs),
	connrequestf(connreq), disconnectedf(disconnected),
	receivedf(received), errorf(error), state(IDLE)
{
	if(fd == -1 || !setblocking(false))
		throw ERR_INIT; // FIXME FIXME FIXME no throw in constructor

#if defined(SO_NOSIGPIPE)
	{
		int val = 1;
		// ignore sigpipe - FreeBSD
		setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof(val));
	}
#endif

	memset(&addr, '\0', sizeof addr);
}
コード例 #4
0
ファイル: SocketUDP.cpp プロジェクト: chubahowsmall/ead-cel
int SocketUDP::openAsReceiver(const string& ip, int port, bool blocking)
{
    int r;

    _leaveGroup = false;

    r = _ip.setString(ip);
    if (r != E_OK)
        return r;

    r = open(_family, _type, _protocol);
    if (r != E_OK)
        return r;

    r = bind(port);
    if (r != E_OK)
        return r;

    if (_ip.getType() == IPv4::TYPE_MULTICAST) {
        r = joinGroup(_ip);
        if (r != E_OK)
            return r;
        _igmpSender.start(_ip);
        _leaveGroup = true;
    }

    r = setblocking(blocking);
    if (r != E_OK)
        return r;

    return E_OK;
}
コード例 #5
0
ファイル: SocketUDP.cpp プロジェクト: chubahowsmall/ead-cel
int SocketUDP::openAsSender(const string& ip, int port, bool blocking)
{
    int r;

    _leaveGroup = false;

    r = _ip.setString(ip);
    if (r != E_OK)
        return r;

    r = open(_family, _type, _protocol);
    if (r != E_OK)
        return r;

    memset(&_addr.sin_zero, '\0', 8);
    _addr.sin_family = AF_INET;
    _addr.sin_addr.s_addr = inet_addr(ip.c_str());
    _addr.sin_port = htons(port);

    if (_ip.getType() == IPv4::TYPE_MULTICAST) {

        r = setTtl(DEFAULT_MULTICAST_TTL);
        if (r != E_OK)
            return r;

        r = setLoop(DEFAULT_LOOPBACK);
        if (r != E_OK)
            return r;

/*
        // seta valores default para TTL e LOOP
        if (setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl)) < 0) {
            throw 1;
        }
        if (setsockopt(IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loop, sizeof(loop)) < 0) {
            throw 1;
        }

        // permite envio dos pacotes de qualquer interface
        _mreq.imr_interface.s_addr = htonl(INADDR_ANY);
        if (setsockopt(IPPROTO_IP, IP_MULTICAST_IF, (char *)&_mreq.imr_interface,
            sizeof(struct ip_mreq)) < 0) {
            throw 1;
        }
*/            
    } else {
        r = setTtl(DEFAULT_UNICAST_TTL);
        if (r != E_OK)
            return r;
    }

    r = setblocking(blocking);
    if (r != E_OK)
        return r;

    return E_OK;
}
コード例 #6
0
ファイル: tcp_socket.cpp プロジェクト: bobrippling/stick
void TCPSocket::newsocket(int newfd)
{
	if(newfd == -1 || !setblocking(false))
		throw ERR_INIT;

	if(state == CONNECTED)
		shutdown(fd, SHUT_RDWR);

	close(fd);
	fd = newfd;
}
コード例 #7
0
ファイル: Connection.cpp プロジェクト: BillXu/NewProject
	//------------------------------------------------------------------------------------
	Connection::Connection(SOCKET fd)
	{
		this->fd = fd;
		this->recv_bytes = 0;
		this->send_bytes = 0;

		this->active = true;
	
        if (fd > 0)
        {
		    setblocking(fd, false);
        }
	}
コード例 #8
0
void
tty_start_tty(struct tty *tty)
{
	struct termios	 tio;

	if (tty->fd == -1 || tcgetattr(tty->fd, &tty->tio) != 0)
		return;

	setblocking(tty->fd, 0);

	bufferevent_enable(tty->event, EV_READ|EV_WRITE);

	memcpy(&tio, &tty->tio, sizeof tio);
	tio.c_iflag &= ~(IXON|IXOFF|ICRNL|INLCR|IGNCR|IMAXBEL|ISTRIP);
	tio.c_iflag |= IGNBRK;
	tio.c_oflag &= ~(OPOST|ONLCR|OCRNL|ONLRET);
	tio.c_lflag &= ~(IEXTEN|ICANON|ECHO|ECHOE|ECHONL|ECHOCTL|
	    ECHOPRT|ECHOKE|ECHOCTL|ISIG);
	tio.c_cc[VMIN] = 1;
	tio.c_cc[VTIME] = 0;
	if (tcsetattr(tty->fd, TCSANOW, &tio) == 0)
		tcflush(tty->fd, TCIOFLUSH);

	tty_putcode(tty, TTYC_SMCUP);

	tty_putcode(tty, TTYC_SGR0);
	memcpy(&tty->cell, &grid_default_cell, sizeof tty->cell);

	tty_putcode(tty, TTYC_RMKX);
	if (tty_use_acs(tty))
		tty_putcode(tty, TTYC_ENACS);
	tty_putcode(tty, TTYC_CLEAR);

	tty_putcode(tty, TTYC_CNORM);
	if (tty_term_has(tty->term, TTYC_KMOUS))
		tty_puts(tty, "\033[?1000l");

	tty->cx = UINT_MAX;
	tty->cy = UINT_MAX;

	tty->rlower = UINT_MAX;
	tty->rupper = UINT_MAX;

	tty->mode = MODE_CURSOR;

	tty->flags |= TTY_STARTED;

	tty_force_cursor_colour(tty, "");
}
コード例 #9
0
ファイル: tty.c プロジェクト: UNGLinux/Obase
void
tty_stop_tty(struct tty *tty)
{
	struct winsize	ws;

	if (!(tty->flags & TTY_STARTED))
		return;
	tty->flags &= ~TTY_STARTED;

	bufferevent_disable(tty->event, EV_READ|EV_WRITE);

	/*
	 * Be flexible about error handling and try not kill the server just
	 * because the fd is invalid. Things like ssh -t can easily leave us
	 * with a dead tty.
	 */
	if (ioctl(tty->fd, TIOCGWINSZ, &ws) == -1)
		return;
	if (tcsetattr(tty->fd, TCSANOW, &tty->tio) == -1)
		return;

	setblocking(tty->fd, 1);

	tty_raw(tty, tty_term_string2(tty->term, TTYC_CSR, 0, ws.ws_row - 1));
	if (tty_use_acs(tty))
		tty_raw(tty, tty_term_string(tty->term, TTYC_RMACS));
	tty_raw(tty, tty_term_string(tty->term, TTYC_SGR0));
	tty_raw(tty, tty_term_string(tty->term, TTYC_RMKX));
	tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR));
	if (tty_term_has(tty->term, TTYC_CS1) && tty->cstyle != 0) {
		if (tty_term_has(tty->term, TTYC_CSR1))
			tty_raw(tty, tty_term_string(tty->term, TTYC_CSR1));
		else
			tty_raw(tty, tty_term_string1(tty->term, TTYC_CS1, 0));
	}
	tty_raw(tty, tty_term_string(tty->term, TTYC_CR));

	tty_raw(tty, tty_term_string(tty->term, TTYC_CNORM));
	if (tty_term_has(tty->term, TTYC_KMOUS))
		tty_raw(tty, "\033[?1000l");

	tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP));

	if (tty->xterm_version > 270)
		tty_raw(tty, "\033[61;1\"p");
}
コード例 #10
0
ファイル: control.c プロジェクト: bholt/tmux
void
control_error_callback(
    unused struct bufferevent *bufev, unused short what, unused void *data)
{
	struct client	*c = data;

	c->references--;
	if (c->flags & CLIENT_DEAD)
		return;

	bufferevent_disable(c->stdin_event, EV_READ|EV_WRITE);
	setblocking(c->stdin_fd, 1);
	close(c->stdin_fd);
	c->stdin_fd = -1;

	if (c->stdin_callback != NULL)
		c->stdin_callback(c, c->stdin_data);
}
コード例 #11
0
ファイル: uws_http.c プロジェクト: codesaler/uws
int write_response(pConnInfo conn_info, struct response* header_body) {/*{{{*/
    int res;
    setblocking(conn_info->clientfd);

    char *accept_encoding; 
    //compress--start--

    if((header_body->content_len > 0) &&
        uws_config.http.gzip && 
        in_str_array(uws_config.http.gzip_types, get_header_param("Content-Type", header_body->header)) >= 0 &&
        (accept_encoding = get_header_param("Accept-Encoding", conn_info->request_header)) &&
        strstr(accept_encoding, "gzip") != NULL
        ) {

        size_t src_len = header_body->content_len;
        size_t dst_len;
        char *dst_buff;
        gzcompress(&dst_buff, &dst_len, header_body->content, src_len);

        char *content_len = itoa(dst_len);
        add_header_param("Content-Length", content_len, header_body->header);
        uws_free(content_len);
        add_header_param("Content-Encoding", "gzip", header_body->header);
        uws_free(header_body->content);
        header_body->content = dst_buff;
        header_body->content_len = dst_len;
    }

    char* header_str = str_response_header(header_body->header);
    size_t header_len = strlen(header_str);

    res = write(conn_info->clientfd, header_str, header_len);
    uws_free(header_str);

    if(res == -1) return -1;
    res = write(conn_info->clientfd, HEADER_SEP, strlen(HEADER_SEP));
    if(res == -1) return -1;
    res = writen(conn_info->clientfd, header_body->content, header_body->content_len);
    if(res == -1) {return -1;}
    return 0;
}/*}}}*/
コード例 #12
0
void tmate_client_pty_init(struct tmate_session *session)
{
	struct tmate_ssh_client *client = &session->ssh_client;

	ioctl(session->pty, TIOCSWINSZ, &session->ssh_client.winsize_pty);

	memset(&client->channel_cb, 0, sizeof(client->channel_cb));
	ssh_callbacks_init(&client->channel_cb);
	client->channel_cb.userdata = session;
	client->channel_cb.channel_data_function = on_ssh_channel_read,
	ssh_set_channel_callbacks(client->channel, &client->channel_cb);

	ssh_set_message_callback(session->ssh_client.session,
				 on_ssh_message_callback, session);

	setblocking(session->pty, 0);
	event_set(&session->ev_pty, session->pty,
		  EV_READ | EV_PERSIST, __on_pty_event, session);
	event_add(&session->ev_pty, NULL);

	tmate_add_ssh_latency_callback(client, on_latency_callback, session);
}
コード例 #13
0
static selene_error_t *want_pull(selene_t *s, selene_event_e event,
                                 void *baton) {
  int rv = 0;
  char buf[8096];
  size_t blen = 0;
  size_t remaining = 0;
  server_t *srv = (server_t *)baton;

  do {
    SELENE_ERR(
        selene_io_out_enc_bytes(s, &buf[0], sizeof(buf), &blen, &remaining));

    if (blen > 0) {
      setblocking(srv->sock);
      rv = write(srv->sock, buf, blen);
      if (rv < 0) {
        srv->write_err = errno;
        break;
      }
    }
  } while (remaining > 0);

  return SELENE_SUCCESS;
}
コード例 #14
0
void
tty_init_termios(int fd, struct termios *orig_tio, struct bufferevent *bufev)
{
	struct termios	tio;

	if (fd == -1 || tcgetattr(fd, orig_tio) != 0)
		return;

	setblocking(fd, 0);

	if (bufev != NULL)
		bufferevent_enable(bufev, EV_READ|EV_WRITE);

	memcpy(&tio, orig_tio, sizeof tio);
	tio.c_iflag &= ~(IXON|IXOFF|ICRNL|INLCR|IGNCR|IMAXBEL|ISTRIP);
	tio.c_iflag |= IGNBRK;
	tio.c_oflag &= ~(OPOST|ONLCR|OCRNL|ONLRET);
	tio.c_lflag &= ~(IEXTEN|ICANON|ECHO|ECHOE|ECHONL|ECHOCTL|
	    ECHOPRT|ECHOKE|ECHOCTL|ISIG);
	tio.c_cc[VMIN] = 1;
	tio.c_cc[VTIME] = 0;
	if (tcsetattr(fd, TCSANOW, &tio) == 0)
		tcflush(fd, TCIOFLUSH);
}
コード例 #15
0
ファイル: SocketUDP.cpp プロジェクト: chubahowsmall/ead-cel
int SocketUDP::openAsReceiver(int port, bool blocking)
{
    int r;

    _leaveGroup = false;

    r = _ip.setString("127.0.0.1");
    if (r != E_OK)
        return r;

    r = open(_family, _type, _protocol);
    if (r != E_OK)
        return r;

    r = bind(port);
    if (r != E_OK)
        return r;

    r = setblocking(blocking);
    if (r != E_OK)
        return r;

    return E_OK;
}
コード例 #16
0
ファイル: job.c プロジェクト: ThomasAdam/tmux-cvs-archived
/* Start a job running, if it isn't already. */
struct job *
job_run(const char *cmd,
    void (*callbackfn)(struct job *), void (*freefn)(void *), void *data)
{
	struct job	*job;
	struct environ	 env;
	pid_t		 pid;
	int		 nullfd, out[2];

	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, out) != 0)
		return (NULL);

	environ_init(&env);
	environ_copy(&global_environ, &env);
	server_fill_environ(NULL, &env);

	switch (pid = fork()) {
	case -1:
		environ_free(&env);
		return (NULL);
	case 0:		/* child */
		clear_signals(1);

		environ_push(&env);
		environ_free(&env);

		if (dup2(out[1], STDOUT_FILENO) == -1)
			fatal("dup2 failed");
		if (out[1] != STDOUT_FILENO)
			close(out[1]);
		close(out[0]);

		nullfd = open(_PATH_DEVNULL, O_RDWR, 0);
		if (nullfd < 0)
			fatal("open failed");
		if (dup2(nullfd, STDIN_FILENO) == -1)
			fatal("dup2 failed");
		if (dup2(nullfd, STDERR_FILENO) == -1)
			fatal("dup2 failed");
		if (nullfd != STDIN_FILENO && nullfd != STDERR_FILENO)
			close(nullfd);

		closefrom(STDERR_FILENO + 1);

		execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);
		fatal("execl failed");
	}

	/* parent */
	environ_free(&env);
	close(out[1]);

	job = xmalloc(sizeof *job);
	job->cmd = xstrdup(cmd);
	job->pid = pid;
	job->status = 0;

	LIST_INSERT_HEAD(&all_jobs, job, lentry);

	job->callbackfn = callbackfn;
	job->freefn = freefn;
	job->data = data;

	job->fd = out[0];
	setblocking(job->fd, 0);

	job->event = bufferevent_new(job->fd, NULL, NULL, job_callback, job);
	bufferevent_enable(job->event, EV_READ);

	log_debug("run job %p: %s, pid %ld", job, job->cmd, (long) job->pid);
	return (job);
}
コード例 #17
0
ファイル: cmd-pipe-pane.c プロジェクト: ThomasAdam/tmux
static enum cmd_retval
cmd_pipe_pane_exec(struct cmd *self, struct cmdq_item *item)
{
	struct args		*args = self->args;
	struct client		*c = cmd_find_client(item, NULL, 1);
	struct window_pane	*wp = item->target.wp;
	struct session		*s = item->target.s;
	struct winlink		*wl = item->target.wl;
	char			*cmd;
	int			 old_fd, pipe_fd[2], null_fd, in, out;
	struct format_tree	*ft;
	sigset_t		 set, oldset;

	/* Destroy the old pipe. */
	old_fd = wp->pipe_fd;
	if (wp->pipe_fd != -1) {
		bufferevent_free(wp->pipe_event);
		close(wp->pipe_fd);
		wp->pipe_fd = -1;

		if (window_pane_destroy_ready(wp)) {
			server_destroy_pane(wp, 1);
			return (CMD_RETURN_NORMAL);
		}
	}

	/* If no pipe command, that is enough. */
	if (args->argc == 0 || *args->argv[0] == '\0')
		return (CMD_RETURN_NORMAL);

	/*
	 * With -o, only open the new pipe if there was no previous one. This
	 * allows a pipe to be toggled with a single key, for example:
	 *
	 *	bind ^p pipep -o 'cat >>~/output'
	 */
	if (args_has(self->args, 'o') && old_fd != -1)
		return (CMD_RETURN_NORMAL);

	/* What do we want to do? Neither -I or -O is -O. */
	if (args_has(self->args, 'I')) {
		in = 1;
		out = args_has(self->args, 'O');
	} else {
		in = 0;
		out = 1;
	}

	/* Open the new pipe. */
	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_fd) != 0) {
		cmdq_error(item, "socketpair error: %s", strerror(errno));
		return (CMD_RETURN_ERROR);
	}

	/* Expand the command. */
	ft = format_create(item->client, item, FORMAT_NONE, 0);
	format_defaults(ft, c, s, wl, wp);
	cmd = format_expand_time(ft, args->argv[0]);
	format_free(ft);

	/* Fork the child. */
	sigfillset(&set);
	sigprocmask(SIG_BLOCK, &set, &oldset);
	switch (fork()) {
	case -1:
		sigprocmask(SIG_SETMASK, &oldset, NULL);
		cmdq_error(item, "fork error: %s", strerror(errno));

		free(cmd);
		return (CMD_RETURN_ERROR);
	case 0:
		/* Child process. */
		proc_clear_signals(server_proc, 1);
		sigprocmask(SIG_SETMASK, &oldset, NULL);
		close(pipe_fd[0]);

		null_fd = open(_PATH_DEVNULL, O_WRONLY, 0);
		if (out) {
			if (dup2(pipe_fd[1], STDIN_FILENO) == -1)
				_exit(1);
		} else {
			if (dup2(null_fd, STDIN_FILENO) == -1)
				_exit(1);
		}
		if (in) {
			if (dup2(pipe_fd[1], STDOUT_FILENO) == -1)
				_exit(1);
			if (pipe_fd[1] != STDOUT_FILENO)
				close(pipe_fd[1]);
		} else {
			if (dup2(null_fd, STDOUT_FILENO) == -1)
				_exit(1);
		}
		if (dup2(null_fd, STDERR_FILENO) == -1)
			_exit(1);
		closefrom(STDERR_FILENO + 1);

		execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);
		_exit(1);
	default:
		/* Parent process. */
		sigprocmask(SIG_SETMASK, &oldset, NULL);
		close(pipe_fd[1]);

		wp->pipe_fd = pipe_fd[0];
		if (wp->fd != -1)
			wp->pipe_off = EVBUFFER_LENGTH(wp->event->input);
		else
			wp->pipe_off = 0;

		setblocking(wp->pipe_fd, 0);
		wp->pipe_event = bufferevent_new(wp->pipe_fd,
		    cmd_pipe_pane_read_callback,
		    cmd_pipe_pane_write_callback,
		    cmd_pipe_pane_error_callback,
		    wp);
		if (wp->pipe_event == NULL)
			fatalx("out of memory");
		if (out)
			bufferevent_enable(wp->pipe_event, EV_WRITE);
		if (in)
			bufferevent_enable(wp->pipe_event, EV_READ);

		free(cmd);
		return (CMD_RETURN_NORMAL);
	}
}
コード例 #18
0
ファイル: imt_plugin.c プロジェクト: mmarchand/pmacct
/* Functions */
void imt_plugin(int pipe_fd, struct configuration *cfgptr, void *ptr) 
{
  int maxqsize = (MAX_QUERIES*sizeof(struct pkt_primitives))+sizeof(struct query_header)+2;
  struct sockaddr cAddr;
  struct pkt_data *data;
  struct ports_table pt;
  unsigned char srvbuf[maxqsize];
  unsigned char *srvbufptr;
  struct query_header *qh;
  unsigned char *pipebuf;
  char path[] = "/tmp/collect.pipe";
  short int go_to_clear = FALSE;
  u_int32_t request, sz;
  struct ch_status *status = ((struct channels_list_entry *)ptr)->status;
  int datasize = ((struct channels_list_entry *)ptr)->datasize;
  struct extra_primitives extras;
  unsigned char *rgptr;
  int pollagain = 0;
  u_int32_t seq = 0;
  int rg_err_count = 0;
  int ret;
  struct pkt_bgp_primitives *pbgp, empty_pbgp;
  struct pkt_nat_primitives *pnat, empty_pnat;
  struct pkt_mpls_primitives *pmpls, empty_pmpls;
  char *pcust, empty_pcust[] = "";
  struct pkt_vlen_hdr_primitives *pvlen, empty_pvlen;
  struct networks_file_data nfd;
  struct timeval select_timeout;
  struct primitives_ptrs prim_ptrs;

  fd_set read_descs, bkp_read_descs; /* select() stuff */
  int select_fd, lock = FALSE;
  int cLen, num, sd, sd2;
  char *dataptr;

  memcpy(&config, cfgptr, sizeof(struct configuration));
  memcpy(&extras, &((struct channels_list_entry *)ptr)->extras, sizeof(struct extra_primitives));
  recollect_pipe_memory(ptr);
  pm_setproctitle("%s [%s]", "IMT Plugin", config.name);

  if (config.pidfile) write_pid_file_plugin(config.pidfile, config.type, config.name);
  if (config.logfile) {
    fclose(config.logfile_fd);
    config.logfile_fd = open_logfile(config.logfile, "a");
  }

  if (extras.off_pkt_vlen_hdr_primitives) {
    Log(LOG_ERR, "ERROR ( %s/%s ): variable-length primitives, ie. label, are not supported in IMT plugin. Exiting ..\n", config.name, config.type);
    exit_plugin(1);
  }

  reload_map = FALSE;
  status->wakeup = TRUE;

  /* a bunch of default definitions and post-checks */
  pipebuf = (unsigned char *) malloc(config.buffer_size);
  if (!pipebuf) {
    Log(LOG_ERR, "ERROR ( %s/%s ): malloc() failed (pipebuf). Exiting ..\n", config.name, config.type);
    exit_plugin(1);
  }

  setnonblocking(pipe_fd);
  memset(pipebuf, 0, config.buffer_size);
  no_more_space = FALSE;

  if (config.what_to_count & (COUNT_SUM_HOST|COUNT_SUM_NET))
    insert_func = sum_host_insert;
  else if (config.what_to_count & COUNT_SUM_PORT) insert_func = sum_port_insert;
  else if (config.what_to_count & COUNT_SUM_AS) insert_func = sum_as_insert;
#if defined (HAVE_L2)
  else if (config.what_to_count & COUNT_SUM_MAC) insert_func = sum_mac_insert;
#endif
  else insert_func = insert_accounting_structure;

  memset(&nt, 0, sizeof(nt));
  memset(&nc, 0, sizeof(nc));
  memset(&pt, 0, sizeof(pt));

  load_networks(config.networks_file, &nt, &nc);
  set_net_funcs(&nt);

  if (config.ports_file) load_ports(config.ports_file, &pt);
  if (config.pkt_len_distrib_bins_str) load_pkt_len_distrib_bins();
  else {
    if (config.what_to_count_2 & COUNT_PKT_LEN_DISTRIB) {
      Log(LOG_ERR, "ERROR ( %s/%s ): 'aggregate' contains pkt_len_distrib but no 'pkt_len_distrib_bins' defined. Exiting.\n", config.name, config.type);
      exit_plugin(1); 
    }
  }

  if ((!config.num_memory_pools) && (!have_num_memory_pools))
    config.num_memory_pools = NUM_MEMORY_POOLS;
  
  if (!config.memory_pool_size) config.memory_pool_size = MEMORY_POOL_SIZE;  
  else {
    if (config.memory_pool_size < sizeof(struct acc)) {
      Log(LOG_WARNING, "WARN ( %s/%s ): enforcing memory pool's minimum size, %d bytes.\n", config.name, config.type, sizeof(struct acc));
      config.memory_pool_size = MEMORY_POOL_SIZE;
    }
  }

  if (!config.imt_plugin_path) config.imt_plugin_path = path; 
  if (!config.buckets) config.buckets = MAX_HOSTS;

  init_memory_pool_table(config);
  if (mpd == NULL) {
    Log(LOG_ERR, "ERROR ( %s/%s ): unable to allocate memory pools table\n", config.name, config.type);
    exit_plugin(1);
  }

  current_pool = request_memory_pool(config.buckets*sizeof(struct acc));
  if (current_pool == NULL) {
    Log(LOG_ERR, "ERROR ( %s/%s ): unable to allocate first memory pool, try with larger value.\n", config.name, config.type);
    exit_plugin(1);
  }
  a = current_pool->base_ptr;

  lru_elem_ptr = malloc(config.buckets*sizeof(struct acc *));
  if (lru_elem_ptr == NULL) {
    Log(LOG_ERR, "ERROR ( %s/%s ): unable to allocate LRU element pointers.\n", config.name, config.type);
    exit_plugin(1);
  }
  else memset(lru_elem_ptr, 0, config.buckets*sizeof(struct acc *));

  current_pool = request_memory_pool(config.memory_pool_size);
  if (current_pool == NULL) {
    Log(LOG_ERR, "ERROR ( %s/%s ): unable to allocate more memory pools, try with larger value.\n", config.name, config.type);
    exit_plugin(1);
  }

  signal(SIGHUP, reload); /* handles reopening of syslog channel */
  signal(SIGINT, exit_now); /* exit lane */
  signal(SIGUSR1, SIG_IGN);
  signal(SIGUSR2, reload_maps);
  signal(SIGPIPE, SIG_IGN);
  signal(SIGCHLD, SIG_IGN); 

  memset(&empty_pbgp, 0, sizeof(empty_pbgp));
  memset(&empty_pnat, 0, sizeof(empty_pnat));
  memset(&empty_pmpls, 0, sizeof(empty_pmpls));
  memset(&empty_pvlen, 0, sizeof(empty_pvlen));

  /* building a server for interrogations by clients */
  sd = build_query_server(config.imt_plugin_path);
  cLen = sizeof(cAddr);

  /* preparing for synchronous I/O multiplexing */
  select_fd = 0;
  FD_ZERO(&read_descs);
  FD_SET(sd, &read_descs);
  if (sd > select_fd) select_fd = sd;
  FD_SET(pipe_fd, &read_descs);
  if (pipe_fd > select_fd) select_fd = pipe_fd;
  select_fd++;
  memcpy(&bkp_read_descs, &read_descs, sizeof(read_descs));

  qh = (struct query_header *) srvbuf;

  /* plugin main loop */
  for(;;) {
    select_again:
    select_timeout.tv_sec = DEFAULT_IMT_PLUGIN_SELECT_TIMEOUT;
    select_timeout.tv_usec = 0;

    memcpy(&read_descs, &bkp_read_descs, sizeof(bkp_read_descs));
    num = select(select_fd, &read_descs, NULL, NULL, &select_timeout);
    if (num <= 0) {
      if (getppid() == 1) {
	Log(LOG_ERR, "ERROR ( %s/%s ): Core process *seems* gone. Exiting.\n", config.name, config.type);
	exit_plugin(1);
      } 

      goto select_again;  
    }

    gettimeofday(&cycle_stamp, NULL);

    /* doing server tasks */
    if (FD_ISSET(sd, &read_descs)) {
      struct pollfd pfd;
      int ret;

      sd2 = accept(sd, &cAddr, &cLen);
      setblocking(sd2);
      srvbufptr = srvbuf;
      sz = maxqsize;

      pfd.fd = sd2;
      pfd.events = POLLIN;

      recv_again:
      ret = poll(&pfd, 1, 1000);
      if (ret == 0) {
        Log(LOG_WARNING, "WARN ( %s/%s ): Timed out while processing fragmented query.\n", config.name, config.type); 
        close(sd2);
	goto select_again;
      }
      else {
        num = recv(sd2, srvbufptr, sz, 0);
        if (srvbufptr[num-1] != '\x4') {
	  srvbufptr += num;
	  sz -= num;
	  goto recv_again; /* fragmented query */
        }
      }

      num = num+(maxqsize-sz);

      if (qh->num > MAX_QUERIES) {
	Log(LOG_DEBUG, "DEBUG ( %s/%s ): request discarded. Too much queries.\n", config.name, config.type);
	close(sd2);
	continue;
      }

      request = qh->type;
      if (request & WANT_RESET) request ^= WANT_RESET;
      if (request & WANT_LOCK_OP) {
	lock = TRUE;
	request ^= WANT_LOCK_OP;
      }

      /* 
	 - if explicitely required, we do not fork: query obtains exclusive
	   control - lock - over the memory table; 
	 - operations that may cause inconsistencies (full erasure, counter
	   reset for individual entries, etc.) are entitled of an exclusive
	   lock.
	 - if query is matter of just a single short-lived walk through the
	   table, we avoid fork(): the plugin will serve the request;
         - in all other cases, we fork; the newly created child will serve
	   queries asyncronously.
      */

      if (request & WANT_ERASE) {
	request ^= WANT_ERASE;
	if (request) {
	  if (num > 0) process_query_data(sd2, srvbuf, num, &extras, datasize, FALSE);
	  else Log(LOG_DEBUG, "DEBUG ( %s/%s ): %d incoming bytes. Errno: %d\n", config.name, config.type, num, errno);
	}
	Log(LOG_DEBUG, "DEBUG ( %s/%s ): Closing connection with client ...\n", config.name, config.type);
	go_to_clear = TRUE;  
      }
      else if (((request == WANT_COUNTER) || (request == WANT_MATCH)) &&
	(qh->num == 1) && (qh->what_to_count == config.what_to_count)) {
	if (num > 0) process_query_data(sd2, srvbuf, num, &extras, datasize, FALSE);
        else Log(LOG_DEBUG, "DEBUG ( %s/%s ): %d incoming bytes. ERRNO: %d\n", config.name, config.type, num, errno);
        Log(LOG_DEBUG, "DEBUG ( %s/%s ): Closing connection with client ...\n", config.name, config.type);
      } 
      else if (request == WANT_CLASS_TABLE) {
	if (num > 0) process_query_data(sd2, srvbuf, num, &extras, datasize, FALSE);
        else Log(LOG_DEBUG, "DEBUG ( %s/%s ): %d incoming bytes. ERRNO: %d\n", config.name, config.type, num, errno);
        Log(LOG_DEBUG, "DEBUG ( %s/%s ): Closing connection with client ...\n", config.name, config.type);
      }
      else if (request == WANT_PKT_LEN_DISTRIB_TABLE) {
        if (num > 0) process_query_data(sd2, srvbuf, num, &extras, datasize, FALSE);
        else Log(LOG_DEBUG, "DEBUG ( %s/%s ): %d incoming bytes. ERRNO: %d\n", config.name, config.type, num, errno);
        Log(LOG_DEBUG, "DEBUG ( %s/%s ): Closing connection with client ...\n", config.name, config.type);
      }
      else {
	if (lock) {
	  if (num > 0) process_query_data(sd2, srvbuf, num, &extras, datasize, FALSE);
          else Log(LOG_DEBUG, "DEBUG ( %s/%s ): %d incoming bytes. Errno: %d\n", config.name, config.type, num, errno);
          Log(LOG_DEBUG, "DEBUG ( %s/%s ): Closing connection with client ...\n", config.name, config.type);
	}
	else { 
          switch (fork()) {
	  case -1: /* Something went wrong */
	    Log(LOG_WARNING, "WARN ( %s/%s ): Unable to serve client query: %s\n", config.name, config.type, strerror(errno));
	    break;
          case 0: /* Child */
            close(sd);
	    pm_setproctitle("%s [%s]", "IMT Plugin -- serving client", config.name);
            if (num > 0) process_query_data(sd2, srvbuf, num, &extras, datasize, TRUE);
	    else Log(LOG_DEBUG, "DEBUG ( %s/%s ): %d incoming bytes. Errno: %d\n", config.name, config.type, num, errno);
            Log(LOG_DEBUG, "DEBUG ( %s/%s ): Closing connection with client ...\n", config.name, config.type);
            close(sd2);
            exit(0);
          default: /* Parent */
            break;
          } 
	}
      }
      close(sd2);
    }

    /* clearing stats if requested */
    if (go_to_clear) {
      /* When using extended BGP features we need to
	 free() up memory allocations before erasing */ 
      /* XXX: given the current use of empty_* vars we have always to
         free_extra_allocs() in order to prevent memory leaks */
      /*
      if (extras.off_pkt_bgp_primitives || extras.off_pkt_nat_primitives ||
	  extras.off_pkt_mpls_primitives || extras.off_custom_primitives)
      */
	free_extra_allocs(); 
      clear_memory_pool_table();
      current_pool = request_memory_pool(config.buckets*sizeof(struct acc));
      if (current_pool == NULL) {
        Log(LOG_ERR, "ERROR ( %s/%s ): Cannot allocate my first memory pool, try with larger value.\n", config.name, config.type);
        exit_plugin(1);
      }
      a = current_pool->base_ptr;

      current_pool = request_memory_pool(config.memory_pool_size);
      if (current_pool == NULL) {
        Log(LOG_ERR, "ERROR ( %s/%s ): Cannot allocate more memory pools, try with larger value.\n", config.name, config.type);
        exit_plugin(1);
      }
      go_to_clear = FALSE;
      no_more_space = FALSE;
      memcpy(&table_reset_stamp, &cycle_stamp, sizeof(struct timeval));
    }

    if (FD_ISSET(pipe_fd, &read_descs)) {
      if (!pollagain) {
        seq++;
        seq %= MAX_SEQNUM;
      }

      pollagain = FALSE;
      if ((num = read(pipe_fd, &rgptr, sizeof(rgptr))) == 0)
        exit_plugin(1); /* we exit silently; something happened at the write end */

      if (num < 0) {
        pollagain = TRUE;
        goto select_again;
      }

      memcpy(pipebuf, rgptr, config.buffer_size);
      if (((struct ch_buf_hdr *)pipebuf)->seq != seq) {
        rg_err_count++;
        if (config.debug || (rg_err_count > MAX_RG_COUNT_ERR)) {
          Log(LOG_ERR, "ERROR ( %s/%s ): We are missing data.\n", config.name, config.type);
          Log(LOG_ERR, "If you see this message once in a while, discard it. Otherwise some solutions follow:\n");
          Log(LOG_ERR, "- increase shared memory size, 'plugin_pipe_size'; now: '%d'.\n", config.pipe_size);
          Log(LOG_ERR, "- increase buffer size, 'plugin_buffer_size'; now: '%d'.\n", config.buffer_size);
          Log(LOG_ERR, "- increase system maximum socket size.\n\n");
          seq = ((struct ch_buf_hdr *)pipebuf)->seq;
	}
      }

      if (num > 0) {
	data = (struct pkt_data *) (pipebuf+sizeof(struct ch_buf_hdr));

	while (((struct ch_buf_hdr *)pipebuf)->num > 0) {

	  // XXX: to be optimized: remove empty_* vars
          if (extras.off_pkt_bgp_primitives)
	    pbgp = (struct pkt_bgp_primitives *) ((u_char *)data + extras.off_pkt_bgp_primitives);
	  else pbgp = &empty_pbgp;
          if (extras.off_pkt_nat_primitives) 
            pnat = (struct pkt_nat_primitives *) ((u_char *)data + extras.off_pkt_nat_primitives);
          else pnat = &empty_pnat;
          if (extras.off_pkt_mpls_primitives) 
            pmpls = (struct pkt_mpls_primitives *) ((u_char *)data + extras.off_pkt_mpls_primitives);
          else pmpls = &empty_pmpls;
          if (extras.off_custom_primitives)
	    pcust = ((u_char *)data + extras.off_custom_primitives);
          else pcust = empty_pcust;
	  if (extras.off_pkt_vlen_hdr_primitives)
	    pvlen = (struct pkt_vlen_hdr_primitives *) ((u_char *)data + extras.off_pkt_vlen_hdr_primitives); 
	  else pvlen = &empty_pvlen;

	  for (num = 0; net_funcs[num]; num++)
	    (*net_funcs[num])(&nt, &nc, &data->primitives, pbgp, &nfd);

	  if (config.ports_file) {
	    if (!pt.table[data->primitives.src_port]) data->primitives.src_port = 0;
	    if (!pt.table[data->primitives.dst_port]) data->primitives.dst_port = 0;
	  }

	  if (config.pkt_len_distrib_bins_str &&
	      config.what_to_count_2 & COUNT_PKT_LEN_DISTRIB)
	    evaluate_pkt_len_distrib(data);

	  prim_ptrs.data = data; 
	  prim_ptrs.pbgp = pbgp; 
	  prim_ptrs.pnat = pnat;
	  prim_ptrs.pmpls = pmpls;
	  prim_ptrs.pcust = pcust;
	  prim_ptrs.pvlen = pvlen;
	  
          (*insert_func)(&prim_ptrs);

	  ((struct ch_buf_hdr *)pipebuf)->num--;
	  if (((struct ch_buf_hdr *)pipebuf)->num) {
            dataptr = (unsigned char *) data;
            dataptr += datasize;
            data = (struct pkt_data *) dataptr;
	  }
        }
      }
    } 

    if (reload_map) {
      load_networks(config.networks_file, &nt, &nc);
      load_ports(config.ports_file, &pt);
      reload_map = FALSE;
    }
  }
}
コード例 #19
0
ファイル: addr.c プロジェクト: srsbsns/libsrsbsns
int addr_mksocket(const char *host, const char *service,
    int socktype, int aflags, conbind_t func,
    struct sockaddr *sockaddr, size_t *addrlen,
    int64_t softto_us, int64_t hardto_us)
{
	D("invoked: host='%s', serv='%s', scktype: %d, aflags: %d, func: %s, sto=%lu, hto=%lu", host, service, socktype, aflags, !func ? "(none)" : func == connect ? "connect" : func == bind ? "bind" : "(unkonwn)", softto_us, hardto_us);

	struct addrinfo *ai_list = NULL;
	struct addrinfo hints;
	int64_t hardtsend = hardto_us ? tstamp_us() + hardto_us : 0;
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = socktype;
	hints.ai_protocol = 0;
	hints.ai_flags = aflags;
	if (isdigitstr(service))
		hints.ai_flags |= AI_NUMERICSERV;


	D("calling getaddrinfo on '%s:%s'", host, service);

	int r = getaddrinfo(host, service, &hints, &ai_list);

	if (r != 0) {
		W("getaddrinfo() failed: %s", gai_strerror(r));
		return -1;
	}

	if (!ai_list) {
		W("getaddrinfo() result address list empty");
		return -1;
	}

	bool success = false;
	int sck = -1;

	D("iterating over result list...");
	for (struct addrinfo *ai = ai_list; ai; ai = ai->ai_next) {
		sck = -1;
		if (hardtsend && hardtsend - tstamp_us() <= 0) {
			W("hard timeout");
			return 0;
		}

		D("next result, creating socket (fam=%d, styp=%d, prot=%d)",
		    ai->ai_family, ai->ai_socktype, ai->ai_protocol);

		sck = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
		if (sck < 0) {
			WE("cannot create socket");
			continue;
		}

		char peeraddr[64] = "(non-INET/INET6)";
		unsigned short peerport = 0;

		if (ai->ai_family == AF_INET) {
			struct sockaddr_in *sin =
			    (struct sockaddr_in*)ai->ai_addr;

			inet_ntop(AF_INET, &sin->sin_addr,
			    peeraddr, sizeof peeraddr);

			peerport = ntohs(sin->sin_port);
		} else if (ai->ai_family == AF_INET6) {
			struct sockaddr_in6 *sin =
			    (struct sockaddr_in6*)ai->ai_addr;

			inet_ntop(AF_INET6, &sin->sin6_addr,
			    peeraddr, sizeof peeraddr);

			peerport = ntohs(sin->sin6_port);
		}

		char portstr[7];
		snprintf(portstr, sizeof portstr, ":%hu", peerport);
		strNcat(peeraddr, portstr, sizeof peeraddr);

		int opt = 1;
		socklen_t optlen = sizeof opt;

		D("peer addr is '%s'", peeraddr);

		if (sockaddr)
			*sockaddr = *(ai->ai_addr);
		if (addrlen)
			*addrlen = ai->ai_addrlen;
		
		if (func) {
			D("going non-blocking");
			if (setblocking(sck, false) == -1) {
				WE("failed to enable nonblocking mode");
				close(sck);
				continue;
			}

			D("set to nonblocking mode, calling the backend function...");
			errno = 0;
			bool doselect = false;
			int r = func(sck, ai->ai_addr, ai->ai_addrlen);

			if (r == -1 && (errno != EINPROGRESS)) {
				WE("backend failed");
				close(sck);
				continue;
			} else if (r == -1)
				doselect = true;

			int64_t trem = 0;
			D("backend returned with %d", r);
			if (doselect) {
				if (hardtsend) {
					trem = hardtsend - tstamp_us();
					if (trem <= 0) {
						D("hard timeout detected");
						close(sck);
						continue;
					}
				}

				int64_t softtsend = softto_us ? tstamp_us() + softto_us : 0;

				if (softtsend) {
					int64_t trem_tmp = softtsend - tstamp_us();

					if (trem_tmp <= 0) {
						W("soft timeout");
						close(sck);
						continue;
					}

					if (trem_tmp < trem)
						trem = trem_tmp;
				}

				D("calling io_select1w (timeout: %lld us)", trem);
				r = io_select1w(sck, trem, true);

				if (r < 0) {
					WE("select() failed");
					close(sck);
					continue;
				} else if (!r) {
					W("select() timeout");
					close(sck);
					continue;
				} else
					D("selected!");

				D("calling getsockopt to query error state");
				if (getsockopt(sck, SOL_SOCKET, SO_ERROR, &opt, &optlen) != 0) {
					W("getsockopt failed");
					close(sck);
					continue;
				}

				if (opt == 0) {
					I("socket in good shape! ('%s')", peeraddr);
					if (setblocking(sck, true) == -1) {
						WE("failed to disable nonblocking mode");
						close(sck);
						continue;
					}
					success = true;
					break;
				} else {
					char errstr[256];
					strerror_r(opt, errstr, sizeof errstr);
					W("backend function failed (%d: %s)", opt, errstr);
					close(sck);
					continue;
				}
			} else {
				I("There we go... ('%s')", peeraddr);
				if (setblocking(sck, true) == -1) {
					WE("failed to disable nonblocking mode");
					close(sck);
					continue;
				}
				success = true;
				break;
			}

		} else {
			success = true;
			break;
		}
	}
	
	D("after loop; alling freeaddrinfo then returning %d", sck);

	freeaddrinfo(ai_list);

	return success ? sck : -1;
}
コード例 #20
0
ファイル: cmd-pipe-pane.c プロジェクト: 20400992/tmux
enum cmd_retval
cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct client		*c = cmdq->state.c;
	struct window_pane	*wp = cmdq->state.tflag.wp;
	struct session		*s = cmdq->state.tflag.s;
	struct winlink		*wl = cmdq->state.tflag.wl;
	char			*cmd;
	int			 old_fd, pipe_fd[2], null_fd;
	struct format_tree	*ft;

	/* Destroy the old pipe. */
	old_fd = wp->pipe_fd;
	if (wp->pipe_fd != -1) {
		bufferevent_free(wp->pipe_event);
		close(wp->pipe_fd);
		wp->pipe_fd = -1;
	}

	/* If no pipe command, that is enough. */
	if (args->argc == 0 || *args->argv[0] == '\0')
		return (CMD_RETURN_NORMAL);

	/*
	 * With -o, only open the new pipe if there was no previous one. This
	 * allows a pipe to be toggled with a single key, for example:
	 *
	 *	bind ^p pipep -o 'cat >>~/output'
	 */
	if (args_has(self->args, 'o') && old_fd != -1)
		return (CMD_RETURN_NORMAL);

	/* Open the new pipe. */
	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_fd) != 0) {
		cmdq_error(cmdq, "socketpair error: %s", strerror(errno));
		return (CMD_RETURN_ERROR);
	}

	/* Expand the command. */
	ft = format_create(cmdq, 0);
	format_defaults(ft, c, s, wl, wp);
	cmd = format_expand_time(ft, args->argv[0], time(NULL));
	format_free(ft);

	/* Fork the child. */
	switch (fork()) {
	case -1:
		cmdq_error(cmdq, "fork error: %s", strerror(errno));

		free(cmd);
		return (CMD_RETURN_ERROR);
	case 0:
		/* Child process. */
		close(pipe_fd[0]);
		clear_signals(1);

		if (dup2(pipe_fd[1], STDIN_FILENO) == -1)
			_exit(1);
		if (pipe_fd[1] != STDIN_FILENO)
			close(pipe_fd[1]);

		null_fd = open(_PATH_DEVNULL, O_WRONLY, 0);
		if (dup2(null_fd, STDOUT_FILENO) == -1)
			_exit(1);
		if (dup2(null_fd, STDERR_FILENO) == -1)
			_exit(1);
		if (null_fd != STDOUT_FILENO && null_fd != STDERR_FILENO)
			close(null_fd);

		closefrom(STDERR_FILENO + 1);

		execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);
		_exit(1);
	default:
		/* Parent process. */
		close(pipe_fd[1]);

		wp->pipe_fd = pipe_fd[0];
		wp->pipe_off = EVBUFFER_LENGTH(wp->event->input);

		wp->pipe_event = bufferevent_new(wp->pipe_fd,
		    NULL, NULL, cmd_pipe_pane_error_callback, wp);
		bufferevent_enable(wp->pipe_event, EV_WRITE);

		setblocking(wp->pipe_fd, 0);

		free(cmd);
		return (CMD_RETURN_NORMAL);
	}
}
コード例 #21
0
ファイル: cmd-pipe-pane.c プロジェクト: Hooman3/minix
int
cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct args		*args = self->args;
	struct client		*c;
	struct window_pane	*wp;
	char			*command;
	int			 old_fd, pipe_fd[2], null_fd;

	if ((c = cmd_find_client(ctx, NULL)) == NULL)
		return (-1);

	if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL)
		return (-1);

	/* Destroy the old pipe. */
	old_fd = wp->pipe_fd;
	if (wp->pipe_fd != -1) {
		bufferevent_free(wp->pipe_event);
		close(wp->pipe_fd);
		wp->pipe_fd = -1;
	}

	/* If no pipe command, that is enough. */
	if (args->argc == 0 || *args->argv[0] == '\0')
		return (0);

	/*
	 * With -o, only open the new pipe if there was no previous one. This
	 * allows a pipe to be toggled with a single key, for example:
	 *
	 *	bind ^p pipep -o 'cat >>~/output'
	 */
	if (args_has(self->args, 'o') && old_fd != -1)
		return (0);

	/* Open the new pipe. */
	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_fd) != 0) {
		ctx->error(ctx, "socketpair error: %s", strerror(errno));
		return (-1);
	}

	/* Fork the child. */
	switch (fork()) {
	case -1:
		ctx->error(ctx, "fork error: %s", strerror(errno));
		return (-1);
	case 0:
		/* Child process. */
		close(pipe_fd[0]);
		clear_signals(1);

		if (dup2(pipe_fd[1], STDIN_FILENO) == -1)
			_exit(1);
		if (pipe_fd[1] != STDIN_FILENO)
			close(pipe_fd[1]);

		null_fd = open(_PATH_DEVNULL, O_WRONLY, 0);
		if (dup2(null_fd, STDOUT_FILENO) == -1)
			_exit(1);
		if (dup2(null_fd, STDERR_FILENO) == -1)
			_exit(1);
		if (null_fd != STDOUT_FILENO && null_fd != STDERR_FILENO)
			close(null_fd);

		closefrom(STDERR_FILENO + 1);

		command = status_replace(
		    c, NULL, NULL, NULL, args->argv[0], time(NULL), 0);
		execl(_PATH_BSHELL, "sh", "-c", command, (char *) NULL);
		_exit(1);
	default:
		/* Parent process. */
		close(pipe_fd[1]);

		wp->pipe_fd = pipe_fd[0];
		wp->pipe_off = EVBUFFER_LENGTH(wp->event->input);

		wp->pipe_event = bufferevent_new(wp->pipe_fd,
		    NULL, NULL, cmd_pipe_pane_error_callback, wp);
		bufferevent_enable(wp->pipe_event, EV_WRITE);

		setblocking(wp->pipe_fd, 0);
		return (0);
	}
}
コード例 #22
0
ファイル: modeegdriver.c プロジェクト: BCI-AR/NeuroServer
int main(int argc, char **argv)
{
    char responseBuf[MAXLEN];
    int i;
    int retval;
    ser_t serport;
    char EDFPacket[MAXHEADERLEN];
    int EDFLen = MAXHEADERLEN;
    /// buffer for reading from serial port
    char smallbuf[PROTOWINDOW];
    char *hostname = NULL;
    char *deviceName = NULL;
    /// DEFAULTHOST;
    unsigned short portno = 0;
    ///  DEFAULTPORT;
    struct timeval when;

    rprintf("ModEEG Driver v. %s-%s\n", VERSION, OSTYPESTR);

    rinitNetworking();
    /// process command line inputs
    for (i = 1; argv[i]; ++i) {
        if (argv[i][0] == '-' && argv[i][1] == 'h') {
            printHelp();
            exit(0);
        }
        if (argv[i][0] == '-' && argv[i][1] == 'd') {
            if (argv[i+1] == NULL) {
                rprintf("Bad devicename option: %s\nExpected device name as next argument.\n", argv[i]);
                exit(1);
            }
            deviceName = argv[i+1];
            i += 1;
            continue;
        }
        if (hostname == NULL) {
            hostname = argv[i];
            continue;
        }
        if (portno == 0) {
            portno = atoi(argv[i]);
            continue;
        }
    }
    if (deviceName == NULL)
        deviceName = DEFAULTDEVICE;
    if (portno == 0)
        portno = DEFAULTPORT;
    if (hostname == NULL)
        hostname = DEFAULTHOST;

    makeREDFConfig(&current, &modEEGCfg);
    writeEDFString(&current, EDFPacket, &EDFLen);


    sock_fd = rsocket();
    if (sock_fd < 0) {
        perror("socket");
        rexit(1);
    }
    setblocking(sock_fd);

    rprintf("Attempting to connect to nsd at %s:%d\n", hostname, portno);
    retval = rconnectName(sock_fd, hostname, portno);
    if (retval != 0) {
        rprintf("connect error\n");
        rexit(1);
    }
    rprintf("Socket connected.\n");
    fflush(stdout);

    serport = openSerialPort(deviceName,57600);
    rprintf("Serial port %s opened.\n", deviceName);

    writeString(sock_fd, "eeg\n", &ob);
    mGetOK(sock_fd, &ib);
    writeString(sock_fd, "setheader ", &ob);
    writeBytes(sock_fd, EDFPacket, EDFLen, &ob);
    writeString(sock_fd, "\n", &ob);
    mGetOK(sock_fd, &ib);
    updateMaxFd(sock_fd);
#ifndef __MINGW32__
    updateMaxFd(serport);
#endif
    when.tv_usec = (1000000L / modEEGCfg.chan[0].sampleCount);
    rprintf("Polling at %d Hertz or %d usec\n", modEEGCfg.chan[0].sampleCount, when.tv_usec);
    for (;;) {
        int i, readSerBytes;
        int retval;
        fd_set toread;
        when.tv_sec = 0;
        when.tv_usec = (1000000L / modEEGCfg.chan[0].sampleCount);
        FD_ZERO(&toread);
        FD_SET(sock_fd, &toread);
#ifndef __MINGW32__
        FD_SET(serport, &toread);
#endif
        retval = rselect_timed(max_fd, &toread, NULL, NULL, &when);
        readSerBytes = readSerial(serport, smallbuf, PROTOWINDOW);
        if (readSerBytes < 0) {
            rprintf("Serial error.\n");
        }
        if (readSerBytes > 0) {
            for (i = 0; i < readSerBytes; ++i)
                eatCharacter(smallbuf[i]);
        }
        if (FD_ISSET(sock_fd, &toread)) {
            my_read(sock_fd, responseBuf, MAXLEN, &ib);
        }
        if (isEOF(sock_fd, &ib)) {
            rprintf("Server died, exitting.\n");
            exit(0);
        }
    }

    return 0;
}
コード例 #23
0
ファイル: job.c プロジェクト: wilywampa/tmux
/* Start a job running, if it isn't already. */
struct job *
job_run(const char *cmd, struct session *s, const char *cwd,
    job_update_cb updatecb, job_complete_cb completecb, job_free_cb freecb,
    void *data)
{
	struct job	*job;
	struct environ	*env;
	pid_t		 pid;
	int		 nullfd, out[2];
	const char	*home;

	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, out) != 0)
		return (NULL);

	/*
	 * Do not set TERM during .tmux.conf, it is nice to be able to use
	 * if-shell to decide on default-terminal based on outside TERM.
	 */
	env = environ_for_session(s, !cfg_finished);

	switch (pid = fork()) {
	case -1:
		environ_free(env);
		close(out[0]);
		close(out[1]);
		return (NULL);
	case 0:		/* child */
		clear_signals(1);

		if (cwd == NULL || chdir(cwd) != 0) {
			if ((home = find_home()) == NULL || chdir(home) != 0)
				chdir("/");
		}

		environ_push(env);
		environ_free(env);

		if (dup2(out[1], STDIN_FILENO) == -1)
			fatal("dup2 failed");
		if (dup2(out[1], STDOUT_FILENO) == -1)
			fatal("dup2 failed");
		if (out[1] != STDIN_FILENO && out[1] != STDOUT_FILENO)
			close(out[1]);
		close(out[0]);

		nullfd = open(_PATH_DEVNULL, O_RDWR, 0);
		if (nullfd < 0)
			fatal("open failed");
		if (dup2(nullfd, STDERR_FILENO) == -1)
			fatal("dup2 failed");
		if (nullfd != STDERR_FILENO)
			close(nullfd);

		closefrom(STDERR_FILENO + 1);

		execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);
		fatal("execl failed");
	}

	/* parent */
	environ_free(env);
	close(out[1]);

	job = xmalloc(sizeof *job);
	job->state = JOB_RUNNING;

	job->cmd = xstrdup(cmd);
	job->pid = pid;
	job->status = 0;

	LIST_INSERT_HEAD(&all_jobs, job, entry);

	job->updatecb = updatecb;
	job->completecb = completecb;
	job->freecb = freecb;
	job->data = data;

	job->fd = out[0];
	setblocking(job->fd, 0);

	job->event = bufferevent_new(job->fd, job_read_callback,
	    job_write_callback, job_error_callback, job);
	bufferevent_enable(job->event, EV_READ|EV_WRITE);

	log_debug("run job %p: %s, pid %ld", job, job->cmd, (long) job->pid);
	return (job);
}