示例#1
0
void Sys_Net_Wait(struct SysNetData *netdata, struct SysSocket *socket, unsigned int timeout_us)
{
	fd_set rfds;
	ULONG sigmask;

	WaitIO((struct IORequest *)netdata->timerrequest);

	if (SetSignal(0, 0) & (1<<netdata->timerport->mp_SigBit))
		Wait(1<<netdata->timerport->mp_SigBit);

	FD_ZERO(&rfds);
	FD_SET(socket->s, &rfds);

	netdata->timerrequest->tr_node.io_Command = TR_ADDREQUEST;
	netdata->timerrequest->tr_time.tv_secs = timeout_us / 1000000;
	netdata->timerrequest->tr_time.tv_micro = timeout_us % 1000000;

	SendIO((struct IORequest *)netdata->timerrequest);

	sigmask = 1<<netdata->timerport->mp_SigBit;

	WaitSelect(socket->s + 1, &rfds, 0, 0, 0, &sigmask);

	AbortIO((struct IORequest *)netdata->timerrequest);
}
/**
 * Check whether we received/can send some data from/to the content server and
 * when that's the case handle it appropriately
 */
void ClientNetworkContentSocketHandler::SendReceive()
{
	if (this->sock == INVALID_SOCKET || this->isConnecting) return;

	if (this->lastActivity + IDLE_TIMEOUT < _realtime_tick) {
		this->Close();
		return;
	}

	fd_set read_fd, write_fd;
	struct timeval tv;

	FD_ZERO(&read_fd);
	FD_ZERO(&write_fd);

	FD_SET(this->sock, &read_fd);
	FD_SET(this->sock, &write_fd);

	tv.tv_sec = tv.tv_usec = 0; // don't block at all.
#if !defined(__MORPHOS__) && !defined(__AMIGA__)
	select(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv);
#else
	WaitSelect(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv, NULL);
#endif
	if (FD_ISSET(this->sock, &read_fd)) {
		this->Recv_Packets();
		this->lastActivity = _realtime_tick;
	}

	this->writable = !!FD_ISSET(this->sock, &write_fd);
	this->Send_Packets();
}
示例#3
0
static int iread( struct ftp_info *info, int skt, BOOL checkbreak )
{
//struct opusftp_globals *ogp = info->fi_og;
int                     retval = -1;
fd_set                  rd, ex;
ULONG                   flags;
struct timeval          timer = { 0, 0 };

// set network timeout for the select wait call
set_timeout(info,&timer);

FD_ZERO( &rd );
FD_ZERO( &ex );

FD_SET( skt,&rd );
FD_SET( skt,&ex );
flags = checkbreak ? SIGBREAKF_CTRL_D : 0;

//  WaitSelect returns number of ready file descriptors if
//  successful.  Zero (0) if a timeout occurred.
//  (-1) upon error.


if	(WaitSelect( skt+1, &rd, 0L, &ex, &timer, &flags ) >= 0)
	{
	D(bug("recv - "));

	// is data available from the socket?
	if	(FD_ISSET( skt, &rd ))
		{
		// number of bytes read if successful else -1.
		// can be 0 for EOF
		retval = recv( skt, info->fi_bufiobuf, BUFIOBUFSIZE, 0 );
		}

#ifdef DEBUG
	// has the socket been closed?
	if	(FD_ISSET( skt, &ex ))
		D(bug( "** iread() socket exception\n" ));
#endif

	// whatever check if user has hit CTRL_D
	if	(flags & SIGBREAKF_CTRL_D)
		{
		info->fi_abortsignals = 0;
		D(bug( "*** iread() CTRL-D SIGNAL ***\n" ));
		retval = -1;
		}
	}


return(retval);
}
示例#4
0
void Sys_Net_Wait(struct SysNetData *netdata, struct SysSocket *socket, unsigned int timeout_us)
{
	struct timeval tv;
	fd_set rfds;

	FD_ZERO(&rfds);
	FD_SET(socket->s, &rfds);

	tv.tv_sec = timeout_us / 1000000;
	tv.tv_usec = timeout_us % 1000000;

	WaitSelect(socket->s + 1, &rfds, 0, 0, &tv, 0);
}
示例#5
0
文件: tcp.cpp 项目: ComLock/OpenTTD
/**
 * Check whether this socket can send or receive something.
 * @return \c true when there is something to receive.
 * @note Sets #writable if more data can be sent.
 */
