flocate() — Locate a VSAM record

Standards

Standards / Extensions C or C++ Dependencies
Language Environment both  

Format

#include <stdio.h>

int flocate(FILE *stream, const void *key, size_t key_len, int options);

#define _OPEN_SYS_UNLOCKED_EXT 1
#include <stdio.h>

int flocate_unlocked(FILE *stream, const void *key, size_t key_len, int options);

General description

Moves the VSAM file position indicator associated with the stream pointed to by stream, according to the rest of the arguments specified.

To avoid infringing on the user's name space, this nonstandard function has two names. One name is prefixed with two underscore characters, and one name is not. The name without the prefix underscore characters is exposed only when you use LANGLVL(EXTENDED).

To use this function, you must either invoke the function using its external entry point name (that is, the name that begins with two underscore characters), or compile with LANGLVL(EXTENDED). When you use LANGLVL(EXTENDED) any relevant information in the header is also exposed.

key points to a key used for positioning.

key_len specifies the length of the search key. The key_len argument value must always be nonzero, except for __KEY_FIRST and __KEY_LAST.
KSDS, KSDS PATH, and ESDS PATH
The key can point to a field of any storage type except register. Typically it points to a character string whose length is key_len. The key_len must be less than or equal to the key length of the data set. If key_len is the same as the file's key length, a full key search is automatically used; otherwise, a generic search is used. A generic key search is one in which the search key is a leading portion of the key field. The record positioned to is the first of the records having the same generic key.
ESDS
The key points to a relative byte address that may be stored as 4 or 8 byte value. key_len is either 4 or 8.
RRDS
The key points to a relative record number stored as an unsigned long int. key_len is either 4 or 8.

options specifies the position options described in Table 1.

Table 1. Position Options Parameter for flocate()
__KEY_FIRST Positions to the first record in the file. Subsequent reads are in the forward direction. key and key_len are ignored.
__KEY_LAST Positions to the last record in the file. Subsequent reads are in backward order. key and key_len are ignored.

Only applies to VSAM files opened in record mode.

__KEY_EQ Positions to the first record with the specified key. Subsequent reads are in the forward direction.
__KEY_EQ_BWD Positions to the first record with the specified key. Subsequent reads are in backward order. Using this option requires a full key search. Key_len must be equal to the key length as defined for the data set.

Only applies to VSAM files opened in record mode.

__KEY_GE Positions to the first record with a key greater than or equal to the specified key.
__RBA_EQ Positions to the record with the specified RBA. Subsequent reads are in the forward direction.

You cannot use __RBA_EQ with an alternative index path.

Using this option with RRDS is not recommended. The underlying VSAM utilities do not support seeking to an RBA in an RRDS file. The flocate() function attempts to convert the RBA to a Relative Record Number by dividing the value by the LRECL of the file and using the equivalent __KEY_EQ.

Using this option with KSDS is not recommended because the RBA of a given record may change over time, because of inserts, deletions, or updates of other records.

__RBA_EQ_BWD Positions to the record with the specified RBA. Subsequent reads are in backward order.

You cannot use __RBA_EQ_BWD with an alternative index path.

Using this option with RRDS is not recommended. The underlying VSAM utilities do not support seeking to an RBA in an RRDS file. The flocate() function attempts to convert the RBA to a Relative Record Number by dividing the value by the LRECL of the file and using the equivalent __KEY_EQ_BWD.

Using this option with KSDS is not recommended because the RBA of a given record may change over time, because of inserts, deletions, or updates of other records.

Only applies to VSAM files opened in record mode.

_KEY_EQ_BWD Positions to the first record with the specified key. Subsequent reads are in backward order.

Using this option requires a full key search. key_len must be set equal to the key length as defined for the data set.

Only applies to VSAM files opened in record mode.

Notes:
  1. When you are trying to use flocate() in a path to a nonunique key, the resulting position will be at the first physical record of the duplicate key set.
  2. flocate() releases all record locking.
  3. Writes to VSAM data sets are not affected by preceding calls to flocate().
  4. If a record was not found, you must successfully relocate to another position before reading or writing (using the flocate() function). The exception to this is that a write that follows a failed flocate() will succeed if the file was opened for initial loading, but no records have been written to it yet.

flocate_unlocked() is functionally equivalent to flocate() with the exception that it is not thread-safe. This function can safely be used in a multithreaded application if and only if it is called while the invoking thread owns the (FILE*) object, as is the case after a successful call to either the flockfile() or ftrylockfile() function.

Considerations for VSAM extended addressability data sets: flocate() accepts key lengths of 4 or 8 when relative byte address (RBA) values are used for positioning. A key length of 8 is required only when the working with a VSAM extended addressability data set, because when the address grows past the 4GB boundary, the key needs to be large enough to hold the value.

When using the value 4GB-1 as the key to flocate(), the key length must be 8 and the data type used must be 8 bytes in size (for example, X' 00000000FFFFFFFF') . If the key length is 4, flocate() treats the key as -1(EOF).

Returned value

If successful, flocate() returns 0.

If a record was not found or the position is beyond the EOF, flocate() returns EOF.

Example

#include <stdio.h>

int main(void)
{
   FILE *stream;
   int   vsam_rc;
   char *key = "RECORD 27";

   stream = fopen("DD:MYCLUS", "rb+,type=record");
   vsam_rc = flocate(stream, key, 9, __KEY_EQ);
⋮
}

Related information