Qp0lProcessSubtree()--Process a Path Name
Syntax
#include <Qp0lstdi.h> int Qp0lProcessSubtree ( Qlg_Path_Name_T *Path_Name, uint Subtree_level, Qp0l_Objtypes_List_t *Objtypes_array_ptr, uint Local_remote_obj, Qp0l_IN_EXclusion_List_t *IN_EXclusion_ptr, uint Err_recovery_action, Qp0l_User_Function_t *UserFunction_ptr, void *Function_CtlBlk_ptr, ...);
Service Program Name: QP0LLIB2
Default Public Authority: *USE
Threadsafe: Conditional; see Usage Notes.
The Qp0lProcessSubtree() function searches the directory tree under a specific path name. It selects and passes objects, one at a time, to an exit program that is identified on its call. The exit program can be either a procedure or a program.
Qp0lProcessSubtree() performs read operations to access any object in any file system. The order in which objects are selected and passed to the exit program can vary within a given file system and within a given directory, dependent on file system rules. The only guaranteed ordering is that all selected objects within a given directory are passed to the exit program before the parent directory is passed to the exit program.
Parameters
- Path_Name
- (Input) The path name where Qp0lProcessSubtree() starts
its search. All relative path names are relative to the current directory at
the time of the call to Qp0lProcessSubtree(). This path name
is in the Qlg_Path_Name_T format. For more information about this structure, see
Path name format. The Path_Name parameter must
be NULL to use the IN_EXclusion_ptr parameter to enter multiple path
names for inclusion on a single call to
Qp0lProcessSubtree().
- Subtree_level
- (Input) An unsigned integer that tells
Qp0lProcessSubtree() whether or not to open subdirectories in the path
being processed. Valid values follow:
- 0
- QP0L_SUBTREE_YES: All subdirectories are opened by Qp0lProcessSubtree() so that the objects they contain are sent to the exit program if they meet the caller's selection criteria.
- 1
- QP0L_SUBTREE_NO: Only first-level objects are processed. The names of subdirectories, which meet the selection criteria, are passed to the exit program, but they are not opened by Qp0lProcessSubtree(). Thus, the objects the subdirectories contain are not matched against selection criteria and therefore are not sent to the exit program.
- Objtypes_array_ptr
- (Input) A pointer to an array of object types. Each entry in the array
identifies an object type that Qp0lProcessSubtree() uses to
determine what will be passed to the exit program. The Number of object types
field contains the total number of object types in the array. A NULL pointer
means that there is no filtering according to object type and that all object
types that meet other selection criteria are passed to the exit program.
The structure for this parameter follows.
Offset Type Field Dec Hex 0 0 BINARY(4) Number of object types 4 4 ARRAY(*) of CHAR(11) Array of object types structure
- Array of object types structure
- An array identifying each object type used to determine what will be passed
to the exit program when processing a path. Each entry is limited to 11
characters, including a NULL terminator, and is padded with blanks. Object
types must be entered in standard object type format which is all
capital letters, preceded by an asterisk (*). For a complete list of the
available object types, see External object types.
Qp0lProcessSubtree() verifies that valid object types are entered and returns the errno EINVAL when an object type that is not valid is entered. Although some object types are scoped to a specific file system, Qp0lProcessSubtree() does not validate object types according to file systems.
Valid special values for this parameter follow:
*ALLDIR: Select all directory object types. This includes *LIB, *DIR, *FLR, *FILE, and *DDIR object types. *ALLQSYS: Select all QSYS.LIB object types. This includes all objects in the QSYS.LIB file system and all independent ASP QSYS.LIB file systems which are available when the API is first called. Note: IN_EXclusion_ptr must also be specified as an inclusion array. If *NOQSYS is specified, *ALLQSYS cannot also be specified.
*ALLSTMF: Select all stream file object types. This includes *MBR, *DOC, *STMF, *DSTMF, and *USRSPC object types. *MBR: Select all database file member types. *NOQSYS: Exclude all QSYS.LIB object types. This includes all objects in the QSYS.LIB file system and all independent ASP QSYS.LIB file systems which are available when the API is first called. Note: This special value only has meaning if '/' or '/asp_name' is specified for the Path_Name parameter (where asp_name is the name of an independent ASP which is available when the API is first called). Additionally, if IN_EXclusion_ptr is specified, it must only be as an exclusion array. If *ALLQSYS is specified, *NOQSYS cannot also be specified.
- Number of object types
- The number of types included in the search.
- Local_remote_obj
- (Input) An unsigned integer that tells
Qp0lProcessSubtree() whether to select only local objects, only remote
objects, or both. Note that the decision of whether a file is local or remote
varies according to the respective file system rules. Objects in file systems
that do not carry either a local or remote indicator are treated as remote.
Valid values follow:
0 QP0L_LOCAL_REMOTE_OBJ: Both local and remote objects are passed to the exit program. 1 QP0L_LOCAL_OBJ: Only local objects are passed to the exit program. 2 QP0L_REMOTE_OBJ: Only remote objects are passed to the exit program.
- IN_EXclusion_ptr
- (Input) A pointer to an array of pointers. Each pointer in the array points
to a specific path name that identifies a directory, and all of its
subdirectories, that Qp0lProcessSubtree() either includes or
excludes in its search to find objects that meet the caller's input criteria.
If this pointer is not NULL, the IN_EXclusion pointer type must indicate
whether the list is an inclusive or exclusive list. The Number of pointers
field must contain the number of path names for inclusion or exclusion on the
search.
Use an inclusive list to specify multiple path names for searches on a single call to Qp0lProcessSubtree() versus using the Path_Name parameter, which searches only one path per call. The Path_Name parameter and an inclusive list are mutually exclusive. EINVAL is returned if both parameters are specified. The IN_EXclusion_ptr must be NULL if not used. All of the rules that apply to a single Path_Name entry apply to each inclusive list entry.
While an inclusion list allows the caller of Qp0lProcessSubtree() to identify multiple path names for processing, Qp0lProcessSubtree() does not perform any verification to ensure uniqueness of path names or to verify any other relationship between path names entered in the inclusion array. For example, if the path names entered represent nested directories, Qp0lProcessSubtree() calls the exit program multiple times without any error message or other notification of this nesting.
Specify the root directory for a given file system as an exclusive list entry to eliminate that file system from a search.
All relative path names are relative to the current directory at the time of the call to Qp0lProcessSubtree().
The structure for this parameter follows.
This points to a list of path names to either include or exclude from a search.
Offset Type Field Dec Hex 0 0 BINARY(4) IN_EXclusion pointer type 4 4 BINARY(4) Number of pointers 8 8 CHAR(8) Reserved 16 10 ARRAY(*) Path name pointers
- IN_EXclusion pointer type
- Whether a path name array contains directories that are included or
contains directories that are excluded. Valid values follow:
0 QP0L_INCLUSION_TYPE: An inclusion array is identified. 1 QP0L_EXCLUSION_TYPE: An exclusion array is identified. - Number of pointers
- The number of path name pointers that are in the inclusion or exclusion array.
- Path name pointers
- An array of pointers. Each pointer points to a path name that is included or excluded. Each path name must follow the Qlg_Path_Name_T structure. For more information about this structure, see Path name format.
- Reserved
- A reserved field. This field must be set to binary zero.
- Err_recovery_action
- (Input) An unsigned integer that describes how
Qp0lProcessSubtree() handles errors that are not severe enough to
force the API to bypass error recovery and immediately end processing.
Valid values follow:
0 QP0L_PASS_WITH_ERRORID: Calls the exit program and specifies the name (when the name is available) of the object being accessed when an error occurs. This value also sends a valid errno to the exit program. 1 QP0L_BYPASS_NO_ERRORID: Bypasses the object being accessed when an error occurs, and moves to process the next object in the tree without notification to the exit program that an error has occurred. 2 QP0L_JOBLOG_NO_ERRORID: Sends message CPDA1C0 to the job log to identify the object being accessed when an error occurs, and moves to process the next object in the tree without notification to the exit program that an error has occurred. 3 QP0L_NULLNAME_ERRORID: Calls the exit program with a NULL object name and a valid errno. 4 QP0L_END_PROCESS_SUBTREE: Quits Qp0lProcessSubtree() when an error occurs, and returns to the calling program, regardless of the error type. Note that the exit program is still given a call but cannot override the caller's decision to end processing. Calling the exit program allows the exit program to perform other tasks before the API returns to the caller. For example, the exit program can put information in the function control block that can be processed by the caller when the caller regains control.
- UserFunction_ptr
- (Input) A pointer to the name of an exit program that the caller wants
Qp0lProcessSubtree() to call upon finding an object that
matches the selection criteria. This exit program can be either a procedure or
a program. See Process a Path Name Exit Program for
the syntax of the user exit program.
The structure for this parameter follows.
This points to the user exit program. The exit program can be a procedure or a program.
Offset Type Field Dec Hex 0 0 BINARY(4) Function type flag 4 4 CHAR(10) Program library 14 E CHAR(10) Program name 24 18 CHAR(1) Multithreaded job action 25 19 CHAR(7) Reserved 32 20 PP(*) Procedure pointer to the exit procedure
- Function type flag
- An unsigned integer that indicates whether the user-supplied exit program
that is called by Qp0lProcessSubtree() is a procedure or a
program. Valid values follow:
0 QP0L_USER_FUNCTION_PTR: A user procedure is called. 1 QP0L_USER_FUNCTION_PGM: A user program is called. - Multithreaded job action
- (Input) A CHAR(1) value that indicates the action to take in a
multithreaded job. The default value is QP0L_MLTTHDACN_SYSVAL. For release
compatibility and for processing this parameter against the QMLTTHDACN system
value, x'00, x'01', x'02', & x'03' are treated as x'F0', x'F1', x'F2', and
x'F3'. Valid values follow:
x'00' QP0L_MLTTHDACN_SYSVAL: The API evaluates the QMLTTHDACN system value to determine the action to take in a multithreaded job. Although the API can make repetitive calls to an exit program, the system value is evaluated once before Qp0lProcessSubtree() issues its first exit program call. This value is used on subsequent calls until the API returns control to its caller. Valid QMLTTHDACN system values follow: '1' Call the exit program. Do not send an informational message. '2' Call the exit program. Send informational message CPI3C80. Qp0lProcessSubtree() may call the exit program multiple times; however, this message is sent only once for each call to Qp0lProcessSubtree(). '3' The exit program is not called when the API determines that it is running in a multithreaded job. ENOTSAFE is returned. x'01' QP0L_MLTTHDACN_NOMSG: Call the exit program. Do not send an informational message. x'02' QP0L_MLTTHDACN_MSG: Call the exit program. Send informational message CPI3C80. Qp0lProcessSubtree() may call the exit program multiple times; however, this message is sent only once for each call to Qp0lProcessSubtree(). x'03' QP0L_MLTTHDACN_NO: The exit program is not called when the API determines that it is running in a multithreaded job. ENOTSAFE is returned. - Procedure pointer to the exit procedure
- A procedure pointer to the procedure that Qp0lProcessSubtree() calls. This field must be NULL if a program is called instead of a procedure.
- Program library
- The library in which the called program, identified by Program name, is located. This field must be blank if a procedure is called instead of a program.
- Program name
- The name of the program that is called. The program is located in the library identified by Program library. This field must be blank if a procedure is called instead of a program.
- Reserved
- A reserved field. This field must be set to binary zero.
- Function_CtlBlk_ptr
- (Input) A pointer that Qp0lProcessSubtree() passes to the user-defined exit program that is called. Qp0lProcessSubtree() does not process this pointer or what is referred to by the pointer. It passes the pointer as a parameter to the user-defined exit program that was specified. This is a means for the caller of Qp0lProcessSubtree() to pass information to and from the Process a Path Name exit program.
Authorities
Note: Adopted authority is not used.
Authorization Required for Qp0lProcessSubtree()
Object Referred to | Authority Required | errno |
---|---|---|
Each directory, preceding the last component, in a Path Name | *X | EACCES |
The Path Name directory and all subdirectories of the Path Name that are included in the search. | *RX (See Note) | EACCES |
Each directory, preceding the last component, in any path name pointed to by the IN_EXclusion ptr | *X | EACCES |
The Path Name directory and all subdirectories of any path name pointed to by an inclusive list | *RX (See Note) | EACCES |
The object identified by the path name that is passed to the exit program, if the object is a user profile (*USRPRF) | Any authority greater than *EXCLUDE | EACCES |
Any called program pointed to by the UserFunction_ptr parameter | *X | EACCES |
Any library that contains the called program pointed to by the UserFunction_ptr parameter | *X | EACCES |
Note: If the directory or subdirectories have no objects in them, only *R is required. |
Return Value
0 | Qp0lProcessSubtree() was successful. |
-1 | Qp0lProcessSubtree() was not successful. The errno variable is set to indicate the error. |
Error Conditions
If Qp0lProcessSubtree() is not successful, the errno indicates one of the following errors:
Error condition | Additional information |
---|---|
[EACCES] |
If you are accessing a remote file through the Network File System, update operations to file permissions at the server are not reflected at the client until updates to data that is stored locally by the Network File System take place. (Several options on the Add Mounted File System (ADDMFS) command determine the time between refresh operations of local data.) Access to a remote file may also fail due to different mappings of user IDs (UID) or group IDs (GID) on the local and remote systems. |
[EAGAIN] | |
[EBADNAME] | |
[EBUSY] | |
[ECONVERT] | |
[EDAMAGE] | |
[EFAULT] | |
[EINVAL] | |
[EIO] | |
[EISDIR] | |
[ELOOP] | |
[EMFILE] | |
[ENAMETOOLONG] | |
[ENFILE] | |
[ENOENT] | |
[ENOMEM] | |
[ENOSPC] | |
[ENOSYSRSC] | |
[ENOTAVAIL] | |
[ENOTDIR] | |
[ENOTSAFE] | |
[EUNKNOWN] |
Error Messages
The following message may be sent from this function:
Message ID | Error Message Text |
---|---|
CPE3418 E | Possible APAR condition or hardware failure. |
CPF3CF2 E | Error(s) occurred during running of &1 API. |
CPFA0D4 E | File system error occurred. Error number &1. |
CPF9872 E | Program or service program &1 in library &2 ended. Reason code &3. |
Usage Notes
- 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
- Where multiple threads exist in the job.
- If the exit program called by Qp0lProcessSubtree() is not
threadsafe or uses a function that is not threadsafe, then
Qp0lProcessSubtree() is not threadsafe.
- If the exit program called by Qp0lProcessSubtree() uses a
function that fails when there are secondary threads active in the job,
Qp0lProcessSubtree() may fail as a result.
- Basic function and usage considerations
- Qp0lProcessSubtree() does not perform the following tasks
but is designed to work with the user exit function and other APIs to be useful
in accomplishing the following and other tasks:
- Retrieve object attributes (like authorities, dates, or sizes).
- Build lists from selected objects.
- Delete directories.
- Identify multiple occurrences of an object within or across directories.
- Count the number of objects in a directory.
- DosSetRelMaxFH() is called to increase to the maximum the number of file descriptors that can be opened during processing such that Qp0lProcessSubtree() is not likely to fail due to a lack of descriptors. This value is not reset when Qp0lProcessSubtree() ends because the API could be running in a multithreaded job.
- Qp0lProcessSubtree() does not perform the following tasks
but is designed to work with the user exit function and other APIs to be useful
in accomplishing the following and other tasks:
- Object locking
Qp0lProcessSubtree() does not perform any object locking, other than what is done when opening a directory to read the objects it contains, so that the exit program does not encounter or need to manage locks held by Qp0lProcessSubtree().
If Qp0lProcessSubtree() encounters a directory that is locked, Qp0lProcessSubtree() uses the defined Err_recovery_action to determine how to handle the locked condition. Locks on objects that are not directories have no effect on Qp0lProcessSubtree().
- Search Results
Once Qp0lProcessSubtree() has started searching a path, its search results may be affected by operations that update the organization of objects within the specifed directory tree. This includes, but is not limited to, the following:
- Adding, removing, or renaming object links,
- Mounting or unmounting file systems,
- Updating the effective root directory for the process calling this API,
- Updating the contents of a symbolic link.
- Design considerations for parameters
- Symbolic links
When the last component of the path name supplied on the initial call of Qp0lProcessSubtree() is a symbolic link, Qp0lProcessSubtree() resolves and follows the initial link to its target and performs its normal functions on the target. All other symbolic links that are encountered in the same search are not resolved to their targets.
If the path name supplied on the initial call of Qp0lProcessSubtree() is a symbolic link that points to another file system or that points to a remote file system, the API resolves and processes the initial link only. It does not resolve other symbolic links that are encountered in the same search. However, if the caller specified that remote objects are not processed, but the initial path name (whether a symbolic link or not) points to a remote file system, the link is not resolved. Qp0lProcessSubtree() calls the exit program with a NULL path name and an indicator that Qp0lProcessSubtree() has completed successfully without any error indicators to the exit program.
When *SYMLNK is specified as part of the selection criteria, Qp0lProcessSubtree() does not resolve the selected names.
- Recovery Actions
There are three separate parameters that control error recovery during a search. The caller of the API determines how an error should be reported to the exit program by setting the Err_recovery_actions parameter. The API sets the Selection status pointer and sends it to the exit program to indicate one of four conditions: the API search status is OK, the last object has been processed, the API has encountered recoverable errors, or the search cannot continue. For error conditions it also sends a valid errno. The exit program returns an indicator back to the API either to continue or to end the search by setting the Return value pointer. For error conditions, it also returns a valid errno, pointed to by the Return value pointer. Each time Qp0lProcessSubtree() regains control from the exit program, it determines whether the search should continue or end by evaluating the Err_recovery_actions parameter, its Selection status pointer, and the Return value pointer. Upon ending, Qp0lProcessSubtree() returns 0 to indicate a successful search, or a -1 and an errno to indicate the error condition. This errno may have been set by the exit program (Return value pointer).
This error recovery design allows for flexibility in handling errors between the caller, the API, and the exit program. Whenever an unrecoverable error occurs, if possible, the exit program is given a final call; this call allows the exit program to do such tasks as cleanup or to put information in the function control block, or to record information about the error. However, the exit program cannot decide that the search should continue. The API will return to its caller when it regains control. There are three instances in which the API determines that the exit program is not called:
- When the API cannot resolve the exit program name or its authorization.
- When input parameters are missing or specified incorrectly. (The API returns EINVAL to the caller before any other processing.)
- When the API encounters an unexpected exception or an internal processing error.
Following is a diagram showing the flow and relationship of these parameters.
- Symbolic links
Scenarios
Following are scenarios showing calls and the results of calls to Qp0lProcessSubtree(). Directory Structure A and Directory Structure B define the input directory structure for these scenarios.
Figure: Directory Structure A
This directory structure represents three subdirectories (a, b, c), three objects (x, y, z), and a symbolic link (t).
Figure: Directory Structure B
This directory structure represents six subdirectories (a, b, c, d, e, f) and seven objects (t, u, v, w, x, y, z).
Scenario 1
This scenario assumes processing a directory as shown by Directory Structure A in Figure above.
This scenario shows a call to the API without any criteria to filter the
selection of objects in the path being searched. If the API call were coded
with the parameter values as shown by Input value in Scenario 1 API Input, the exit program would be called nine
times and would pass the object names as shown by the Object Name
Pointer in Results of a call. Because
QP0L_SUBTREE_YES is specified, all of the directories in the path will be
opened and the name of all the objects that they contain will be passed to the
exit program. Note that the only guaranteed order is that parent directories
are passed to the exit program after all of their children.
Figure: Scenario 1 API Input
Input Parameter | Input value |
---|---|
*Path_Name | '/' ('/' processes every directory on the system and is not recommended if performance is a consideration) |
Subtree_level | QP0L_SUBTREE_YES |
*Objtypes_array_ptr | NULL |
Local_remote_obj | QP0L_LOCAL_REMOTE_OBJ |
*IN_EXclusion_ptr | NULL |
Err_recovery_action | QP0L_PASS_WITH_ERRORID |
*UserFunction_ptr | QP0L_USER_FUNCTION_PTR |
*Function_CtlBlk_ptr | NULL |
Figure: Results of a call
Exit Program Call Count | Object Name Pointer |
---|---|
1 | /a/b/y |
2 | /a/b |
3 | /a/x |
4 | /a/t |
5 | /a/c/z |
6 | /a/c |
7 | /a |
8 | / |
9 | NULL path name (indicates the API completed) |
Scenario 2
This scenario assumes processing a directory as shown by Directory Structure A in the Figure above.
This shows a call to the API with the Subtree level parameter set to retrieve only one level, without any object filtering. Since QP0L_SUBTREE_NO is specified, the names of all objects in the path will be passed to the exit program, however, none of the directories will be opened. This allows a caller to perform tasks such as identifying all of the root objects for a file system. For example, this would identify all of the first level folders, when processing against the QDLS file system. Then the API can be called recursively from within the exit program, with each of these folders specified as the path to be searched.
If the API call were coded with the parameter values as shown by Input
value in Scenario 2 API Input, the exit program
would be called six times and would pass the object names as shown by the
Object Name Pointer in Results of a call.
Figure: Scenario 2 API Input
Input Parameter | Input value |
---|---|
*Path_Name | '/a' |
Subtree_level | QP0L_SUBTREE_NO |
*Objtypes_array_ptr | NULL |
Local_remote_obj | QP0L_LOCAL_REMOTE_OBJ |
*IN_EXclusion_ptr | NULL |
Err_recovery_action | QP0L_PASS_WITH_ERRORID |
*UserFunction_ptr | QP0L_USER_FUNCTION_PTR |
*Function_CtlBlk_ptr | NULL |
Figure: Results of a call
Exit Program Call Count | Object Name Pointer |
---|---|
1 | /a/b |
2 | /a/x |
3 | /a/t |
4 | /a/c |
5 | /a |
6 | NULL path name (indicates the API completed) |
Scenario 3
This scenario assumes processing a directory as shown by Directory Structure B in the Figure above.
This scenario represents a call to the API with an inclusion list. Note that the Path Name parameter is not used as the starting directory since each entry in an inclusion list is treated as a starting directory.
If the API call were coded with the parameter values as shown by Input value in Scenario 3 API Input, the exit program would be called six times and would pass the object names as shown by the Object Name Pointer in Results of a call.
Note that /a/b/c/d/v could be returned before /a/b/c/d/u, as shown in this scenario, since children in a directory can be returned in any order. The only guaranteed order is that the exit program is called with all children objects before being called with the parent to allow the exit program to delete directories if desired.
Figure: Scenario 3 API Input
Input Parameter | Input value |
---|---|
*Path_Name | NULL (not used with an inclusion list) |
Subtree_level | QP0L_SUBTREE_YES |
*Objtypes_array_ptr | '*DIR ' '*STMF ' |
Local_remote_obj | QP0L_LOCAL_OBJ |
*IN_EXclusion_ptr | QP0L_INCLUSION_TYPE, '/a/b/c/d/' '/a/b/c/e/' |
Err_recovery_action | QP0L_PASS_WITH_ERRORID |
*UserFunction_ptr | QP0L_USER_FUNCTION_PTR |
*Function_CtlBlk_ptr | NULL |
Figure: Results of a call
Exit Program Call Count | Object Name Pointer |
---|---|
1 | /a/b/c/d/v |
2 | /a/b/c/d/u |
3 | /a/b/c/d |
4 | /a/b/c/e/w |
5 | /a/b/c/e/ |
6 | NULL path name (indicates the API completed) |
Scenario 4
This scenario assumes processing a directory as shown by Directory Structure B in the Figure above.
This scenario represents a call to the API with an exclusion list. Note that each relative entry in the exclusion list is resolved relative to the current working directory at the time the API is called. This scenario assumes that the current working directory is /a/b/.
If the API call were coded with the parameter values as shown by Input value in Scenario 4 API Input, the exit program would be called eight times and would pass the object names as shown by the Object Name Pointer in Results of a call.
This scenario also shows that children in a directory can be returned in any order. The only guaranteed order is that the exit program is called with all children objects before being called with the parent to allow the exit program to delete directories if desired.
Figure: Scenario 4 API Input
Input Parameter | Input value |
---|---|
*Path_Name | '/a/b/' |
Subtree_level | QP0L_SUBTREE_YES |
*Objtypes_array_ptr | '*DIR ' '*STMF ' |
Local_remote_obj | QP0L_LOCAL_OBJ |
*IN_EXclusion_ptr | QP0L_EXCLUSION_TYPE, 'c/d/' 'c/e/' |
Err_recovery_action | QP0L_PASS_WITH_ERRORID |
*UserFunction_ptr | QP0L_USER_FUNCTION_PTR |
*Function_CtlBlk_ptr | NULL |
Figure: Results of a call
Exit Program Call Count | Object Name Pointer |
---|---|
1 | /a/b/t |
2 | /a/b/c/y |
3 | /a/b/c/f/z |
4 | /a/b/c/f |
5 | /a/b/c/x |
6 | /a/b/c |
7 | /a/b |
8 | NULL path name (indicates the API completed) |
Related Information
- The <Qp0lstdi.h> file (see Header Files for UNIX®-Type Functions)
- The <qlg.h> file (see Header Files for UNIX-Type Functions)
- QlgProcessSubtree()--Process a Path Name (using NLS-enabled path name)
- Process a Path Name Exit Program
Example
The following example shows a call to the Qp0lProcessSubtree() API with a procedure as the exit program.
Note: By using the code examples, you agree to the terms of the Code license and disclaimer information.
/*****************************************************************/ /*****************************************************************/ #include <Qp0lstdi.h> #include <stdio.h> #include <errno.h> #include <qtqiconv.h> void Obj_Print_Function (uint *Selection_status_pointer, uint *Error_value_pointer, uint *Return_value_pointer, Qlg_Path_Name_T *Object_name_pointer, void *Function_control_block_pointer) { /****************************************************************/ /* This exit program example prints the names, one at a time, */ /* of each entry in a directory structure that it receives on */ /* each call from Qp0lProcessSubtree(). */ /****************************************************************/ #define PATH_TYPE_POINTER 0x00000001 /* If this flag is on, */ /* the qlg structure contains a */ /* pointer to the path name. */ /* Otherwise, the path name is in */ /* contiguous storage within the */ /* qlg structure. */ typedef union pn_input_type { char pn_char_type[256]; /* path name is in */ /* contiguous storage */ char *pn_ptr_type; /* path name is a pointer */ }; typedef struct pnstruct { Qlg_Path_Name_T qlg_struct; union pn_input_type pn; }; struct pnstruct *pns; char *path_ptr; size_t insz; size_t outsz = 1000; char outbuf[1000]; char *outbuf_ptr; iconv_t cd; size_t ret_iconv; QtqCode_T toCode; QtqCode_T fromCode; memset(&toCode, 0x00, sizeof(toCode)); memset(&fromCode, 0x00, sizeof(fromCode)); if (*Selection_status_pointer == QP0L_SELECT_OK) { if (Object_name_pointer != NULL) { toCode.CCSID = 37; fromCode.CCSID = Object_name_pointer->CCSID; /************************************************************/ /* Point to the pathname and get the size of the pathname */ /* that was sent from the Qp0lProcessSubtree() API. The */ /* format of the pathname must be determined by evaluating */ /* Path_Type in the qlg structure. */ /************************************************************/ pns = (struct pnstruct *)Object_name_pointer; if (Object_name_pointer->Path_Type & PATH_TYPE_POINTER) { path_ptr = pns->pn.pn_ptr_type; } else { path_ptr = (char *)(pns->pn.pn_char_type); } insz = pns->qlg_struct.Path_Length; /************************************************************/ /* Initialize the print buffer. */ /************************************************************/ outbuf_ptr = (char *)outbuf; memset(outbuf_ptr, 0x00, insz); /************************************************************/ /* Use iconv to convert from 61952 to the job CCSID. */ /* REMEMBER iconv will change the data that it receives. */ /************************************************************/ cd = /* Open the conversion descriptor.*/ QtqIconvOpen(&toCode, &fromCode); if (cd.return_value == -1) { /*********************************************************/ /* If conversion descriptor was not opened successfully, */ /* return an error and errno (ECONVERT) to the API. */ /*********************************************************/ *Return_value_pointer = errno; return; } ret_iconv = /* Perform the conversion.*/ (iconv(cd, (char **)&(path_ptr), &insz, (char **)&(outbuf_ptr), &outsz)); if (ret_iconv != 0) { /*********************************************************/ /* If the conversion failed, close the conversion */ /* descriptor and return an error and errno (ECONVERT) */ /* to the API. */ /*********************************************************/ ret_iconv= iconv_close(cd); *Return_value_pointer = errno; return; } /************************************************************/ /* Print the name of the object being processed and close */ /* the conversion descriptor. */ /************************************************************/ printf("In User Exit Program. Path is %s.\n", outbuf); ret_iconv = iconv_close(cd); } /* end Object_name_pointer != NULL */ else { printf("In User Exit Program with a null Pathname \n"); } } /* end *Selection_status_pointer == QP0L_SELECT_OK */ *Return_value_pointer = 0; } /* end Exit program */ int main (int argc, char *argv[]) { #define MYPN "/TestDir" const int zero = 0; const char US_const[3]= "US"; const char Language_const[4]="ENU"; const char Path_Name_Del_const[2]= "/"; const char LibObj_const[12]= "*LIB "; typedef struct pnstruct { Qlg_Path_Name_T qlg_struct; char pn[50]; /* Must be greater than */ /* or equal the length */ /* of the path name. */ }; struct pnstruct pns; Qp0l_Objtypes_List_t MyObj_types; Qp0l_User_Function_t User_function; struct { uint AnyData_to_the_exitprogram; uint AnyData_not_processed_by_the_API; } CtlBlkAreaName; int rc; /***************************************************************/ /* In this example, the pathname is defined by MYPN as TestDir */ /* and it is assumed that the TestDir directory exists on the */ /* system. Various other functions or other routines could be */ /* included here to (for example): */ /* 1) determine the beginning search directory. */ /* 2) construct the path name in the correct format. */ /* 3) others... */ /***************************************************************/ /***************************************************************/ /***************************************************************/ /* Initialize Qp0lProcessSubtree() API Parameters */ /***************************************************************/ memset((void*)&pns, 0x00, sizeof(struct pnstruct)); pns.qlg_struct.CCSID = 37; memcpy(pns.qlg_struct.Country_ID,US_const,2); memcpy(pns.qlg_struct.Language_ID,Language_const,3); pns.qlg_struct.Path_Type = zero; pns.qlg_struct.Path_Length = sizeof(MYPN)-1; memcpy(pns.qlg_struct.Path_Name_Delimiter,Path_Name_Del_const,1); memcpy(pns.pn,MYPN,sizeof(MYPN)); MyObj_types.Number_Of_Objtypes = zero; memset((void *)&User_function, 0x00, sizeof(Qp0l_User_Function_t)); User_function.Function_Type = QP0L_USER_FUNCTION_PTR; User_function.Mltthdacn[0] = QP0L_MLTTHDACN_NOMSG; User_function.Procedure = &Obj_Print_Function; if (rc = Qp0lProcessSubtree((Qlg_Path_Name_T *)&pns, QP0L_SUBTREE_YES, (Qp0l_Objtypes_List_t *)NULL, QP0L_LOCAL_REMOTE_OBJ, (Qp0l_IN_EXclusion_List_t *)NULL, QP0L_PASS_WITH_ERRORID, &User_function, &CtlBlkAreaName) == 0) { printf("Qp0lProcessSubtree() Successful : error = %d\n", errno); } else {/*unsuccessful return from Qp0lProcessSubtree() API */ printf("ERROR on Qp0lProcessSubtree(): error = %d\n", errno); perror("Error message"); } } /* end main */
API introduced: V4R3