Qp0lReaddir()--Read Directory Entry with Extensions


  Syntax
 #include <sys/types.h>
 #include <dirent.h>
 
 int Qp0lReaddir(DIR *dirp, char *entry,  
              char **result, struct Qp0lReaddir_T *extensions);
  Service Program Name: QP0LLIB1

  Default Public Authority: *USE

  Threadsafe: Conditional; see Usage Notes

The Qp0lReaddir() function is used to retrieve directory entry information from a directory stream associated with dirp. It can retrieve this information in a number of different formats based on values present in the Qp0lReaddir_T structure specified by the extensions parameter.

The Qp0lReaddir() function stores a pointer to a directory entry structure at the location referenced by result. This pointer represents the next directory entry in the directory stream that is associated with dirp. If entry is a NULL pointer, result will reference system-supplied storage, similar to the pointer returned by the readdir() or QlgReaddir() functions.

If entry is not a NULL pointer, then result will reference the storage pointed to by entry, similar to the readdir_r() or QlgReaddir_r() functions. Additionally, the Qp0lReaddir() function will initialize the storage that is referenced by entry with information retrieved from the directory stream. The storage pointed to by entry must be large enough to contain all the requested attribute and name information.

If the call to Qp0lReaddir() actually reads the directory, the access time of the directory is updated.

The Qp0lReaddir() function converts the directory entry name into one of the following:

  1. The CCSID (coded character set identifier) of the job at the time of the call to opendir().
  2. The CCSID specified in the Qlg_Path_Name_T structure for the dirname parameter supplied to QlgOpendir(). See QlgOpendir()--Open Directory (using NLS-enabled path name) for more information.

If the directory entry name cannot be represented in the desired CCSID, then that directory entry will not be returned by Qp0lReaddir() and no error indication will occur.

Parameters

dirp
(Input) A pointer to a DIR that refers to the open directory stream to be read. This pointer is returned by opendir() or QlgOpendir() (see opendir()--Open Directory or QlgOpendir()--Open Directory (using NLS-enabled path name)).
entry
(Output) A pointer to storage in which the directory entry information is to be placed. This pointer may be NULL.
result
(Output) A pointer to a pointer to storage. Upon successfully reading a directory entry, the output pointer will point to storage describing the next directory entry in the directory stream. If entry is not a NULL pointer, the output pointer will be set to the same value as entry. Upon reaching the end of the directory stream, the output pointer will be set to NULL.
extensions
(Input) A pointer to a Qp0lReaddir_T structure, which has the following contents:



Attribute Format Structures

