Net8(TM) Administrator's Guide
Release 8.0.3

A51576_01

Library

Product

Contents

Index

Prev Next

9
Net8 Enhancements for Programmers

Net8 includes an application program interface (API) called Net8 OPEN allowing programmers to develop both database and non-database applications. In addition, Net8 contains several new benefits for programmers including UNIX client programming, signal handler and alarm programming, Bequeath Adapter and child process termination.

This chapter contains the following sections:

9.1 Net8 OPEN

Net8 includes an application program interface (API) called Net8 OPEN, which enables programmers to:

Net8 OPEN provides applications a single common interface to all industry standard network protocols.

The relationship of Net8 OPEN to other products is shown in Figure 9-1.

Figure 9-1 Net8 OPEN

Using Net8 OPEN, you can solve a number of problems, such as:

9.1.1 Net8 OPEN API Function Calls

In contrast to a remote procedure call interface, Net8 OPEN provides a byte stream-oriented API that can be used to develop basic applications which send and receive data. Applications developed with Net8 OPEN must ensure that values sent across the network are interpreted correctly at the receiving end.

The Net8 OPEN API consists of five function calls:

Table 9-1 Net8 OPEN API Function Call Summary
TNSOPEN    

Description:  

Initializes the Net8 OPEN API per-connection handle. This function must be the first Net8 OPEN call that a user makes. Note that tnsopen() does not establish a connection; connections are established by the send and receive calls as needed.

If you are writing a client program (which will initiate the connection), "name" contains a service name in the same format as those in the Net8 configuration file TNSNAMES.ORA.

If you are writing a server program, "name" should be NULL. Your server program will pick up the connection automatically when you make the first tnsrecv() call to receive data (see the section on tnsrecv).  

Synopsis:  

int tnsopen(handlep, name)
void **handlep;
const char *name;
 

Parameters:  

handlep (IN/OUT)

- Address to receive Net8 connection handle

name (IN)

- Service name  

Prerequisites:  

The handlep parameter must not be NULL  

Returns:  

Upon successful completion a zero value is returned. Otherwise, a positive Net8 API error is returned.  

TNSCLOSE    

Description:  

Shuts down the connection. The user must call this function to close the connection and release the handle properly.  

Synopsis:  

int tnsclose(handlep)
void **handlep;
 

Parameters:  

handlep(IN/OUT)

- Address of a pointer to a Net8 connection handle  

Prerequisites:  

The handlep parameter must not be NULL.  

Returns:  

Upon successful completion a zero value is returned, and *handlep is set to NULL. Otherwise, a positive Net8 API error number is returned.  

TNSSEND    

Description:  

Sends data to the Net8 connection handle.

In the first call to tnssend() on the client side, the connection is established before any data is sent to the handle. The client application must first call tnssend() after tnsopen() to establish a connection to the server. It is an error if the client application calls tnsrecv() first, or if the server program calls tnssend() first.

Note that this also means that the tnssend() call may return errors related to connection establishment - so the first indication you get that, for instance, you have given the incorrect TNS address, is that an error occurs on the first tnssend() call, rather than on the tnsopen() call as you may first expect.  

Synopsis:  

int tnssend(handle, data, length)
void *handle;
const void *data;
size_t *length;
 

Parameters:  

handle(IN/OUT) - pointer to Net8 connection 
handle returned by tnsopen()
data(IN) - pointer to data to be sent
length(IN/OUT) - pointer to the length of data to 
be sent in bytes and the actual number of bytes 
written on return.
 

Prerequisites:  

The parameters must not be NULL.  

Returns:  

Upon successful completion a zero value is returned, and the actual number of bytes written is returned as the value pointed to by the length parameter. Otherwise, a positive Net8 API error number is returned.  

TNSRECV    

Description:  

Receives data from the Net8 connection handle.

In the first call to tnsrecv() on the server side, the connection is established before data is received from the handle. The server must first call tnsrecv() after tnsopen() to accept the connection from the client.

Incoming connections are accepted by the Net8 Listener (tnslsnr), which automatically spawns off a copy of your server program when needed, and hands it the new connection. You must configure the network listener with the location of your server program for this to occur - see the section on configuration below.  

Synopsis:  

int tnsrecv(handle, data, length)
void *handle;
void *data;
size_t *length;
 

Parameters:  

