コード例 #1
0
ファイル: tcp.c プロジェクト: zsh-users/zsh
int
cleanup_(Module m)
{
    tcp_cleanup();
    freelinklist(ztcp_sessions, (FreeFunc) ztcp_free_session);
    return setfeatureenables(m, &module_features, NULL);
}
コード例 #2
0
/* ARGSUSED */
void
tcp_time_wait_collector(void *arg)
{
	tcp_t *tcp;
	int64_t now;
	mblk_t *mp;
	conn_t *connp;
	kmutex_t *lock;
	boolean_t removed;
	extern void (*cl_inet_disconnect)(netstackid_t, uint8_t, sa_family_t,
	    uint8_t *, in_port_t, uint8_t *, in_port_t, void *);

	squeue_t *sqp = (squeue_t *)arg;
	tcp_squeue_priv_t *tcp_time_wait =
	    *((tcp_squeue_priv_t **)squeue_getprivate(sqp, SQPRIVATE_TCP));

	mutex_enter(&tcp_time_wait->tcp_time_wait_lock);
	tcp_time_wait->tcp_time_wait_tid = 0;
#ifdef DEBUG
	tcp_time_wait->tcp_time_wait_running = B_TRUE;
#endif

	if (tcp_time_wait->tcp_free_list != NULL &&
	    tcp_time_wait->tcp_free_list->tcp_in_free_list == B_TRUE) {
		TCP_G_STAT(tcp_freelist_cleanup);
		while ((tcp = tcp_time_wait->tcp_free_list) != NULL) {
			tcp_time_wait->tcp_free_list = tcp->tcp_time_wait_next;
			tcp->tcp_time_wait_next = NULL;
			tcp_time_wait->tcp_free_list_cnt--;
			ASSERT(tcp->tcp_tcps == NULL);
			CONN_DEC_REF(tcp->tcp_connp);
		}
		ASSERT(tcp_time_wait->tcp_free_list_cnt == 0);
	}

	/*
	 * In order to reap time waits reliably, we should use a
	 * source of time that is not adjustable by the user -- hence
	 * the call to ddi_get_lbolt64().
	 */
	now = ddi_get_lbolt64();
	while ((tcp = tcp_time_wait->tcp_time_wait_head) != NULL) {
		/*
		 * lbolt64 should not wrap around in practice...  So we can
		 * do a direct comparison.
		 */
		if (now < tcp->tcp_time_wait_expire)
			break;

		removed = tcp_time_wait_remove(tcp, tcp_time_wait);
		ASSERT(removed);

		connp = tcp->tcp_connp;
		ASSERT(connp->conn_fanout != NULL);
		lock = &connp->conn_fanout->connf_lock;
		/*
		 * This is essentially a TW reclaim fast path optimization for
		 * performance where the timewait collector checks under the
		 * fanout lock (so that no one else can get access to the
		 * conn_t) that the refcnt is 2 i.e. one for TCP and one for
		 * the classifier hash list. If ref count is indeed 2, we can
		 * just remove the conn under the fanout lock and avoid
		 * cleaning up the conn under the squeue, provided that
		 * clustering callbacks are not enabled. If clustering is
		 * enabled, we need to make the clustering callback before
		 * setting the CONDEMNED flag and after dropping all locks and
		 * so we forego this optimization and fall back to the slow
		 * path. Also please see the comments in tcp_closei_local
		 * regarding the refcnt logic.
		 *
		 * Since we are holding the tcp_time_wait_lock, its better
		 * not to block on the fanout_lock because other connections
		 * can't add themselves to time_wait list. So we do a
		 * tryenter instead of mutex_enter.
		 */
		if (mutex_tryenter(lock)) {
			mutex_enter(&connp->conn_lock);
			if ((connp->conn_ref == 2) &&
			    (cl_inet_disconnect == NULL)) {
				ipcl_hash_remove_locked(connp,
				    connp->conn_fanout);
				/*
				 * Set the CONDEMNED flag now itself so that
				 * the refcnt cannot increase due to any
				 * walker.
				 */
				connp->conn_state_flags |= CONN_CONDEMNED;
				mutex_exit(lock);
				mutex_exit(&connp->conn_lock);
				if (tcp_time_wait->tcp_free_list_cnt <
				    tcp_free_list_max_cnt) {
					/* Add to head of tcp_free_list */
					mutex_exit(
					    &tcp_time_wait->tcp_time_wait_lock);
					tcp_cleanup(tcp);
					ASSERT(connp->conn_latch == NULL);
					ASSERT(connp->conn_policy == NULL);
					ASSERT(tcp->tcp_tcps == NULL);
					ASSERT(connp->conn_netstack == NULL);

					mutex_enter(
					    &tcp_time_wait->tcp_time_wait_lock);
					tcp->tcp_time_wait_next =
					    tcp_time_wait->tcp_free_list;
					tcp_time_wait->tcp_free_list = tcp;
					tcp_time_wait->tcp_free_list_cnt++;
					continue;
				} else {
					/* Do not add to tcp_free_list */
					mutex_exit(
					    &tcp_time_wait->tcp_time_wait_lock);
					tcp_bind_hash_remove(tcp);
					ixa_cleanup(tcp->tcp_connp->conn_ixa);
					tcp_ipsec_cleanup(tcp);
					CONN_DEC_REF(tcp->tcp_connp);
				}
			} else {
				CONN_INC_REF_LOCKED(connp);
				mutex_exit(lock);
				mutex_exit(&tcp_time_wait->tcp_time_wait_lock);
				mutex_exit(&connp->conn_lock);
				/*
				 * We can reuse the closemp here since conn has
				 * detached (otherwise we wouldn't even be in
				 * time_wait list). tcp_closemp_used can safely
				 * be changed without taking a lock as no other
				 * thread can concurrently access it at this
				 * point in the connection lifecycle.
				 */

				if (tcp->tcp_closemp.b_prev == NULL)
					tcp->tcp_closemp_used = B_TRUE;
				else
					cmn_err(CE_PANIC,
					    "tcp_timewait_collector: "
					    "concurrent use of tcp_closemp: "
					    "connp %p tcp %p\n", (void *)connp,
					    (void *)tcp);

				TCP_DEBUG_GETPCSTACK(tcp->tcmp_stk, 15);
				mp = &tcp->tcp_closemp;
				SQUEUE_ENTER_ONE(connp->conn_sqp, mp,
				    tcp_timewait_close, connp, NULL,
				    SQ_FILL, SQTAG_TCP_TIMEWAIT);
			}
		} else {
			mutex_enter(&connp->conn_lock);
			CONN_INC_REF_LOCKED(connp);
			mutex_exit(&tcp_time_wait->tcp_time_wait_lock);
			mutex_exit(&connp->conn_lock);
			/*
			 * We can reuse the closemp here since conn has
			 * detached (otherwise we wouldn't even be in
			 * time_wait list). tcp_closemp_used can safely
			 * be changed without taking a lock as no other
			 * thread can concurrently access it at this
			 * point in the connection lifecycle.
			 */

			if (tcp->tcp_closemp.b_prev == NULL)
				tcp->tcp_closemp_used = B_TRUE;
			else
				cmn_err(CE_PANIC, "tcp_timewait_collector: "
				    "concurrent use of tcp_closemp: "
				    "connp %p tcp %p\n", (void *)connp,
				    (void *)tcp);

			TCP_DEBUG_GETPCSTACK(tcp->tcmp_stk, 15);
			mp = &tcp->tcp_closemp;
			SQUEUE_ENTER_ONE(connp->conn_sqp, mp,
			    tcp_timewait_close, connp, NULL,
			    SQ_FILL, SQTAG_TCP_TIMEWAIT);
		}
		mutex_enter(&tcp_time_wait->tcp_time_wait_lock);
	}

	if (tcp_time_wait->tcp_free_list != NULL)
		tcp_time_wait->tcp_free_list->tcp_in_free_list = B_TRUE;

	/*
	 * If the time wait list is not empty and there is no timer running,
	 * restart it.
	 */
	if ((tcp = tcp_time_wait->tcp_time_wait_head) != NULL &&
	    tcp_time_wait->tcp_time_wait_tid == 0) {
		hrtime_t firetime;

		firetime = TICK_TO_NSEC(tcp->tcp_time_wait_expire - now);
		/* This ensures that we won't wake up too often. */
		firetime = MAX(TCP_TIME_WAIT_DELAY, firetime);
		tcp_time_wait->tcp_time_wait_tid =
		    timeout_generic(CALLOUT_NORMAL, tcp_time_wait_collector,
		    sqp, firetime, CALLOUT_TCP_RESOLUTION,
		    CALLOUT_FLAG_ROUNDUP);
	}
#ifdef DEBUG
	tcp_time_wait->tcp_time_wait_running = B_FALSE;
#endif
	mutex_exit(&tcp_time_wait->tcp_time_wait_lock);
}
コード例 #3
0
ファイル: ip_input.c プロジェクト: cminyard/qemu
void ip_cleanup(Slirp *slirp)
{
    udp_cleanup(slirp);
    tcp_cleanup(slirp);
    icmp_cleanup(slirp);
}
コード例 #4
0
ファイル: main.c プロジェクト: darknrgy/6WD-Robot
/* Main routine for the server threads */
thr_startfunc_t serve_pipe(void *data)
{
	char sio_buf[BUFSIZ], sock_buf[BUFSIZ];
	int fd_max, sio_fd, sock_fd;
	int sio_count, sock_count;
	int res, port;
	fd_set rfds, wfds;
	pipe_s *pipe = (pipe_s *)data;
#if defined(__UNIX__)
	struct timeval tv = {pipe->timeout, 0};
	struct timeval *ptv = &tv;
#elif defined(__WIN32__)
	struct timeval tv = {0,10000};
	struct timeval *ptv = &tv;
	DWORD msecs = 0, timeout = pipe->timeout * 1000;
#endif

	port = pipe->sio.info.port;

	/* Only proceed if we can lock the mutex */
	if (thr_mutex_trylock(pipe->mutex))
	{
		error("server(%d) - resource is locked", port);
	}
	else
	{

		sio_count = 0;
		sock_count = 0;
		sio_fd = pipe->sio.fd;
		sock_fd = pipe->sock.fd;
#if defined(__UNIX__)
		fd_max = sio_fd > sock_fd ? sio_fd : sock_fd;	
#elif defined(__WIN32__)
		fd_max = sock_fd;
		msecs = GetTickCount();
#endif
		fprintf(stderr, "server(%d) - thread started\n", port);
		
		while (1)
		{
			FD_ZERO(&rfds);
			FD_ZERO(&wfds);

#if defined(__UNIX__)
			/* Always ask for read notification to check for EOF */			
			FD_SET(sio_fd, &rfds);
			/* Only ask for write notification if we have something to write */
			if (sock_count > 0)
				FD_SET(sio_fd, &wfds);

			/* Reset timeout values */
			tv.tv_sec = pipe->timeout;
			tv.tv_usec = 0;

#endif
			/* Always ask for read notification to check for EOF */
			FD_SET(sock_fd, &rfds);
			/* Only ask for write notification if we have something to write */
			if (sio_count > 0)
				FD_SET(sock_fd, &wfds);

			//DBG_MSG2("server(%d) waiting for events", port);
			
			/* Wait for read/write events */
			res = select(fd_max + 1, &rfds, &wfds, NULL, ptv);
			if (res == -1)
			{
				perror2("server(%d) - select()", port);
				break;
			}
#if defined(__UNIX__)

			/* Use the select result for timeout detection */
			if (res == 0)
			{
				fprintf(stderr, "server(%d) - timed out\n", port);
				break;
			}

			/* Input from serial port? */
			if (FD_ISSET(sio_fd, &rfds))
#elif defined(__WIN32__)
				
			if (1)
#endif
			{
				/* Only read input if buffer is empty */
				if (sio_count == 0)
				{
					sio_count = sio_read(&pipe->sio, sio_buf, sizeof(sio_buf));
					if (sio_count <= 0)
					{
						if (sio_count == 0)
						{
#if defined(__UNIX__)
							fprintf(stderr, "server(%d) - EOF from sio\n", port);
							break;
#endif
						}
						else
						{
							perror2("server(%d) - read(sio)", port);
							break;
						}
					}
					else 
					{
						DBG_MSG3("server(%d) - read %d bytes from sio", port, sio_count);
					}
				}
			}

			/* Write to socket possible? */
			if (FD_ISSET(sock_fd, &wfds))
			{
				if (sio_count > 0)
				{
					if ((res = tcp_write(&pipe->sock, sio_buf, sio_count)) < 0)
					{
						perror2("server(%d) - write(sock)", port);
						break;
					}
					DBG_MSG3("server(%d) - Wrote %d bytes to sock", port, res);
					sio_count -= res;
				}
			}


			/* Input from socket? */
			if (FD_ISSET(sock_fd, &rfds))
			{
				/* Only read input if buffer is empty */
				if (sock_count == 0)
				{
					sock_count = tcp_read(&pipe->sock, sock_buf, sizeof(sock_buf));
					if (sock_count <= 0)
					{
						if (sock_count == 0)
						{
							fprintf(stderr, "server(%d) - EOF from sock\n", port);
							break;
						}
						else
						{
							perror2("server(%d) - read(sock)", port);
							break;
						}
					}
					DBG_MSG3("server(%d) - read %d bytes from sock", port, sock_count);
				}
			}

#if defined(__UNIX__)
			/* Write to serial port possible? */
			if (FD_ISSET(sio_fd, &wfds))
#elif defined(__WIN32__)
			
			/* No socket IO performed? */
			if ((!FD_ISSET(sock_fd, &rfds)) && (!FD_ISSET(sock_fd, &wfds)))
			{
				/* Break on a time out */
				if (GetTickCount() - msecs > timeout)
				{
					fprintf(stderr, "server(%d) - timed out\n", port);
					break;					
				}
			}
			else
			{
				msecs = GetTickCount();
			}

			if (1)
#endif
			{
				if (sock_count > 0)
				{
					if ((res = sio_write(&pipe->sio, sock_buf, sock_count)) < 0)
					{
						perror2("server(%d) - write(sio)", port);
						break;
					}
					DBG_MSG3("server(%d) - wrote %d bytes to sio", port, res);
					sock_count -= res;
				}
			}

		}
		
		/* Unlock our mutex */
		thr_mutex_unlock(pipe->mutex);		
	}

   	fprintf(stderr, "server(%d) exiting\n", port);

	/* Clean up - don't call pipe_cleanup() as that would nuke our mutex */
	sio_cleanup(&pipe->sio);
	tcp_cleanup(&pipe->sock);


	free(pipe);
	
	thr_exit((thr_exitcode_t)0);

	return (thr_exitcode_t)0;
}
コード例 #5
0
ファイル: tcp.c プロジェクト: zsh-users/zsh
static int
bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
{
    int herrno, err=1, destport, force=0, verbose=0, test=0, targetfd=0;
    ZSOCKLEN_T  len;
    char **addrp, *desthost;
    const char *localname, *remotename;
    struct hostent *zthost = NULL, *ztpeer = NULL;
    struct servent *srv;
    Tcp_session sess = NULL;

    if (OPT_ISSET(ops,'f'))
	force = 1;

    if (OPT_ISSET(ops,'v'))
	verbose = 1;

    if (OPT_ISSET(ops,'t'))
        test = 1;

    if (OPT_ISSET(ops,'d')) {
	targetfd = atoi(OPT_ARG(ops,'d'));
	if (!targetfd) {
	    zwarnnam(nam, "%s is an invalid argument to -d", OPT_ARG(ops,'d'));
	    return 1;
	}
    }


    if (OPT_ISSET(ops,'c')) {
	if (!args[0]) {
	    tcp_cleanup();
	}
	else {
	    targetfd = atoi(args[0]);
	    sess = zts_byfd(targetfd);
	    if(!targetfd) {
		zwarnnam(nam, "%s is an invalid argument to -c", args[0]);
		return 1;
	    }

	    if (sess)
	    {
		if ((sess->flags & ZTCP_ZFTP) && !force)
		{
		    zwarnnam(nam, "use -f to force closure of a zftp control connection");
		    return 1;
		}
		tcp_close(sess);
		return 0;
	    }
	    else
	    {
		zwarnnam(nam, "fd %s not found in tcp table", args[0]);
		return 1;
	    }
	}
    }
    else if (OPT_ISSET(ops,'l')) {
	int lport = 0;

	if (!args[0]) {
	    zwarnnam(nam, "-l requires an argument");
	    return 1;
	}

	srv = getservbyname(args[0], "tcp");
	if (srv)
	    lport = srv->s_port;
	else
	    lport = htons(atoi(args[0]));
	if (!lport) { zwarnnam(nam, "bad service name or port number");
	return 1;
	}
	sess = tcp_socket(PF_INET, SOCK_STREAM, 0, ZTCP_LISTEN);

	if (!sess) {
	    zwarnnam(nam, "unable to allocate a TCP session slot");
	    return 1;
	}
#ifdef SO_OOBINLINE
	len = 1;
	setsockopt(sess->fd, SOL_SOCKET, SO_OOBINLINE, (char *)&len, sizeof(len));
#endif
	if (!zsh_inet_aton("0.0.0.0", &(sess->sock.in.sin_addr)))
	{
	    zwarnnam(nam, "bad address: %s", "0.0.0.0");
	    return 1;
	}

	sess->sock.in.sin_family = AF_INET;
	sess->sock.in.sin_port = lport;


	if (bind(sess->fd, (struct sockaddr *)&sess->sock.in, sizeof(struct sockaddr_in)))
	{
	    char buf[DIGBUFSIZE];
	    convbase(buf, (zlong)ntohs(lport), 10);
	    zwarnnam(nam, "could not bind to port %s: %e", buf, errno);
	    tcp_close(sess);
	    return 1;
	}

	if (listen(sess->fd, 1))
	{
	    zwarnnam(nam, "could not listen on socket: %e", errno);
	    tcp_close(sess);
	    return 1;
	}

	if (targetfd) {
	    sess->fd = redup(sess->fd, targetfd);
	}
	else {
	    /* move the fd since no one will want to read from it */
	    sess->fd = movefd(sess->fd);
	}

	if (sess->fd == -1) {
	    zwarnnam(nam, "cannot duplicate fd %d: %e", sess->fd, errno);
	    tcp_close(sess);
	    return 1;
	}

	setiparam_no_convert("REPLY", (zlong)sess->fd);

	if (verbose)
	    printf("%d listener is on fd %d\n", ntohs(sess->sock.in.sin_port), sess->fd);

	return 0;

    }
    else if (OPT_ISSET(ops,'a'))
    {
	int lfd, rfd;

	if (!args[0]) {
	    zwarnnam(nam, "-a requires an argument");
	    return 1;
	}

	lfd = atoi(args[0]);

	if (!lfd) {
	    zwarnnam(nam, "invalid numerical argument");
	    return 1;
	}

	sess = zts_byfd(lfd);
	if (!sess) {
	    zwarnnam(nam, "fd %s is not registered as a tcp connection", args[0]);
	    return 1;
	}

	if (!(sess->flags & ZTCP_LISTEN))
	{
	    zwarnnam(nam, "tcp connection not a listener");
	    return 1;
	}

	if (test) {
#if defined(HAVE_POLL) || defined(HAVE_SELECT)
# ifdef HAVE_POLL
	    struct pollfd pfd;
	    int ret;

	    pfd.fd = lfd;
	    pfd.events = POLLIN;
	    if ((ret = poll(&pfd, 1, 0)) == 0) return 1;
	    else if (ret == -1)
	    {
		zwarnnam(nam, "poll error: %e", errno);
		return 1;
	    }
# else
	    fd_set rfds;
	    struct timeval tv;
	    int ret;
	    
	    FD_ZERO(&rfds);
	    FD_SET(lfd, &rfds);
	    tv.tv_sec = 0;
	    tv.tv_usec = 0;
	    
	    if ((ret = select(lfd+1, &rfds, NULL, NULL, &tv)) == 0) return 1;
	    else if (ret == -1)
	    {
		zwarnnam(nam, "select error: %e", errno);
		return 1;
	    }
	    
# endif
	    
#else
	    zwarnnam(nam, "not currently supported");
	    return 1;
#endif
	}
	sess = zts_alloc(ZTCP_INBOUND);

	len = sizeof(sess->peer.in);
	do {
	    rfd = accept(lfd, (struct sockaddr *)&sess->peer.in, &len);
	} while (rfd < 0 && errno == EINTR && !errflag);

	if (rfd == -1) {
	    zwarnnam(nam, "could not accept connection: %e", errno);
	    tcp_close(sess);
	    return 1;
	}

	/* redup expects fd is already registered */
	addmodulefd(rfd, FDT_MODULE);

	if (targetfd) {
	    sess->fd = redup(rfd, targetfd);
	    if (sess->fd < 0) {
		zerrnam(nam, "could not duplicate socket fd to %d: %e", targetfd, errno);
		return 1;
	    }
	}
	else {
	    sess->fd = rfd;
	}

	setiparam_no_convert("REPLY", (zlong)sess->fd);

	if (verbose)
	    printf("%d is on fd %d\n", ntohs(sess->peer.in.sin_port), sess->fd);
    }
    else
    {
	if (!args[0]) {
	    LinkNode node;
	    for(node = firstnode(ztcp_sessions); node; incnode(node))
	    {
		sess = (Tcp_session)getdata(node);

		if (sess->fd != -1)
		{
		    zthost = gethostbyaddr((const void *)&(sess->sock.in.sin_addr), sizeof(sess->sock.in.sin_addr), AF_INET);
		    if (zthost)
			localname = zthost->h_name;
		    else
			localname = inet_ntoa(sess->sock.in.sin_addr);
		    ztpeer = gethostbyaddr((const void *)&(sess->peer.in.sin_addr), sizeof(sess->peer.in.sin_addr), AF_INET);
		    if (ztpeer)
			remotename = ztpeer->h_name;
		    else
			remotename = inet_ntoa(sess->peer.in.sin_addr);
		    if (OPT_ISSET(ops,'L')) {
			int schar;
			if (sess->flags & ZTCP_ZFTP)
			    schar = 'Z';
			else if (sess->flags & ZTCP_LISTEN)
			    schar = 'L';
			else if (sess->flags & ZTCP_INBOUND)
			    schar = 'I';
			else
			    schar = 'O';
			printf("%d %c %s %d %s %d\n",
			       sess->fd, schar,
			       localname, ntohs(sess->sock.in.sin_port),
			       remotename, ntohs(sess->peer.in.sin_port));
		    } else {
			printf("%s:%d %s %s:%d is on fd %d%s\n",
			       localname, ntohs(sess->sock.in.sin_port),
			       ((sess->flags & ZTCP_LISTEN) ? "-<" :
				((sess->flags & ZTCP_INBOUND) ? "<-" : "->")),
			       remotename, ntohs(sess->peer.in.sin_port),
			       sess->fd,
			       (sess->flags & ZTCP_ZFTP) ? " ZFTP" : "");
		    }
		}
	    }
	    return 0;
	}
	else if (!args[1]) {
	    destport = htons(23);
	}
	else {

	    srv = getservbyname(args[1],"tcp");
	    if (srv)
		destport = srv->s_port;
	    else
		destport = htons(atoi(args[1]));
	}
	
	desthost = ztrdup(args[0]);
	
	zthost = zsh_getipnodebyname(desthost, AF_INET, 0, &herrno);
	if (!zthost || errflag) {
	    zwarnnam(nam, "host resolution failure: %s", desthost);
	    zsfree(desthost);
	    return 1;
	}
	
	sess = tcp_socket(PF_INET, SOCK_STREAM, 0, 0);

	if (!sess) {
	    zwarnnam(nam, "unable to allocate a TCP session slot");
	    zsfree(desthost);
	    return 1;
	}

#ifdef SO_OOBINLINE
	len = 1;
	setsockopt(sess->fd, SOL_SOCKET, SO_OOBINLINE, (char *)&len, sizeof(len));
#endif

	if (sess->fd < 0) {
	    zwarnnam(nam, "socket creation failed: %e", errno);
	    zsfree(desthost);
	    zts_delete(sess);
	    return 1;
	}
	
	for (addrp = zthost->h_addr_list; err && *addrp; addrp++) {
	    if (zthost->h_length != 4)
		zwarnnam(nam, "address length mismatch");
	    do {
		err = tcp_connect(sess, *addrp, zthost, destport);
	    } while (err && errno == EINTR && !errflag);
	}
	
	if (err) {
	    zwarnnam(nam, "connection failed: %e", errno);
	    tcp_close(sess);
	    zsfree(desthost);
	    return 1;
	}
	else
	{
	    if (targetfd) {
		sess->fd = redup(sess->fd, targetfd);
		if (sess->fd < 0) {
		    zerrnam(nam, "could not duplicate socket fd to %d: %e", targetfd, errno);
		    zsfree(desthost);
		    tcp_close(sess);
		    return 1;
		}
	    }

	    setiparam_no_convert("REPLY", (zlong)sess->fd);

	    if (verbose)
		printf("%s:%d is now on fd %d\n",
			desthost, destport, sess->fd);
	}
	
	zsfree(desthost);
    }

    return 0;
}
コード例 #6
0
ファイル: main.c プロジェクト: BackupTheBerlios/gift-ares
int main (int argc, char *argv[])
{
	ASLogger *logger;
	int stdin_handle;
	input_id stdinput;

#ifdef WIN32
	HANDLE hThread;
	int fds[2];
#endif

	/* winsock init */
	tcp_startup ();

	/* setup logging */
	logger = as_logger_create ();
	as_logger_add_output (logger, "stderr");
	as_logger_add_output (logger, "ares.log");

	AS_DBG ("Logging subsystem started");

	/* setup event system */
	as_event_init ();

	/* init lib */
	if (!as_init ())
	{
		printf ("FATA: as_init() failed\n");
		exit (1);
	}

#ifdef WIN32
	/* create console reading thread on windows */
	if (socketpair (0, 0, 0, fds) < 0)
	{
		printf ("FATAL: socketpair() failed\n");
		exit (1);
	}

	stdin_handle = fds[1];
	hThread = (HANDLE) _beginthreadex (NULL, 0, console_input_func,
	                                   (void *)fds[0], 0, NULL);

	if (hThread == (HANDLE) -1 || hThread == (HANDLE) 0)
	{
		printf ("FATAL: couldn't start input thread\n");
		exit (1);
	}
#else
	stdin_handle = 0;
#endif

	/* add callback for command handling */
	stdinput = input_add (stdin_handle, NULL, INPUT_READ, stdin_cb, 0);

#if 0
	/* print prompt */
	printf ("> ");
#endif

	/* run event loop */
	AS_DBG ("Entering event loop");
	as_event_loop ();
	AS_DBG ("Left event loop");

	input_remove (stdinput);

#if WIN32
	/* terminate thread if it is still running and close thread handle */
	TerminateThread (hThread, 0);
	CloseHandle (hThread);
#endif

	/* cleanup  lib */
	as_cleanup ();

	/* shutdown */
	as_event_shutdown ();
	as_logger_free (logger);

	/* winsock shutdown */
	tcp_cleanup ();

	return 0;
}