BeOS Page logo. Open BeOS ProjectBoost Signal - BeOS software archive. BeBits - BeOS software archive. Free! BeOS 5.



Porting tips.


Sockets.

One of the most critical functionality problems, I found when porting to Be, is it's poor support of sockets, in so far as, you can open a socket as easily as on a UNIX system but unlike UNIX systems an open Be socket cannot be read from like a file pointer, you can only use send/recv (stream) sendto/recvfrom (datagram). Consider the following code exerts where sockt_rd is an open socket:

if((nntp_rd_fp = (FILE *) fdopen (sockt_rd, "r")) == NULL) return(-1)

while (fgets (string, size, nntp_rd_fp) == NULL
{
if (errno != EINTR) return(-1);
  }

The above code will not work under Be, Be sockets cannot be treated as file descriptors hence the first line does not work, and you have no open file pointer open to read from, game over. So now lets consider a simplified Be alternated:

blocking = 1;
setsockopt(beos_rw_socket, SOL_SOCKET, SO_NONBLOCK, &blocking, sizeof(int));

while((result == B_OK || result == EWOULDBLOCK) && timed < time_out)
{
num_bytes = recv(sockt_rd, cp, buf_size, 0);
if (num_bytes > 0){
   cp += num_bytes;
   bytes_rcvd += num_bytes;
   if( (buf_size -= num_bytes) == 0 ) break;   
   if(strchr(string,'\n')!=NULL) break;
   }
   time(&time_later);
  if(time_later > time_then) timed=time_later-time_then;
   else timed=time_then-time_later;
  result = errno;
}

blocking = 0;
setsockopt(beos_rw_socket, SOL_SOCKET, SO_NONBLOCK, &blocking, sizeof(int));

The main points to consider in the above code are, the first two lines where the socket is set to none blocking, normally Be sockets are set to blocking, in other words if there is no data for the recv() command to read it will wait until there is some, if none ever comes the you application is hung on that line. After that, the Data is read and as soon as we have at least one '\n' the loop breaks, note unlike gets() the recv() command could and probably has read past the first '\n' this data will recv() command could and probably has read past the first '\n' this data will be there for the next read so extra code is necessary to store it,(as in my tin port). After the data is read the last two lines reset the socket to blocking. for send().

Opening a socket.

The following code will open a network socket under BeOS.

int s = -1, port = 119;
long host_addr;
struct sockaddr_in sin;
struct hostent *gethostbyname (), *hp;
memset((char *) &sin,'\0', sizeof (sin));
/* Create the socket. */
if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) return (-1);
/* Set the address format for the imminent bind. AF_INET ("Address Format: InterNET") /*
sin.sin_family = AF_INET;
/*In this example port is 119 NTTP,(News). */
sin.sin_port = htons (port);
/* First checks is the mahine is already a number or a numeric IP add string */
if (!isdigit(*machine) || (unsigned long)(sin.sin_addr.s_addr = inet_addr (machine)) == -1)
 {/* No then it's a name and get host info incluning all IP address */
  if((hp = gethostbyname (machine)) == NULL)
   {
   /* Error, close socket and return /*
   closesocket(s);
   return (-1);
    }

 memcpy((char *) &sin.sin_addr, hp->h_addr, hp->h_length);
 }
/* Connect to Host */
if (connect (s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
  {
  /* Failed to connect close socket and return some kind of error indication. */
  (void) close (s);
  return (-1);
   }
/* Return opened socket */
return (s);