Qp0lReaddirAttrDirent
char d_reserved1[16]
Reserved.
unsigned int d_fileno_gen_id
The generation ID associated with the file ID.
ino_t d_fileno
The file ID of the object. This number uniquely identifies the object within a file system.
unsigned int d_reclen
The length of the directory entry in bytes.
int d_reserved3
Reserved.
char d_reserved4[8]
Reserved.
Qp0lReaddirAttr001
char d_reserved1[24]
Reserved.
unsigned int d_reclen
The length of the directory entry in bytes.
mode_t d_mode
A bit string indicating the permissions and privileges of the object. Symbols are defined in the <sys/stat.h> header file to refer to bits in a mode_t value; these symbols are listed in chmod()--Change File Authorizations.
char d_reserved3[26]
Reserved.
char d_pc_read_only
A non-zero value indicates the object cannot be written to or deleted, have its extended attributes changed or deleted, or have its size changed.
char d_pc_hidden
A non-zero value indicates the object cannot be displayed using an ordinary directory listing.
char d_pc_system
A non-zero value indicates the object is a system file and is excluded from normal directory searches.
char d_pc_archive
A non-zero value indicates the object has changed since the last time the file was examined.
char d_reserved4[2]
Reserved.
qp0l_objtype_t d_objtype
The object type; for example, *STMF or *DIR. Refer to the CL programming topic for a list of the object types.
char d_reserved5[5]
Reserved.
Qp0lReaddirAttr002
time64_t d_create_time
The time the object was created.
time64_t d_modify_time
The most recent time the contents of the object were changed.
char d_reserved1[8]
Reserved.
unsigned int d_reclen
The length of the directory entry in bytes.
mode_t d_mode
A bit string indicating the permissions and privileges of the object. Symbols are defined in the <sys/stat.h> header file to refer to bits in a mode_t value; these symbols are listed in chmod()--Change File Authorizations.
time64_t d_access_time
The most recent time the object was accessed.
time64_t d_chkout_time
The time the object was last checked out.
char d_chk_user[10]
The name of the user to whom the object is checked out. The field is blank if the object is not checked out.
char d_pc_read_only
A non-zero value indicates the object cannot be written to or deleted, have its extended attributes changed or deleted, or have its size changed.
char d_pc_hidden
A non-zero value indicates the object cannot be displayed using an ordinary directory listing.
char d_pc_system
A non-zero value indicates the object is a system file and is excluded from normal directory searches.
char d_pc_archive
A non-zero value indicates the object has changed since the last time the file was examined.
char d_reserved3[18]
Reserved.
unsigned long long d_size
Defined as follows for each file type:
Regular File
The number of data bytes in the file.
Directory
The number of bytes allocated to the directory.
Symbolic Link
The number of bytes in the path name stored in the symbolic link.
Local Socket
Always zero.
Operating System Native Object
This value is dependent on the object type.
unsigned int d_extended_attr_size
The size in bytes of the object's extended attributes.
char d_reserved4[4]
Reserved.
Qp0lReaddirAttr003
char d_reserved1[8]
Reserved.
time64_t d_modify_time
The most recent time the contents of the object were changed.
unsigned int d_fileno_gen_id
The generation ID associated with the file ID.
ino_t d_fileno
The file ID of the object. This number uniquely identifies the object within a file system.
unsigned int d_reclen
The length of the directory entry in bytes.
mode_t d_mode
A bit string indicating the permissions and privileges of the object. Symbols are defined in the <sys/stat.h> header file to refer to bits in a mode_t value; these symbols are listed in chmod()--Change File Authorizations.
time64_t d_access_time
The most recent time the object was accessed.
time64_t d_chkout_time
The time the object was last checked out.
char d_chk_user[10]
The name of the user to whom the object is checked out. The field is blank if the object is not checked out.
char d_reserved3[4]
Reserved.
unsigned short d_nlink
The number of links to the object. If the actual number of links is greater than 65,535, then this field will contain 65,535 (0xFFFF).
qp0l_objtype_t d_objtype
The object type; for example, *STMF or *DIR. Refer to the CL programming topic for a list of the object types.
char d_reserved4[5]
Reserved.
unsigned long long d_size
Defined as follows for each file type:
Regular File
The number of data bytes in the file.
Directory
The number of bytes allocated to the directory.
Symbolic Link
The number of bytes in the path name stored in the symbolic link.
Local Socket
Always zero.
Operating System Native Object
This value is dependent on the object type.
char d_reserved5[16]
Reserved.
unsigned long long d_alloc_size
The number of bytes allocated to the object.
time64_t d_change_time
The most recent time the status of the object was changed.
char d_sys_archive
A non-zero value indicates the object has changed since the last time the file was examined.
char d_remote
A non-zero value indicates the object's data is stored remotely.
char d_non_savable
A non-zero value indicates the object cannot be saved.
char d_nwsstg
A non-zero value indicates the object is a network storage space object.
char d_case
A non-zero value indicates the file system is case-sensitive.
char d_oflow
A non-zero value indicates the object has overflowed the auxiliary storage pool it resides in.
char d_stg_free
A non-zero value indicates the file's data has been moved offline, freeing its online storage.
char d_file_format
A non-zero value indicates the object is a *TYPE2 stream file (*STMF) object.
char d_alwckpwrt
A non-zero value indicates the object can be shared with readers and writers during save-while-active checkpoint processing.
char d_signed
A non-zero value indicates the object has an IBM i digital signature.
char d_dir_format
A non-zero value indicates the object is a *TYPE2 directory (*DIR) object.
char d_system_signed
A non-zero value indicates the object was signed by a source that is trusted by the system.
char d_sisvtx
A non-zero value indicates additional restrictions for rename and unlink operations are in place for a directory. Objects can be linked into a directory with these additional restrictions, but cannot be renamed or unlinked from it unless one or more of the following are true for the user performing the operation:
  • The user is the owner of the object.
  • The user is the owner of the directory.
  • The user has *ALLOBJ special authority.
This restriction only applies to directories. Other object types may have this attribute, however, it will be ignored. This attribute is equivalent to the S_ISVTX mode bit for an object.
char d_virtual_vol
A non-zero value indicates the object is a virtual volume.
char d_temp_fs
A non-zero value indicates the objects that reside in the UDFS are temporary objects.
char d_temp_obj
A non-zero value indicates the object is a temporary object.
char d_preferred_storage_fs
A non-zero value indicates that storage for objects created in the UDFS should be allocated from solid state drive storage media, if available.
char d_inherit_alwckpwrt
A non-zero value indicates that stream files created in this directory can be shared with readers and writers during save-while-active checkpoint processing.
char d_sys_restricts_save
A non-zero value indicates that the object cannot be saved because of system restrictions.
char d_reserved6[21]
Reserved.