handle(IN/OUT) - pointer to Net8 connection 
handle returned by tnsopen()
data(IN/OUT) - pointer to buffer to receive data 
length(IN/OUT) - pointer to the length of buffer 
to receive data and actual number of bytes 
received on return
 

Prerequisites:  

All parameters must not be NULL.  

Returns:  

Upon successful completion a zero value is returned, and the actual number of bytes received is returned as the value pointed to by the length parameter. Otherwise, a positive Net8 API error number is returned.  

TNSCONTROL    

Description:  

Sets the connection to blocking or nonblocking mode.  

Synopsis:  

int tnscontrol(handle, cmd)
void *handle;
int *cmd;
 

Parameters:  

handle(IN) - pointer to Net8 connection handle 
returned by tnsopen()
cmd(IN) - option to apply to the connection. 
Currently supported values are:
TNSAPINONBLOCKING - set connection into 
nonblocking mode
TNSAPIBLOCKING - set connection into 
blocking mode
 

Prerequisites:  

The handle must not be NULL, and cmd must be one of the supported commands.  

Returns:  

A zero value is returned if the option is successfully set.  

9.1.2 Finding the Net8 OPEN Applications Program Interface

The applications program interface is provided as part of the standard Net8 installation. To use it, you need the following:

9.1.3 Building Your Own Application

Modules which make reference to Net8 OPEN functions should include TNSAPI.H, as follows:

#include <tnsapi.h>

Your makefile (or other location for your build command) should ensure that the include path is set properly so that it can find TNSAPI.H. Refer to the sample makefiles provided in your installation.

9.1.4 Configuring the System to Use Your Net8 OPEN Application

To configure Net8 to recognize your Net8 OPEN application, proceed as follows:

  1. Add the location of your server program to your listener configuration file (LISTENER.ORA), so that the network listener knows to start your server if a connection request is received.

    To do this, choose a system identifier (SID) name for your service similar to that of an Oracle database. Do not pick the same SID as your database.

    For example, if you are configuring a "chat" program, you could call the SID "chatsid". Place the program into the same place as the Oracle server executable, which is normally $ORACLE_HOME/bin, which we will assume here is in /usr/oracle/bin.

    You would place the following entry in a listener configuration file as follows:

    SID_LIST_LISTENER = 
    
    
          (SID_LIST =
    
    (SID_DESC =
    (SID_NAME = chatsid)/*your SID name*/(ORACLE_HOME = /usr/oracle/
    bin)/*$ORACLE_HOME bin directory*/(PROGRAM = chatsvr)/*the name of 
    your server program*/)
    

    You need to restart the listener, so it will recognize the new service.

  2. Add the address of your application server to your local names configuration file (TNSNAMES.ORA).

    For example, if your listener is listening on the following address:

    (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=unixhost)(PORT=1521)))
    

    And you want people to refer to the service you created above as "chat".

    You would add the following parameter to your TNSNAMES.ORA file:

    chat=
    (DESCRIPTION=
    
    (ADDRESS=(PROTOCOL=tcp)(HOST=unixhost)(PORT=1521)
    )
    (CONNECT_DATA=(SID=chatsid)
    )
    
    )

    Note that the address contains the SID you configured in the LISTENER.ORA file above. Also note that the second line started with at least one space character, which indicates that it is a continuation line.

    If you have domains in your network, you need to name your service accordingly. For instance, use chat.acme.com if the domain is acme.com. Again, use the existing TNSNAMES.ORA file as a template - if all the other service names end in a domain, you need to name your service similarly.

  3. Place the executable for your service in the same directory as your Oracle Server executable. On UNIX platforms, place the executable in the $ORACLE_HOME/bin directory indicated in your LISTENER.ORA file. In this example, you would place the program "chatsvr" in the location /usr/oracle/bin/chatsvr.

    If needed on your operating system, you also must ensure that you have permission to execute your program.

9.1.5 Sample Programs

Two sample applications are provided with Net8 OPEN:

9.1.6 Net8 OPEN API Errors

This section lists the error numbers which can be returned if one of the above function calls fails. Note that in some cases, connection-related errors may come back from a send or receive call, if the connection has not yet been established at that time.

