COHERENT manpages

This page displays the COHERENT manpage for libsocket [Library of communications routines].

List of available manpages
Index


libsocket -- Library

Library of communications routines

libsocket  is  a library  of  routines that  emulate  the Berkeley  sockets
library.  It includes the following functions:

accept().............. Accept a connection on a socket
bind()................ Bind a name to a socket
bitcount()............ Count bits in a bit-mask
connect()............. Connect to a socket
endhostent().......... Close file /etc/hosts
endnetent()........... Close network file
endprotoent()......... Close protocols file
endservent().......... Close protocols file
ffs()................. Translate a bit mask into an integer value
getdtablesize()....... Get the number of files a process can open
gethostbyaddr()....... Retrieve host information by address
gethostbyname()....... Retrieve host information by name
gethostname()......... Get the name of the local host
getnetbyaddr()........ Get a network entry by address
getnetbyname()........ Get a network entry by address
getnetent()........... Fetch a network entry
getpeername()......... Get name of connected peer
getprotobyname()...... Get protocol entry by protocol name
getprotobynumb()...... Get protocol entry by protocol number
getprotoent()......... Get protocol entry
getservbyname()....... Get a service entry by name
getservbyport()....... Get a service entry by port number
getservent().......... Get a service entry
getsockname()......... Get the name of a socket
getsockopt().......... Read a socket option
gettimeofday()........ Berkeley time function
inet_addr()........... Transform an IP address from text to binary
inet_network()........ Transform an IP address from text to an integer
listen().............. Listen for a connection on a socket
random().............. Return a random number
recv()................ Receive a message from a connected socket
recvfrom()............ Receive a message from a socket
select().............. Check whether sockets are ready for activity
send()................ Send a message to a connected socket
sendto().............. Send a message to a socket
sethostent().......... Open and rewind file /etc/hosts
setnetent()........... Open and rewind file /etc/networks
sethostent().......... Open and rewind file /etc/hosts
setprotoent()......... Open the protocols file
setservent().......... Open the services file
setsockopt().......... Set a socket option
shutdown()............ Replace function to shut down system
SOCKADDRLEN()......... Return length of an address
socket().............. Create a socket
socketpair().......... Create a pair of sockets
srandom()............. Seed the random-number generator
strcasecmp().......... Case-insensitive string comparison
strcasencmp()......... Case-insensitive string comparison
usleep().............. Sleep briefly

Function socket() creates a socket;  the caller dictates the type of socket
to  be  created,  and  the  communications  protocol that  it  comprehends.
socket() returns a descriptor,  which resembles a file descriptor and which
can  be  passed  to  the  system  calls  read()  and  write()  to  exchange
information with whatever plugs itself into that socket.  (For details, see
the Notes section at the end of this article.)

Function bind() binds the newly created socket to a file that you name.  To
await a connection with another process, invoke the function listen(); this
alerts the system to the fact  that you (via your socket) await messages of
a given  type.  Function  select() checks whether  one or more  sockets are
ready to be written to, or  hold data that need to be read.  When a message
becomes available,  invoke function  accept() to accept  communication with
the  process  that  wishes to  connect  to  your  socket.  These  functions
generally are used by ``server'' sockets.

Function connect() directly establishes connection with a server socket via
its name (that is, via the  file to which it is bound).  Once connection is
established,  information can  be exchanged via  the COHERENT  system calls
read() and write().

System Files

The socket  library manipulates the following files.   Each is described in
its own Lexicon entry:

hosts................. Names and addresses of hosts on the local network
hosts.equiv........... Name equivalent hosts
hosts.lpd............. Local system name and domain
inetd.conf............ Configure the Internet daemons
networks.............. Name remote networks
protocols............. Name supported protocols
services.............. List supported TCP/IP services

Example

For following gives a pair of programs that demonstrate sockets.  They were
written by John Dhuse (jdhuse@sedona.intel.com).

The example  consists of two programs, server.c  and client.c. Compile each
with the switch -lsocket. To see how they work, run each in its own virtual
console or xterm window.  Do not run them in the background; otherwise, you
will not  be able  to work  with them interactively.   Be sure to  start up
server first, as it creates the socket into which client plugs itself.

Each process gives  you a prompt; you can type  commands into each.  server
recognizes the following commands:

?  Print the command menu

c  Call select()  to check the  socket.  client displays the  status of the
   socket.

s  Send a string  to server. client prompts for the  string, reads up to 20
   characters, and writes it to the socket.