Values of time64_t are given in terms of seconds since a fixed point in time called the Epoch.

You can examine properties of a mode_t value from a d_mode field using a collection of macros defined in the <sys/stat.h> header file. If mode is a mode_t value, then:

S_ISBLK(mode)
Is non-zero for block special files
S_ISCHR(mode)
Is non-zero for character special files
S_ISDIR(mode)
Is non-zero for directories
S_ISFIFO(mode)
Is non-zero for pipes and FIFO special files
S_ISREG(mode)
Is non-zero for regular files
S_ISLNK(mode)
Is non-zero for symbolic links
S_ISSOCK(mode)
Is non-zero for local sockets
S_ISNATIVE(mode)
Is non-zero for operating system native objects

Name Format Structures

Qp0lReaddirName
qlg_nls_t d_nlsinfo
National language information about d_name.
unsigned int d_namelen
The length of the name in bytes, excluding the null terminator.
char d_name[_QP0L_DIR_NAME]
A string that gives the name of a file in the directory. This string ends in a terminating null, and has a maximum length of {NAME_MAX} bytes, not including the terminating NULL (see pathconf()--Get Configurable Path Name Variables).
Qp0lReaddirNameLg
Qlg_Path_Name_T d_lg_qlg
A Qlg_Path_Name_T structure that describes the name in the d_lg_name field. For more information about the Qlg_Path_Name_T structure, see Path name format.
char d_lg_name[_QP0L_DIR_NAME_LG]
A string that gives the name of an object in the directory. The string is not null-terminated within the field, and is described by the d_lg_qlg field.

Authorities and Locks

None.


Return Value

0
Qp0lReaddir() was successful. The result parameter points to one of the following:
  • A pointer to storage that describes the next directory entry in the directory stream. If entry parameter is not a NULL pointer, then this will be the same value as the entry parameter.
  • A NULL pointer. Qp0lReaddir() reached the end of the directory stream.
error code
Qp0lReaddir() was not successful. This value is set to the same value as the errno global variable.

Error Conditions

If Qp0lReaddir() is not successful, errno usually indicates one of the following errors. Under some conditions, errno could indicate an error other than those listed here.

If interaction with a file server is required to access the object, errno could indicate one of the following errors:


Error Messages

The following messages may be sent from this function:


