From:	SMTP%"RELAY-INFO-VAX@CRVAX.SRI.COM"  4-MAY-1993 19:19:23.07
To:	EVERHART
CC:	
Subj:	Re: Help with LIB$FIND_FILE() & C

Date: 04 May 1993 21:13:34 +0100
From: Arne Vajhøj <ARNE@kopc.hhs.dk>
Subject: Re: Help with LIB$FIND_FILE() & C
To: ewbankk@LOGICA.CO.UK, INFO-VAX@SRI.COM
Message-id: <01GXSI34UIB8935AZ5@kopc.hhs.dk>
X-VMS-To: KOPC::IN%"ewbankk@LOGICA.CO.UK"
X-VMS-Cc: IN::"INFO-VAX@SRI.COM"
MIME-version: 1.0
Content-type: TEXT/PLAIN; CHARSET=ISO-8859-1
Content-transfer-encoding: 8BIT

> I am trying to use LIB$FIND_FILE in a VAX C program to search a wildcard file
> specification for files as follows:
> 
> #include <descrip.h>
> #include <ssdef.h>
> #include <stdio.h>
> #include <stdlib.h>
> 
> main( void )
> {
>   int iStatus = SS$_NORMAL;
>   $DESCRIPTOR( dscSearch, "*.*" );
>   struct dsc$descriptor_s dscResultant;
>   unsigned int context;
> 
>   dscResultant.dsc$b_class = DSC$K_CLASS_S;
>   dscResultant.dsc$b_dtype = DSC$K_DTYPE_T;
> 
>   while ( 1 )
>   {
>     iStatus = LIB$FIND_FILE( &dscSearch, &dscResultant, &context, 0, 0, 0, 0 );
>     if ( iStatus % 2 == 0 )     /* Error */
>         break;
>     printf( "%s\n", dscResultant.dsc$a_pointer );
>   }
> 
>   exit( iStatus );
> }
> 
> However this doesn't work - I get '%RMS-F-FAB, invalid FAB or FAB not
> accessible'.
> 
> What am I doing wrong?

The pointer dscResultant.dsc$a_pointer is uninitialize, so LIB$FIND_FILE
puts the result somewhere "random". The results are "unpredictable".

The following modified version works:

#include <string.h>
#include <descrip.h>
#include <ssdef.h>
#include <stdio.h>
#include <stdlib.h>

main( void )
{
  int iStatus = SS$_NORMAL;
  $DESCRIPTOR( dscSearch, "*.*" );
  char fnm[256],*s;
  $DESCRIPTOR( dscResultant, fnm );
  unsigned int context;

  while ( 1 )
  {
    iStatus = LIB$FIND_FILE( &dscSearch, &dscResultant, &context, 0, 0, 0, 0 );
    if ( iStatus % 2 == 0 )     /* Error */
        break;
    s = strchr( &fnm, ' ' );
    *s = '\0';
    printf( "%s\n", &fnm );
  }

  exit( iStatus );
}

You should also call LIB$FIND_FILE_END to follow good programming practice !

BTW - the following two examples of calling LIB$FIND_FILE from C was posted
here by me 2 years ago. The first looks almost identical to yours. The
second is more tricky !

Here they are:

#include <stdio.h>
#include <ssdef.h>
#include <rmsdef.h>
#include <descrip.h>
#include <string.h>

int lib$find_file();
int lib$find_file_end();

main()
{
   int context = 0;
   int status;
   char *s;
   char find[]="*.c";
   $DESCRIPTOR(finddesc,find);
   char result[255];
   $DESCRIPTOR(resultdesc,result);
   do {
      status = lib$find_file(&finddesc,&resultdesc,&context,0,0,0,0);
      if (status == RMS$_NORMAL) {
         s = strchr(result,' ');
         *s = '\0';
         printf("%s\n",result);
      };
   } while (status == RMS$_NORMAL);
   lib$find_file_end(&context);
   return SS$_NORMAL;
};

#include <stdio.h>
#include <ssdef.h>
#include <rmsdef.h>
#include <descrip.h>
#include <string.h>

#define $VDESCRIPTOR(name,string) struct dsc$descriptor_vs name = \
                                  { sizeof(string.BODY)-1, DSC$K_DTYPE_VT, \
                                    DSC$K_CLASS_VS, &string }

int lib$find_file();
int lib$find_file_end();

main()
{
   int context = 0;
   int status;
   char *s;
   char find[]="*.c";
   $DESCRIPTOR(finddesc,find);
   struct {
          short LENGTH;
          char BODY[256];
          } result;
   $VDESCRIPTOR(resultdesc,result);
   do {
      status = lib$find_file(&finddesc,&resultdesc,&context,0,0,0,0);
      if (status == RMS$_NORMAL) {
         result.BODY[result.LENGTH] = '\0';
         printf("%s\n",result.BODY);
      };
   } while (status == RMS$_NORMAL);
   lib$find_file_end(&context);
   return SS$_NORMAL;
};

                                                          Arne

Arne Vajhøj                             local DECNET:  KO::ARNE
Computer Department                     PSI:           PSI%238310013040::ARNE
Business School of Southern Denmark     Internet:      ARNE@KO.HHS.DK