r  Read from the  socket.  client prompts for the number  of bytes to read,
   and clips any response to a maximum of 20.

q  Close the socket and terminate the server process.

server recognizes the following commands:

?  Print the command menu.

c  Call select() to check the socket.

r  Read from the socket.  server does not prompt for the number of bytes to
   read,  but tries  to read  the entire  contents of the  socket, up  to a
   maximum of 20 bytes.

e  Echo the  read message back to  the client.  The server  cannot send its
   own message the client, just echo what it received.

q  Close the socket, terminate the server, and unlink() the socket file.

The following gives the source for server.c:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/un.h>

main()
{
    int sd, nsd, err,i,j,rdfds[2],wrtfds[2];
    int efds[2],done,r;
    int arg=1;
    struct sockaddr_un server;
    char *sock_name = "u0";
    char buf[20];
    char command,line[80];
    struct timeval timeout;

    /* clear our address */
    bzero((char *)&server, sizeof(server));

    /* create socket */
    if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) <= 0) {
        err = errno;
        fprintf(stderr, "server: can't create socket\n");
        fprintf(stderr, "server: errno = %d\n", err);
        exit(EXIT_FAILURE);
    }

    server.sun_family = AF_UNIX;
    bcopy(sock_name,server.sun_path,strlen(sock_name));

      /* bind the socket */
    if ((bind(sd, (struct sockaddr *)&server, sizeof(server))) != 0) {
        err = errno;
        fprintf(stderr, "server: can't bind socket\n");
        fprintf(stderr, "server: errno = %d\n", err);
        close(sd);
        exit(EXIT_FAILURE);
    }

      /* listen on the socket */
    if ((listen(sd, 1)) != 0) {
        err = errno;
        fprintf(stderr, "server: can't listen on socket\n");
        fprintf(stderr, "server: errno = %d\n", err);
        close(sd);
        exit(EXIT_FAILURE);
    }

    /* accept connections on the socket */
    if ((nsd = accept(sd, (struct sockaddr*)0, (int *)0)) == -1) {
        err = errno;
        fprintf(stderr, "server: can't accept connection\n");
        fprintf(stderr, "server: errno = %d\n", err);
        close(sd);
        exit(EXIT_FAILURE);
    }

    printf("accepted client connection fd %d\n",nsd);
        /* set to non-blocking io */
    ioctl(nsd,FIOSNBIO,&arg);

    /* echo every message back to client, exit on terminate string */
    printf("entering command loop\n");
    command = 'a';
    while (command != 'q') {
        printf("server> ");
        scanf("%s",line);
        sscanf(line,"%c", &command);
        switch (command) {

        case 'c' :
            /* set up for select */
            rdfds[0] = 1 << nsd; rdfds[1] = 0;
            wrtfds[0] = 1 << nsd; wrtfds[1] = 0;
            efds[0] = 1 << nsd; efds[1] = 0;
            timeout.tv_sec = 0; timeout.tv_usec = 0;
            r = select(nsd+1,rdfds,wrtfds,efds,(struct timeval *)NULL);
            err = errno;

            if (r < 0)
                    printf("select() returned errno %d\n",err);
            else {
                    if (rdfds[0] & (1 << nsd))
                    printf("socket has data to be read\n");
                if (wrtfds[0] & (1 << nsd))
                        printf("data can be written to socket\n");
                if (efds[0] & (1 << nsd))
                    printf("select reports exception on socket\n");
            }
            break;

        case 'r' :
                    bzero(&buf[0], sizeof(buf));
            j = read(nsd,buf,sizeof(buf));
            err = errno;
            if (j < 0)
                printf("read() returned errno %d\n",err);
            else
                printf("got %d bytes, msg is >%s<\n",j,buf);
            break;

        case 'e' :
            printf("echoing >%s< (%d bytes) to client\n",buf,j);
            write(nsd,&buf[0],j);
            break;

        case 'q' :
            close(nsd);
            close(sd);
            unlink(sock_name);
            break;

        case '?' :
            printf("commands:\n");
            printf("   c - check the socket\n");
            printf("   ? - this help message\n");
            printf("   r - read from socket\n");
            printf("   e - echo received message to client\n");
            printf("   q - close socket and quit\n");
            break;

            default :
            printf("\n");
            break;
        }
    }
}

The following gives the source for client.c:

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/un.h>