Usage Notes

  1. This function will fail with error code [ENOTSAFE] when all the following conditions are true:

    • Where multiple threads exist in the job.
    • The object on which this function is operating resides in a file system that is not threadsafe. Only the following file systems are threadsafe for this function:
      • "Root" (/)
      • QOpenSys
      • User-defined
      • QNTC
      • QSYS.LIB
      • Independent ASP QSYS.LIB
      • QOPT
      • Network File System
      • QFileSvr.400

  2. If the dirp argument passed to Qp0lReaddir() does not refer to an open directory stream, Qp0lReaddir() returns the [EBADF] error.

  3. Qp0lReaddir() buffers multiple directory entries to improve performance. This means the directory is not actually read on each call to Qp0lReaddir(). As a result, files that are added to the directory may not be returned on calls to Qp0lReaddir(), and files that are removed from the directory may still be returned on calls to Qp0lReaddir().

  4. Qp0lReaddir() retrieves information from the directory entries, not from the objects in the directory. File systems do not usually place all of the information about an object in the directory entry. In addition, the information in the directory entries might not be updated at the same time as the information in the object. Therefore, some of the data that is returned by Qp0lReaddir() will not match similar data returned by other functions, such as stat() or QlgGetAttr(). Examples include, but are not limited to, the following:
    • The permission bits in the d_mode field may be different than the value returned in the st_mode field returned from stat() or related APIS. However, the object type indicators will be correct.
    • The d_size, d_extended_attr_size, and d_alloc_size fields may not match the sizes returned by other functions. If there is a mismatch, the size returned by Qp0lReaddir() will usually be zero.
    • The d_access_time and d_create_time fields will always be zero for entries returned from the QDLS file system, except for the '.' and '..' entries.
    • If the open directory is the root of a mounted file user-defined file system (UDFS) or network file system (NFS), the data returned for the '..' entry should generally be ignored.
    • For objects in NFS directories, the d_fileno_gen_id field will always be 0xFFFFFFFF.


  5. For best results, you should not change the contents of the Qp0lReaddir_T structure between calls to Qp0lReaddir() for the same open directory stream. In particular, changing the sortedOrder, patternType, or patternName fields between calls may produce undesireable results. Changing other fields will likely produce the expected results, but may have a negative impact on application performance.

  6. When QP0L_READDIR_ATTR_002 or QP0L_READDIR_ATTR_003 is specified for the attrFormat field, some file systems will not return entries for '.' and '..'.

  7. Performance considerations for the Qp0lReaddir() function include the following:
    • Many applications read through a directory and then must immediately call some other API, such as stat(), to retrieve the attributes of the named object so that they can decide what further operations should be performed on the object. The various attribute format structures allow applications to eliminate calling an additional function just to return certain attributes.
    • Many applications read through a directory and perform further operations on each object found in the directory. For example, an application may read through a directory, open each file, read some data from the file, and close the file. These further operations may access the object's storage, which can cause a non-database page fault and negatively affect the performance of the application. Using the asyncBring extension can improve the performance of such an application by bringing the named object into memory before the following operations access its storage, avoiding the page fault.
    • Multiple entries can be returned on a single call to Qp0lReaddir() by specifying a value for the entryBytesProvided field that is large enough hold the desired output information. The result parameter will point to the first entry. Addressability to each succeeding entry is calculated by adding the value in the d_reclen field for the current entry to the address of the current entry. You should not assume that all entries will have the same length. As you process the returned entries, you should keep a running total of the d_reclen values for the entries so that you know how many bytes have been processed. When this total equals or exceeds the entryBytesReturned value, you know that you have reached the end of the returned data and must call Qp0lReaddir() again to read more entries.
  8. QSYS.LIB and Independent ASP QSYS.LIB File System Differences

    Calls to Qp0lReaddir() that update the access time of the directory use the normal rules that apply to libraries and database files. At most, the access time is updated once per day.

    When reading the contents of the /QSYS.LIB directory, user profile (*USRPRF) objects to which the caller does not have any authority (i.e., *EXCLUDE) will not be returned from Qp0lReaddir().

  9. QDLS File System Differences

    The access time of a directory is not affected by Qp0lReaddir().

    When objects in QDLS are accessed, the country or region ID and language ID of the directory entry name are always set to the country or region ID and language ID of the system.

    When a Qp0lReaddir() operation takes place on the /QDLS directory, the user must have *USE authority to each object in the /QDLS directory (that is, *USE authority to each object immediately below QDLS in the directory hierarchy). A directory entry is returned only for those objects for which the user has *USE authority. If the Qp0lReaddir() operation takes place on a directory below QDLS, a directory entry is returned for all objects, even if the user does not have *USE authority for some of the objects.

  10. QOPT File System Differences

    The access time of the directory is not updated on a Qp0lReaddir() operation.


Related Information


Example

The following example reads the contents of the "root" (/) directory.

Note: By using the code examples, you agree to the terms of the Code license and disclaimer information.

#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <stdio.h>

main() {
  int return_code;
  DIR *dir;
  char entry[sizeof(struct Qp0lReaddirAttr003) +
             sizeof(struct Qp0lReaddirName)];
  char *result;
  char *entryName;
  struct Qp0lReaddir_T extensions;

  memset((void *)&extensions,
         0x00,
         sizeof(struct Qp0lReaddir_T));
  extensions.attrFormat = QP0L_READDIR_ATTR_003;
  extensions.nameFormat = QP0L_READDIR_NAME;
  extensions.threadSafe = QP0L_READDIR_THREADSAFE_YES;
  extensions.asyncBring =
    QP0L_READDIR_ASYNCBRING_FILE |
    QP0L_READDIR_ASYNCBRING_DIR;
  if ((dir = opendir("/")) == NULL)
    perror("opendir() error");
  else {
    puts("contents of root:");
    for (return_code = Qp0lReaddir(dir,
                                   entry,
                                   &result,
                                   &extensions);
         result != NULL && return_code == 0;
         return_code = Qp0lReaddir(dir,
                                   entry,
                                   &result,
                                   &extensions))
    {
      entryName = result +
        sizeof((struct Qp0lReaddirAttr003);
      printf("  %s - %s\n",
             ((struct Qp0lReaddirName *)entryName)->d_name,
             ((struct Qp0lReaddirAttr003 *)result)->d_objtype);
    }
    if (return_code != 0)
      perror("Qp0lReaddir() error");
    closedir(dir);
  }
}
Example Output:
contents of root:
  . - *DIR
  .. - *DIR
  QSYS.LIB - *DIR
  QDLS - *DIR
  QOpenSys - *DIR
  QOPT - *DIR
  home - *DIR
  fred - *STMF

API introduced: IBM® i 7.2

[ Back to top | UNIX-Type APIs | APIs by category ]