Name

libdcs.a — C and C++ callable interface to DCS commands.

Synopsis

#include <dcs.h>
			
DCSExitCode dcs_name( args,  
  out,  
  err);  
const char*   args;
char**   out;
char**   err;

For C++ language users, these functions and an enumeration defining the DCSExitCode values are contained in the NCAR_MSS namespace.

#include <dcs.h>
			
NCAR_MSS::DCSExitCode NCAR_MSS::dcs_name( args,  
  out,  
  err);  
const char*   args;
char**   out;
char**   err;

Description

These functions provide a convenient wrapper around the procedure of starting the DCS command and collecting the command's output and exit status. By including the dcs.h header file, the correct types for the arguments and return values will be automatically used regardless of the specific API (32-bit, 64-bit) used by the application program.

The dcs_name in the synopsis is replaced with the name of one of the DCS commands listed below:

DCS request management commands dcsjlog, dcsq, dcsrm and dcswait
Metadata commands msallinfo, mschproj, msclass, mscomment, msdu, msfind, msls, msmv, mspasswd, mspwd, msrecover, msretention, msrm and mstouch.
File transfer msrcp

The args parameter is a string to be parsed into command arguments passed to the DCS command. Pass either a NUL terminated char array or a string constant. The parsing of the args parameter proceeds as follows:

  • Space characters separate arguments. Spaces are skipped until the first non-space character is found. Other white space characters, such as tabs and new lines, do not separate arugments.
  • Characters are then collected into the argument until the next non-quoted space character is found, or the end of the string is reached.
  • Any single character may have its special behavior, if any, escaped by prefixing it with a back slash (\) character.
  • Multiple characters may be quoted by using a pair of either single quotes (') or a pair of double quotes ("). Quoted characters may not be nested, but a double quote may appear inside a pair of single quotes (or vice versa).

The out parameter is the address of a char pointer variable, which will be set to the address of a newly allocated buffer that contains a NUL terminated string containing the stdout stream of the DCS command. The maximum possible size of the buffer is 1 million bytes. The buffer pointed to by out must be freed by the application, or a memory leak will result.

The err parameter is the address of a char pointer variable, which will be set to the address of a newly allocated buffer that contains a NUL terminated string containing the stderr stream of the DCS command. The maximum possible size of the buffer is 1 million bytes. The buffer pointed to by err must be freed by the application, or a memory leak will result.

Return Values

For library or system call detected errors -1 will be returned and errno will be set. An error message, prefixed by ERROR detected by the DCS library:, will appear on the stderr of the calling process. Otherwise, the (positive) exit status of the DCS command will be returned.

Errors

If -1 is returned, errno will likely have been set by one of the following library or system calls: close(2), dup2(2), fork(2), free(3), malloc(3), pipe(2), read(2), select(2), and waitpid(2).

Notes

The library routines work by executing a fork(2) to create a child process, then execvp(2) to start the DCS command (which searchs along the PATH environment variable to find them). The stdout and stderr streams are collected by reading two pipes and placing the output either into the appropriate user-provided buffers or allocating and returning new buffers. The child process is reaped with waitpid(2).

Warning

In an effort to be usable by threaded applications, the libdcs.a routines do not use the system(3) function, as it is not thread safe on all of the platforms supported by DCS. Thus it is not possible to access shell or environment variables in the command's arguments.

If the application catches the SIGCHLD signal, it must be prepared for signal notifications caused by the termination of child processes started by the DCS library. The user's application must not use the wait(2) system call, or the DCS library will likely hang forever waiting for its child process.

This interface works best when the amount of command output is limited to a smaller amount of data. It tries to be memory efficient, but the storage for the collected command output stream is a linked list of 512 byte buffers that is then collapsed into a single buffer that holds the entire contents of the stream. Applications that are processing larger amounts of data should either use pipes directly or redirect the command output to a file, then open that file for reading when the command has completed.

Ensure your PATH environment variable includes the directory containing the DCS commands.

Since the mscdsetup command is not supported by this interface, either provide absolute MSS pathnames, or execute the appropriate mscdsetup(1NCAR) and mscd(1NCAR) commands prior to invoking your executable.

Examples

This example command line should probably work to compile 32-bit API C programs that use the DCS library:

cc -I/usr/local/dcs-4.0/include -L/usr/local/dcs-4.0/lib32 \
   -o program main.c -ldcs

Here is a C example of msls:

#include <dcs.h>
#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char** argv)
{
    DCSExitCode status;
    char*       out;
    char*       err;

    status = msls("-l /DIRECTORY", &out, &err);
    printf("msls exit status: %d\n", status);
    fputs(out, stdout);
    fputs(err, stderr);
    free(out);
    free(err);
    return(0);
}

Here is a more complex example of using the asynchronous feature of msrcp. In this example, we submit the msrcp request, then perform some other tasks, then wait for the msrcp request to complete. Be sure you review the msrcp man page for a complete description of using the "-async" option.

#include <dcs.h>
#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char** argv)
{
    DCSExitCode status;
    char*       msrcpout;
    char*       waitout;
    char*       err;

    /*...create local file "foo"...*/
    /* The DCS job id is placed into "msrcpout"... */
    status = msrcp("-async foo mss:/LOGIN/foo", &msrcpout, &err);
    if (status != DCS_EXIT_SUCCESS) {
        printf("msrcp exit status %d\n", status);
        printf("msrcp stderr: %s\n", err);
        return(1);
    }

    free(err);
    
    /* Perform other tasks
       Now wait for the msrcp to complete...*/
    status = dcswait(msrcpout, &waitout, &err);
    /* Check dcswait status ...*/
    free(msrcpout);
    free(waitout);
    free(err);
    return(status);
}

Files

These the header file is located at /usr/local/dcs-4.0/include/dcs.h. The library is located either in the /usr/local/dcs-4.0/lib32/libdcs.a file for 32-bit API programs, or the /usr/local/dcs-4.0/lib64/libdcs.a file for 64-bit API programs. Some system administrators may also provide symlinks to the header file and the libraries in other system specific locations.

See Also

DCSRunArgvAlloc(3NCAR), DCSRunArgvFixed(3NCAR), DCSRunParseAlloc(3NCAR), DCSRunParseFixed(3NCAR).

dcsjlog(1NCAR), dcsq(1NCAR), dcsrm(1NCAR), dcswait(1NCAR), msallinfo(1NCAR), mschproj(1NCAR), msclass(1NCAR), mscomment(1NCAR), msdu(1NCAR), msfind(1NCAR), msls(1NCAR), msmv(1NCAR), mspasswd(1NCAR), msrawinfo(1NCAR), msrcp(1NCAR), msrecover(1NCAR), msretention(1NCAR), msrm(1NCAR), mstouch(1NCAR).

Copyright

2008 University Corporation for Atmospheric Research, all rights reserved.