20002 - SDFAIL_TNSAPIE - The underlying "send" command failed in tnssend().
20003 - RECVFAIL_TNSAPIE - The underlying "receive" command failed in tnsrecv().
20004 - INVSVROP_TNSAPIE - Operation is invalid as the server.
20005 - INVCLIOP_TNSAPIE - Operation is invalid as the client.
20006 - HDLUNINI_TNSAPIE - The connection should be initialized by calling 
tnsopen().
20007 - INHFAIL_TNSAPIE - Server failed in inheriting the connection from the 
listener.
20008 - ACPTFAIL_TNSAPIE - Server failed in accepting the connection request 
from the client.
20009 - NULHDL_TNSAPIE - A null handle was passed into the call, which is not 
allowed.
20010 - INVOP_TNSAPIE - An invalid operation called was passed into the call.
20011 - MALFAIL_TNSAPIE - A malloc failed in TNS API call.
20012 - NLINIFAIL_TNSAPIE - Failed in NL initialization.
20013 - NMTOOLONG_TNSAPIE - Service name is too long.
20014 - CONFAIL_TNSAPIE - Client connect request failed.
20015 - LSNFAIL_TNSAPIE - Server failed to listen for connect request.
20016 - ANSFAIL_TNSAPIE - Server failed to answer connect request.
20017 - NMRESFAIL_TNSAPIE - Failed to resolve service name.
20018 - WOULDBLOCK_TNSAPIE - Operation would block.
20019 - CTLFAIL_TNSAPIE - Control call failed.
20020 - TNSAPIE_ERROR - TNS error occurred.
20021 - INVCTL_TNSAPIE - Invalid operation request in control call.

9.2 UNIX Client Programming

Event programming in UNIX requires the use of a UNIX signal. When an event occurs, a signal flags a process. The process executes code that is relevant to the particular signal generated. UNIX does not allow a single process to set more than one signal handler or alarm for a particular signal call. If a process sets a second signal handler or alarm request on a signal like SIGCHLD (signal on a child process' status change), UNIX nullifies and loses the previous request for the SIGCHLD.

If any part of your application issues one of these requests, signal handling or alarms may cause the system to lose and never respond to that particular request. Depending on the signal requested, the system may not clean up defunct processes properly because of a signal handler problem.

Net8 provides two solutions to allow for the use of signal handling and alarms in tandem with Oracle's usage of those requests:

9.2.1 Signal Handler and Alarm Programming

Net8 provides an operating system dependent (OSD) call that keeps a table of all signal handler or alarm requests for each signal. Any program that uses the signal handler or alarm is now required to use the Oracle OSD calls. This provides a solution for programmers in UNIX who are not allowed to set more than one signal handler or alarm for a particular call. Any program that uses the signal handler or alarm must use the Oracle OSD calls. This is however, currently available only for internal use. In the near future, an externalized version of the OSD calls for client application usage will be released.

Until then, if you set all of the client's signal handlers before making any database connections, the OSD call will remember the last signal handler set for the signal and will add it to the signal handler table. Note that by doing this, you cannot disable the signal handler.

9.2.1.1 Oracle OSD Signal Handling Rules

To use the table-driven shared OSD signal handler for all SIGCHLD calls, you must observe the following rules:

9.2.2 Bequeath Adapter

This section is for UNIX application programmers who use both the UNIX signal handler for tracking child process status changes with the SIGCHLD call and Net8 for the networking portion of their application.

When a client application is directed to communicate with an Oracle database on the same machine, it uses Net8's Bequeath Adapter to establish the connection. The Bequeath Adapter enables the client to retrieve information from the database without using the network Listener. The Bequeath Adapter internally spawns a server process for each client application. In a sense, it performs locally the same operation that a remote listener does for your connection.

9.2.2.1 Child Process Termination

Since the client application spawns a server process internally through the Bequeath Adapter as a child process, the client application becomes responsible for cleaning up the child process when it completes. When the server process completes its connection responsibilities, it becomes a defunct process. Signal handlers are responsible for cleaning up these defunct processes. Alternatively, you may configure your client profile to pass this process to the UNIX init process by disabling signal handlers.

Use the Oracle Net8 Assistant to configure a client to disable the UNIX signal handler. The profile parameter set to disable is as follows:

BEQUEATH_DETACH=YES

This parameter causes all child processes to be passed over to the UNIX init process (pid = 1). The init process automatically checks for "defunct" child processes and terminates them.

The Bequeath Adapter automatically chooses to use a signal handler in tracking child process status changes. If your application does not use any signal handling, then this default does not affect you.




Prev

Next
Oracle
Copyright © 1997 Oracle Corporation.

All Rights Reserved.

Library

Product

Contents

Index