bool NetworkTCPSocketHandler::CanSendReceive()
{
	fd_set read_fd, write_fd;
	struct timeval tv;

	FD_ZERO(&read_fd);
	FD_ZERO(&write_fd);

	FD_SET(this->sock, &read_fd);
	FD_SET(this->sock, &write_fd);

	tv.tv_sec = tv.tv_usec = 0; // don't block at all.
#if !defined(__MORPHOS__) && !defined(__AMIGA__)
	if (select(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv) < 0) return false;
#else
	if (WaitSelect(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv, NULL) < 0) return false;
#endif

	this->writable = !!FD_ISSET(this->sock, &write_fd);
	return FD_ISSET(this->sock, &read_fd) != 0;
}
示例#6
0
/* static */ void NetworkHTTPSocketHandler::HTTPReceive()
{
	/* No connections, just bail out. */
	if (_http_connections.Length() == 0) return;

	fd_set read_fd;
	struct timeval tv;

	FD_ZERO(&read_fd);
	for (NetworkHTTPSocketHandler **iter = _http_connections.Begin(); iter < _http_connections.End(); iter++) {
		FD_SET((*iter)->sock, &read_fd);
	}

	tv.tv_sec = tv.tv_usec = 0; // don't block at all.
#if !defined(__MORPHOS__) && !defined(__AMIGA__)
	int n = select(FD_SETSIZE, &read_fd, NULL, NULL, &tv);
#else
	int n = WaitSelect(FD_SETSIZE, &read_fd, NULL, NULL, &tv, NULL);
#endif
	if (n == -1) return;

	for (NetworkHTTPSocketHandler **iter = _http_connections.Begin(); iter < _http_connections.End(); /* nothing */) {
		NetworkHTTPSocketHandler *cur = *iter;

		if (FD_ISSET(cur->sock, &read_fd)) {
			int ret = cur->Receive();
			/* First send the failure. */
			if (ret < 0) cur->callback->OnFailure();
			if (ret <= 0) {
				/* Then... the connection can be closed */
				cur->CloseConnection();
				_http_connections.Erase(iter);
				delete cur;
				continue;
			}
		}
		iter++;
	}
}
示例#7
0
int aros_poll(struct pollfd *fds, unsigned int nfds, int timo)
{
  struct timeval timeout, *toptr;
  fd_set ifds, ofds, efds, *ip, *op;
  unsigned int i, maxfd = 0;
  int  rc;

  // Set up the file-descriptor sets in ifds, ofds and efds. 
  FD_ZERO(&ifds);
  FD_ZERO(&ofds);
  FD_ZERO(&efds);
  for (i = 0, op = ip = 0; i < nfds; ++i) 
  {
    fds[i].revents = 0;
    if(fds[i].events & (POLLIN|POLLPRI)) 
    {
      ip = &ifds;
      FD_SET(fds[i].fd, ip);
    }
    if(fds[i].events & POLLOUT) 
    {
      op = &ofds;
      FD_SET(fds[i].fd, op);
    }
    FD_SET(fds[i].fd, &efds);
    if (fds[i].fd > maxfd) {
      maxfd = fds[i].fd;
    }
  } 

  // Set up the timeval structure for the timeout parameter
  if(timo < 0) 
  {
    toptr = 0;
  } 
  else 
  {
    toptr = &timeout;
    timeout.tv_sec = timo / 1000;
    timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000;
  }

  rc = WaitSelect(maxfd + 1, ip, op, &efds, toptr, NULL);

  if(rc <= 0)
    return rc;

  if(rc > 0) 
  {
    for (i = 0; i < nfds; ++i) 
    {
      int fd = fds[i].fd;
      if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds))
        fds[i].revents |= POLLIN;
      if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds))
        fds[i].revents |= POLLOUT;
      if(FD_ISSET(fd, &efds)) // Some error was detected ... should be some way to know.
        fds[i].revents |= POLLHUP;
    }
  }
  return rc;
}
示例#8
0
//
//	Get a remote file, calling the update function after each block arrives
//	Returns the total bytes received.  
//	fi_errno MUST be checked for errors
//	Returns -2 for AmigaDos errors - Use IoErr() to report/handle them
//	Returns -3 for FTP server errors - Use the fi_reply and fi_iobuf fields to report/handle them
//	Returns -1 for rare unlikely errors - Could cause DisplayBeep() etc...
//	now uses IOBUFSIZE 
//
//	Update callback must specify 0xffffffff for total and length if REST fails
//	Update callback must specify 0xffffffff for unknown total
//	Update callback must specify 0 for length of final call
//
unsigned int get( struct ftp_info *info, int (*updatefn)(void *,unsigned int,unsigned int), void *updateinfo, char *remote_path, char *local_path, BOOL restart )
{
// Needed because socket library base is in our task's tc_userdata field
//struct opusftp_globals *ogp = info->fi_og;
unsigned int            total = 0xffffffff;	// Length of file
unsigned int            bytes = 0;		// Bytes received so far
APTR                    f;			// Output file
int                     ds;			// Data socket
int                     b;			// Byte count
int                     reply;			// FTP reply
fd_set                  rd, ex; 
ULONG                   flags;
struct timeval          timer = {0};
int                     display_bytes;
int                     done;

D(bug( "get() '%s' -> '%s'\n", remote_path, local_path ));

// Valid?
if	(!info)
	return 0;

// No abort/error yet
info->fi_aborted = 0;
info->fi_errno = 0;
info->fi_ioerr = 0;
*info->fi_serverr = 0;

// More validity
if	(!remote_path || !local_path)
	{
	info->fi_errno |= FTPERR_XFER_RARERR;
	return 0;
	}

// init counters etc
display_bytes = done = 0;

// open output file for writing
if	((f = OpenBuf( (char *)local_path, restart ? MODE_OLDFILE : MODE_NEWFILE, WBUFSIZE )))
	{
	// Resuming?  So find out where to resume from
	if	(restart)
		{
		SeekBuf( f, 0, OFFSET_END );
		bytes = SeekBuf( f, 0, OFFSET_CURRENT );
		}

	// get connected  - bytes is a market flag 0/x for RETR/REST
	if	((ds = dataconna( info, bytes, "RETR %s", remote_path )) < 0)
		{
		// Source (server error)?
		if	(ds == -2 || ds == -3)
			{
			info->fi_errno |= FTPERR_XFER_SRCERR;
			stccpy( info->fi_serverr, info->fi_iobuf, IOBUFSIZE + 1 );
			}
		else
			info->fi_errno |= FTPERR_XFER_RARERR;
		}
	else
		{
		char *p;

		// Reset bytes if REST failed
		if	(bytes && (info->fi_flags & FTP_NO_REST))
			{
			if	(updatefn)
				(*updatefn)( updateinfo, 0xffffffff, 0xffffffff );

			SeekBuf( f, 0, OFFSET_BEGINNING );
			bytes = 0;
			}

		// First update tells callback where we're starting from
		if	(updatefn)
			(*updatefn)( updateinfo, total, bytes );

		// Does the RETR reply contain the file length?
		if ((p = strstr( info->fi_iobuf, " bytes)" )))
			if	(isdigit(*--p))
				{
				while	(isdigit(*p--)) ;
				total = atoi(p+2);
				}

		// do the transfer

		FD_ZERO( &rd );
		FD_ZERO( &ex );

		// set network timeout for the select wait call
		set_timeout(info,&timer);

		// loop fetch tcp data and save it
		while	(!done)
			{
			// Note: these masks must be set before every call and
			// are all cleared by select wait. Examine the masks
			// afterwards to see what was set

			FD_SET( ds, &rd );
			FD_SET( ds, &ex );
			flags = SIGBREAKF_CTRL_D; 

			if	(WaitSelect( ds + 1 , &rd, NULL, &ex, &timer, &flags ) >= 0)
				{
				// Is there some data ready for us?
				if	(FD_ISSET( ds, &rd ))
					{
					// then get it and store it
					if	((b = recv( ds, info->fi_iobuf, IOBUFSIZE, 0 )))
						{
						// save data
						if	(WriteBuf( f, info->fi_iobuf, b ) == b)
							{
							bytes += b;
	
							// progress bar uprate
							display_bytes += b;

							if	(display_bytes >= UPDATE_BYTE_LIMIT)
								{
								if	(updatefn)
									(*updatefn)( updateinfo, total, display_bytes );

								display_bytes = 0;
								}
							}
						// Write Error
						else
							{
							info->fi_errno |= FTPERR_XFER_DSTERR;
							info->fi_ioerr = IoErr();
							info->fi_aborted = 1;
							ftp_abor( info );
							done = TRUE;
							}	
						}
					else
						done = TRUE;
					}

				// did we get a signal to abort?
				if	(!done && (flags & SIGBREAKF_CTRL_D))
					{
					D(bug( "*** get() CTRL-D SIGNAL ***\n" ));
					info->fi_abortsignals = 0;
					info->fi_aborted = 1;
					ftp_abor( info );	// NEEDED why not just close socket?
					done = TRUE;
					}

				// did we get an exception? Other end closed connection maybe
				if	(FD_ISSET( ds, &ex ))
					{
					D(bug("** get() socket exception\n"));

					// has been aborted from remote ?
					done = TRUE;
					}
				}
			else
				{
				// some socket error -ve a 0 == timeout
				D(bug( "** get() WaitSelect error\n" ));
				done = TRUE;
				}
			}

		// Final progress bar redraw at 100% (if it finished)
		if	(!info->fi_aborted && !info->fi_errno && updatefn)
			(*updatefn)( updateinfo, total, 0 );

		//D(bug( "--> close(%ld)\n", ds ));
		CloseSocket( ds );

#ifdef	DEBUG
//			if	(ui)
//			timeit( ui, bytes );
#endif

		// Get reply to socket closure  Can TIMEOUT
		reply = getreply( info );

		// If transfer was aborted, read the ABOR reply (426)
		// (This could get the reply to RETR (226) but it don't matter)
		if	(info->fi_aborted && reply != 421)
			reply = getreply( info );

		// RETR successful? - Don't set error if we forced it!
		// (This could get the reply to ABOR (225) but it don't matter)
		if	(reply / 100 != COMPLETE)
			if	(!info->fi_errno)
				{
				info->fi_errno |= FTPERR_XFER_SRCERR;
				stccpy( info->fi_serverr, info->fi_iobuf, IOBUFSIZE + 1 );
				}
		}

	CloseBuf( f );

	// Delete empty files if there was an error and we created it
	if	(info->fi_errno && bytes == 0 && !restart)
		DeleteFile( (char *)local_path );
	}
else
	{
	info->fi_errno |= FTPERR_XFER_DSTERR;
	info->fi_ioerr = IoErr();
	}

return bytes;
}
示例#9
0
unsigned int put( struct ftp_info *info, int (*updatefn)(void *,unsigned int,unsigned int), void *updateinfo, char *local_path, char *remote_path, unsigned int restart )
{
//struct opusftp_globals *ogp = info->fi_og;
unsigned int            bytes = 0;
APTR                    f;				// Output file
int                     ds;				// Data socket
int                     b;				// Byte count
fd_set                  wd, ex;
ULONG                   flags = SIGBREAKF_CTRL_D;
struct timeval          timer = {0};
BOOL                    done = FALSE;
int                     display_bytes = 0;

// Valid?
if	(!info)
	return 0;

// No abort/error yet
info->fi_aborted = 0;
info->fi_errno = 0;
info->fi_ioerr = 0;
*info->fi_serverr = 0;

// More validity
if	(!remote_path || !local_path)
	{
	info->fi_errno |= FTPERR_XFER_RARERR;
	return 0;
	}

if	((f = OpenBuf( (char *)local_path, MODE_OLDFILE, WBUFSIZE )))
	{
	// Can TIMEOUT
	if	((ds = dataconna( info, restart, "STOR %s", remote_path )) < 0)
		{
		// Destination (server) error?
		if	(ds == -2 || ds == -3)
			{
			info->fi_errno |= FTPERR_XFER_DSTERR;
			stccpy( info->fi_serverr, info->fi_iobuf, IOBUFSIZE + 1 );
			}
		else
			info->fi_errno |= FTPERR_XFER_RARERR;
		}
	else
		{
		// Resuming a transfer?
		if	(restart)
			{
			// Start at 0 if REST failed
			if	(info->fi_flags & FTP_NO_REST)
				{
				if	(updatefn)
					(*updatefn)( updateinfo, 0xffffffff, 0xffffffff );

				bytes = restart = 0;
				}

			// Otherwise seek to restart position
			else
				{
				SeekBuf( f, restart, OFFSET_BEGINNING );
				bytes = restart;
				}
			}

		// First update tells callback where we're starting from
		if	(updatefn)
			(*updatefn)( updateinfo, 0xffffffff, bytes );

		// Transfer

		FD_ZERO( &wd );
		FD_ZERO( &ex );

		// set network timeout for the select wait call
		set_timeout(info,&timer);

		while	(!done)
			{
			// Note: these masks must be set before every call and
			// are all cleared by select wait. Examine the masks
			// afterwards to see what was set

			FD_SET( ds, &wd );
			FD_SET( ds, &ex );
			flags = SIGBREAKF_CTRL_D; 

			if	(WaitSelect(ds+1, 0L, &wd, &ex, &timer, &flags ) >= 0)
				{
				if	(FD_ISSET( ds, &wd ))
					{
					if	((b = ReadBuf( f, info->fi_iobuf, IOBUFSIZE )) > 0)
						{
						send( ds, info->fi_iobuf, b, 0 );
						bytes += b;

						if	((display_bytes += b) >= UPDATE_BYTE_LIMIT || bytes < UPDATE_BYTE_LIMIT)
							{
							if	(updatefn)
								(*updatefn)( updateinfo, 0xffffffff, display_bytes );

							display_bytes = 0;
							}
						}
					else 
						{
						done = TRUE;

						if	(b < 0)
							{
							info->fi_errno |= FTPERR_XFER_SRCERR;
							info->fi_ioerr = IoErr();
							}
						}
					}

				if	(!done && (flags & SIGBREAKF_CTRL_D))
					{
					D(bug( "*** put() CTRL-D SIGNAL ***\n" ));
					info->fi_abortsignals = 0;
					info->fi_aborted = TRUE;
					done = TRUE;
					}

				if	(FD_ISSET( ds, &ex ))
					{
					D(bug( "** put() socket exception\n" ));
					info->fi_abortsignals = 0;
					done = TRUE;
					}
				}
			else
				{
				// some socket error -ve  a 0== timeout
				D(bug("** put() WaitSelect error\n"));
				done = TRUE;
				}
			}

		// Final progress bar redraw at 100% (if it finished)
		if	(!info->fi_aborted && !info->fi_errno && updatefn)
			(*updatefn)( updateinfo, 0xffffffff, 0 );

		// Close data socket
		//D(bug( "--> close(%ld)\n", ds ));
		CloseSocket( ds );

		// Get reply to socket closure -  Can TIMEOUT
		if	(getreply( info ) / 100 != COMPLETE)
			{
			info->fi_errno |= FTPERR_XFER_DSTERR;
			stccpy( info->fi_serverr, info->fi_iobuf, IOBUFSIZE + 1 );
			}
		}
	CloseBuf( f );
	}
else
	{
	info->fi_errno |= FTPERR_XFER_SRCERR;
	info->fi_ioerr = IoErr();
	}

return bytes;
}
示例#10
0
//
//	Single character get char function
//	Returns char for success
//	Returns -1 for error
//	Returns -2 for timeout
//	Returns -3 for control-D break
//
//	checkabort_time is set either to default or special time for
//	getput only on dest STOR command 
//
static int sgetc( struct ftp_info *info, int skt, int checkabort_time )
{
//struct opusftp_globals *ogp = info->fi_og;
int retval = -1;
unsigned char c;
fd_set rd, ex;
ULONG flags;
int n, nds;
struct timeval t = {0};

// Valid?
if	(!info || skt < 0)
	{
	D(bug( "** sgetc invalid!\n" ));
	return retval;
	}

// set network timeout for the select wait call

if	(checkabort_time == 2)
	t.tv_secs = 5; // special return soon to update progress bar
else
	set_timeout(info,&t);

t.tv_micro = 0;

FD_ZERO( &rd );
FD_ZERO( &ex );

FD_SET( skt, &rd );
FD_SET( skt, &ex );

flags = checkabort_time ? SIGBREAKF_CTRL_D : 0;
	
//	WaitSelect returns number of ready file descriptors if
//	successful.  Zero (0) if a timeout occurred.
//	(-1) upon error.

if	((nds = WaitSelect( skt+1, &rd, 0L, &ex, &t, &flags )) >= 0)
	{
	if	(nds == 0) // timeout or abort
		{
		D(bug( "** sgetc() WaitSelect timeout\n" ));
		retval = -2;
		}		

	// abort button hit?
	if	(flags & SIGBREAKF_CTRL_D)
		{
		info->fi_abortsignals = 0;
		D(bug( "*** sgetc() CTRL-D SIGNAL ***\n" ));
		retval = -3;
		}

	// is data ready?
	if	(FD_ISSET( skt, &rd ))
		if	((n = recv( skt, &c, 1, 0 )) == 1)
			retval = c;

#ifdef DEBUG
	// has the socket been closed?
	if	(FD_ISSET( skt, &ex ))
		D(bug( "** sgetc() socket exception\n" ));
#endif

	}

return retval;
}
示例#11
0
int poll( struct pollfd *pfds, unsigned int nfds, int timeout )
{
	unsigned int i;
	int maxfd = -1, ret;
	fd_set rset,wset,xset;
	struct timeval timeout_tv, *tvp = NULL;

	if (timeout >= 0)
	{
		timeout_tv.tv_sec = (timeout / 1000);
		timeout_tv.tv_usec = (timeout % 1000) * 1000;
		tvp = &timeout_tv;
	}

	if(pfds==NULL||nfds<1)
	{
	  if(pfds==NULL&&nfds<1&&timeout>=0)
	  {
	    ret = WaitSelect(0,NULL,NULL,NULL,tvp,NULL);
	    __chkabort();
	    return(ret);
	  }

	  errno=EINVAL;
	  return -1;
	}

	FD_ZERO (&rset);
	FD_ZERO (&wset);
	FD_ZERO (&xset);

	for (i = 0; i < nfds; i++)
	{
		pfds[i].revents = 0;

		if (pfds[i].events == 0)
			continue;

		if (pfds[i].fd > maxfd)
			maxfd = pfds[i].fd;

		if (pfds[i].events & POLLIN)
			FD_SET (pfds[i].fd, &rset);

		if (pfds[i].events & POLLOUT)
			FD_SET (pfds[i].fd, &wset);

		if (pfds[i].events & POLLERR)
			FD_SET (pfds[i].fd, &xset);
	}

	ret = WaitSelect (maxfd + 1, &rset, &wset, &xset, tvp, NULL);

	__chkabort ( ) ;

	if(ret == -1)
		return ret;

	for (i = 0; i < nfds; i++)
	{
		if (pfds[i].events == 0)
			continue;

		if (FD_ISSET (pfds[i].fd, &rset))
			pfds[i].revents |= POLLIN;

		if (FD_ISSET (pfds[i].fd, &wset))
			pfds[i].revents |= POLLOUT;

		if (FD_ISSET (pfds[i].fd, &xset))
			pfds[i].revents |= POLLERR;
	}

	return ret;
}