main()
{
    int sd, err, i, j, flags;
    int arg=1;
    struct sockaddr_un client;
    char *address="u0";
    char buf[20];
    char command,line[80];
    int rdfds[2],wrtfds[2];
    struct timeval timeout;

    /* clear our address */
    memset((char *)&client,0, sizeof(client));

    /* create socket */
    if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) <= 0) {
        err = errno;
        fprintf(stderr, "client: can't create socket\n");
        fprintf(stderr, "client: errno = %d\n", err);
        exit(EXIT_FAILURE);
    }

    /* set to blocking so connect hangs, waiting for connect */
    arg = 0;
           i = ioctl(sd,FIOSNBIO,&arg);

    client.sun_family = AF_UNIX;
    memcpy(client.sun_path,address,2);

    /* connect to the socket */
    if (connect(sd, (struct sockaddr *)&client, sizeof(client))) {
        err = errno;
        fprintf(stderr, "client: can't connect socket\n");
        fprintf(stderr, "client: errno = %d\n", err);
        close(sd);
        exit(EXIT_FAILURE);
    }
    printf("connected socket fd = %d\n",sd);

    arg = 1;
           i = ioctl(sd,FIOSNBIO,&arg);

    printf("entering command loop\n");
    command = 'a';

    while (command != 'q') {
        printf("client> ");
        scanf("%s",line);
        sscanf(line,"%c",&command);

        switch (command) {
        case 's' :
            printf("message to send: ");
            scanf("%s",buf);
            i = write(sd,buf,strlen(buf));
            err = errno;
            if (i < 0)
                printf("write() returned errno %d\n", err);
            else printf("sent >%s< (%d bytes) to server\n",
                       buf,strlen(buf));
            break;

        case '?' :
            printf("commands:\n");
            printf("   s - send a message\n");
            printf("   ? - this help messge\n");
            printf("   c - check the socket\n");
            printf("   r - read from socket\n");
            printf("   b - set to blocking I/O\n");
            printf("   n - set to non-blocking I/O\n");
            printf("   q - close socket and quit\n");
            break;

        case 'b' :
                arg = 0;
            ioctl(sd,FIOSNBIO,&arg);
            printf("I/O is blocking\n");
            break;

        case 'n' :
                arg = 1;
            ioctl(sd,FIOSNBIO,&arg);
            printf("I/O is non-blocking\n");
            break;

        case 'c' :
                /* setup query fields */
                rdfds[0] = 1 << sd; rdfds[1] = 0;
            wrtfds[0] = 1 << sd; wrtfds[1] = 0;
            timeout.tv_sec = 0; timeout.tv_usec = 0;
            i = select(sd+1,rdfds,wrtfds,(int *)NULL,
                   &timeout);
            err = errno;
            if (i < 0)
                  printf("select() returned error %d\n",err);
            else {
                if (rdfds[0] & (1 << sd))
                    printf("socket has data to be read\n");
                if (wrtfds[0] & (1 << sd))
                    printf("data can be written to socket\n");
                }
            break;

        case 'r' :
            printf("number of bytes to read > ");
            scanf("%d",&i);
            if (i > sizeof(buf)) i = sizeof(buf);
                memset(&buf[0],0, sizeof(buf));
            j = read(sd,buf,i);
            err = errno;
            if (j < 0)
                printf("read() returned errno %d\n",err);
            else
                printf("got %d bytes, msg is >%s<\n",j,buf);
            break;

        case 'q' :
            close(sd);
            break;

        default:
            printf("\n");
            break;
        }
    }
    exit(EXIT_SUCCESS);
}

See Also

device driver,
hosts,
hosts.equiv,
hosts.lpd,
inetd.conf,
libraries,
msgget(),
named pipes,
networks,
pipe(),
protocols,
semget(),
services,
shmget(),
STREAMS

Notes

The version of sockets included with COHERENT is not built into the kernel.
Rather,  it uses  a library  of routines  that use  named pipes  to emulate
sockets.   You should  not invoke  the  system calls  read() or  write() to
manipulate directly any descriptor  returned by a call to socket(), because
this descriptor defines only one of  a set of named pipes required to mimic
a  true  kernel-level socket.   Header  file <sys/socket.h>  replaces
these with the macros that perform  the task correctly.  This means that in
every C file where you perform  a read(), write(), ioctl(), or close() on a
socket, you must include <sys/socket.h>.

This   library   was    adapted   from   Berkeley   sources   by   P.Garbha
(pgd@compuram.bbt.se),  and  was   extensively  revised  by  Mark  Williams
Company.

This product  includes software developed by  the University of California,
Berkeley, and its contributors.