Skip to Main Content
IBM Power Ideas Portal


This portal is to open public enhancement requests against IBM Power Systems products, including IBM i. To view all of your ideas submitted to IBM, create and manage groups of Ideas, or create an idea explicitly set to be either visible by all (public) or visible only to you and IBM (private), use the IBM Unified Ideas Portal (https://ideas.ibm.com).


Shape the future of IBM!

We invite you to shape the future of IBM, including product roadmaps, by submitting ideas that matter to you the most. Here's how it works:

Search existing ideas

Start by searching and reviewing ideas and requests to enhance a product or service. Take a look at ideas others have posted, and add a comment, vote, or subscribe to updates on them if they matter to you. If you can't find what you are looking for,

Post your ideas
  1. Post an idea.

  2. Get feedback from the IBM team and other customers to refine your idea.

  3. Follow the idea through the IBM Ideas process.


Specific links you will want to bookmark for future use

Welcome to the IBM Ideas Portal (https://www.ibm.com/ideas) - Use this site to find out additional information and details about the IBM Ideas process and statuses.

IBM Unified Ideas Portal (https://ideas.ibm.com) - Use this site to view all of your ideas, create new ideas for any IBM product, or search for ideas across all of IBM.

ideasibm@us.ibm.com - Use this email to suggest enhancements to the Ideas process or request help from IBM for submitting your Ideas.

139 VOTE
Status Delivered
Workspace IBM i
Categories Db2 for i
Created by Guest
Created on Jun 16, 2016

DB2 service for IFS listing

I'd like to be able to get a list of IFS files within a directory using a DB2 service.

For example, to get the root directory:
SELECT * FROM TABLE(QSYS2.GET_IFS('/')) A

Which would return a list of stream files and directories within root.

For the home directory:
SELECT * FROM TABLE(QSYS2.GET_IFS('/home')) A


Use Case:

It would be easier to use embedded SQL within RPG instead of declaring multiple APIs to access a list of stream files and directories. Developers would be more efficient and saving a lot of time if they only had to use one statement instead of using different system APIs.


Idea priority Medium
  • Guest
    Reply
    |
    Nov 16, 2019

    QSYS2.IFS_OBJECT_STATISTICS() UDTF has been delivered to IBM i 7.3 and 7.4.

  • Guest
    Reply
    |
    Oct 7, 2019

    The question which needs to be answered is: When there is a valid workaround by using RPG or other tooling which require extra skills do we all see it as a valid solution for all IBM i users who could benefit from the functionality asked in this RFE?

    Greetings Rudi

  • Guest
    Reply
    |
    Oct 4, 2019

    I find it disheartening that this has been under consideration by IBM for nearly two years.

  • Guest
    Reply
    |
    Nov 5, 2018

    This is something that can easily be written by yourself if you're used to the IFS API's. If not, have a look at Scott Klement his examples for IFS processing.

  • Guest
    Reply
    |
    Jan 29, 2018

    The CEAC has reviewed this requirement and recommends that IBM view this as a medium priority requirement that should be addressed. The CEAC feels that if IBM could more quickly provide a simpler solution that can be built upon in the future, that would be preferable.

    Background: The COMMON Europe Advisory Council (CEAC) members have a broad range of experience in working with small and medium-sized IBM i customers. CEAC has a key role in working with IBM i development to help assess the value and impact of individual RFEs on the broader IBM i community, and has therefore reviewed your RFE.

    For more information about CEAC, see http://www.comeur.org/i4a/pages/index.cfm?pageid=3285

    Dawn May - CEAC Program Manager

  • Guest
    Reply
    |
    Nov 14, 2017

    I wrote this a few years ago and it works great. My UDTF name is IFSDIR(,[recursion]).
    It is included in our SQLiQuery.com product for IBM i, but you can probably request that it be "open sourced".

  • Guest
    Reply
    |
    Oct 27, 2017

    IBM has received the requirement and is evaluating it. IBM will provide a response after evaluation is complete.

  • Guest
    Reply
    |
    Sep 18, 2017

    I'm searching and finding examples to do this in RPG. A DB2 Service would have solved my problem instantly.

  • Guest
    Reply
    |
    Jul 18, 2017

    The CAAC has reviewed this requirement and recommends that IBM view this as a medium priority requirement that should be addressed.

    While there are alternatives available as expressed in prior comments, the CAAC felt this support would be best provided as an integrated part of the operating system. With this being part of the operating system, the feature can be used stand-alone without additional code being added to the system; this is an important aspect for small clients being able to embrace modern features.

    Background: The COMMON Americas Advisory Council (CAAC) members have a broad range of experience in working with small and medium-sized IBM i customers. CAAC has a key role in working with IBM i development to help assess the value and impact of individual RFEs on the broader IBM i community, and has therefore reviewed your RFE.

    For more information about CAAC, see www.common.org/caac

    For more details about CAAC's role with RFEs, see http://www.ibmsystemsmag.com/Blogs/i-Can/May-2017/COMMON-Americas-Advisory-Council-%28CAAC%29-and-RFEs/

    Dawn May - CAAC Program Manager

  • Guest
    Reply
    |
    Jul 11, 2017

    This is something that you can easily write yourself (like most of the DB2 services).

    For me this is a waste of IBM resources which are better invested on things you can't write yourself.

  • Guest
    Reply
    |
    Mar 21, 2017

    It would be a big plus if this service had an option to control whether the last accessed timestamp was updated when using it.

  • Guest
    Reply
    |
    Jun 24, 2016

    One such UDTF to read the IFS was published by RPG guru Scott Klement nine(!) years ago in 2007. Later this UDTF was updated in 2010 to include creation timestamp and check_out status.

    Source code:

    * Sample UDTF to read an IFS directory.
    * Scott Klement 05/24/2007
    *
    * To compile:
    * - first make sure the IFSIO_H copybook is in a QRPGLESRC
    * file in your library list.
    * - Also verify that the QLG_H and QP0LSTDI_H copy books
    * are in a QRPGLESRC file in your library list
    * *> CRTRPGMOD IFSDIR SRCFILE(QRPGLESRC) DBGVIEW(*LIST)
    * *> CRTSRVPGM IFSDIR EXPORT(*ALL)
    * - Run the CRTIFSDIR program (see that member for details)
    *
    * To call:
    * This is run from an SQL SELECT statement. See the
    * IFSDIRDEMO member for an example.
    *
    *
    H THREAD(*SERIALIZE) BNDDIR('QC2LE')

    /copy qp0lstdi_h

    D ifsdir pr extpgm('IFSDIR')
    D dirname 500A varying const
    D filename 640A varying
    D size 20p 0
    D type 10a varying
    D btime Z
    D atime Z
    D mtime Z
    D ctime Z
    D ccsid 5p 0
    D owner 10a
    D groupx 10a
    D chkusr 10a
    D n_dirname 5i 0
    D n_filename 5i 0
    D n_size 5i 0
    D n_type 5i 0
    D n_btime 5i 0
    D n_atime 5i 0
    D n_mtime 5i 0
    D n_ctime 5i 0
    D n_ccsid 5i 0
    D n_owner 5i 0
    D n_group 5i 0
    D n_chkusr 5i 0
    D Sql_State 5a
    D Function 517a varying const
    D Specific 128a varying const
    D MsgText 70a varying
    D CallType 10i 0 const
    D ifsdir pi
    ** ------ input parameter -----
    D dirname 500A varying const
    ** ------ one record (row) of result -----
    D filename 640A varying
    D size 20p 0
    D type 10a varying
    D btime Z
    D atime Z
    D mtime Z
    D ctime Z
    D ccsid 5p 0
    D owner 10a
    D groupx 10a
    D chkusr 10a
    ** ------ null ind for input parm -----
    D n_dirname 5i 0
    ** ------ null ind for output (row) -----
    D n_filename 5i 0
    D n_size 5i 0
    D n_type 5i 0
    D n_btime 5i 0
    D n_atime 5i 0
    D n_mtime 5i 0
    D n_ctime 5i 0
    D n_ccsid 5i 0
    D n_owner 5i 0
    D n_group 5i 0
    D n_chkusr 5i 0
    ** ------ Stuff used to interface w/ SQL ------
    D Sql_State 5a
    D Function 517a varying const
    D Specific 128a varying const
    D MsgText 70a varying
    D CallType 10i 0 const

    /copy ifsio_h

    D Open_Event PR
    D Fetch_Event PR
    D Close_Event PR

    D sys_errno PR * ExtProc('__errno')
    D errno s 10i 0 based(p_errno)
    D strerror PR * ExtProc('strerror')
    D errnum 10I 0 value

    D CALL_STARTUP C CONST(-2)
    D CALL_OPEN C CONST(-1)
    D CALL_FETCH C CONST(0)
    D CALL_CLOSE C CONST(1)
    D CALL_FINAL C CONST(2)

    D PARM_NULL C CONST(-1)
    D PARM_NOTNULL C CONST(0)

    D Epoch s z
    D dirh s *

    /free

    // -----------------------------------------
    // Verify that we received a directory name.
    // without that, there's nothing to be done.
    // -----------------------------------------

    if (n_dirname = PARM_NULL);
    SQL_State = '38999';
    MsgText = 'Directory name is required';
    return;
    endif;

    // -----------------------------------------
    // Start all fields at NULL.
    // -----------------------------------------

    n_filename = PARM_NULL;
    n_size = PARM_NULL;
    n_atime = PARM_NULL;
    n_mtime = PARM_NULL;
    n_ctime = PARM_NULL;
    n_type = PARM_NULL;
    n_ccsid = PARM_NULL;
    n_owner = PARM_NULL;
    n_group = PARM_NULL;
    n_btime = PARM_NULL;
    n_chkusr = PARM_NULL;

    // -----------------------------------------
    // Open, Fetch & Close IFS directory stuff
    // -----------------------------------------

    select;
    when CallType = CALL_OPEN; // CALL_OPEN = -1
    Open_Event();

    when CallType = CALL_FETCH; // CALL_FETCH = 0
    Fetch_Event();

    when CallType = CALL_CLOSE; // CALL_CLOSE = 1
    Close_Event();

    endsl;

    return;
    /end-free


    *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    * Open_Event(): This is called when SQL tells us to "open"
    * the "table" that we're going to return.
    * We use it for opening the directory.
    *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    P Open_Event B
    D Open_Event PI

    D CEEUTCO PR opdesc
    D Hours 10I 0
    D Minutes 10I 0
    D Seconds 8F
    D fc 12A options(*omit)

    D junk1 s 10i 0
    D junk2 s 10i 0
    D secs s 8f

    /free
    monitor;
    exsr getEpoch;
    exsr openIfsDir;
    on-error;
    endmon;

    return;

    // ----------------------------------------------
    // All Unix API timestamps are supplied as a count
    // of the number of seconds since the "epoch"
    // (which is defined as midnight, Jan 1, 1970 UTC)
    //
    // Since the epoch is in the UTC time zone, we
    // will need to adjust it for the local computer's
    // time... To get the adjustment, use CEEUTCO.
    // ----------------------------------------------
    begsr getEpoch;
    CEEUTCO(junk1: junk2: secs: *omit);
    Epoch = z'1970-01-01-00.00.00.000000'
    + %seconds(%int(secs));
    endsr;


    // ----------------------------------------------
    // Open the IFS directory
    // ----------------------------------------------
    begsr openIfsDir;
    dirh = opendir(%trim(dirname));
    if (dirh = *null);
    p_errno = sys_errno();
    MsgText = 'opendir: ' + %str(strerror(errno));
    SQL_State = '38998';
    endif;
    endsr;

    /end-free
    P E

    *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    * Fetch_Event(): This is called when SQL tells us to "fetch"
    * a record from the "table". We'll use it to
    * read each file from the directory.
    *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    P Fetch_Event B
    D Fetch_Event PI

    D Entry ds likeds(dirent)
    D based(p_entry)
    D path ds likeds(Qlg_Path_Name_t)
    D reqattr ds likeds(Qp0l_AttrTypes_List_t)
    D attr ds likeds(Qp0l_Attr_Header_t)
    D based(p_Attr)
    D buf s 65535A static
    D need s 10U 0
    D rtn s 10U 0

    D dataSize64 s 20u 0 based(p_dataSize64)
    D objType s like(qp0l_ObjType_t)
    D based(p_ObjType)
    D CheckedOut ds likeds(qp0l_Checkout_t)
    D based(p_CheckedOut)
    D Auth ds likeds(qp0l_Authority_General_t)
    D based(p_Auth)
    /free

    monitor;
    exsr getNextFile;
    exsr getFileInfo;
    on-error;
    endmon;

    return;

    // -------------------------------------------------
    // Get the next file name from the IFS directory
    // -------------------------------------------------
    begsr getNextFile;

    dou (filename<>'.' and filename<>'..');
    p_entry = readdir(dirh);
    if (p_entry = *null);
    SQL_State = '02000';
    return;
    endif;
    filename = %subst(entry.d_name:1:entry.d_namelen);
    enddo;

    n_filename = PARM_NOTNULL;
    endsr;

    // -------------------------------------------------
    // Now we need info about the file. Build a DS
    // describing the path name of the file, as well
    // as the information attributes to request
    // -------------------------------------------------
    begsr getFileInfo;

    path = *ALLx'00';
    path.Path_Name = %trim(dirname) + '/' + filename;
    path.Path_Name_delimiter = '/';
    path.Path_Length = %len(%trimr(path.Path_Name));

    reqattr.Number_of_ReqAttrs = 9;
    reqattr.attrTypes(1) = QP0L_ATTR_OBJTYPE;
    reqattr.attrTypes(2) = QP0L_ATTR_DATA_SIZE_64;
    reqattr.attrTypes(3) = QP0L_ATTR_CREATE_TIME;
    reqattr.attrTypes(4) = QP0L_ATTR_ACCESS_TIME;
    reqattr.attrTypes(5) = QP0L_ATTR_CHANGE_TIME;
    reqattr.attrTypes(6) = QP0L_ATTR_MODIFY_TIME;
    reqattr.attrTypes(7) = QP0L_ATTR_CHECKED_OUT;
    reqattr.attrTypes(8) = QP0L_ATTR_CCSID;
    reqattr.attrTypes(9) = QP0L_ATTR_AUTH;

    // -------------------------------------------------
    // Ask system for information about the file
    // -------------------------------------------------

    if (Qp0lGetAttr( path
    : reqattr
    : %addr(Buf)
    : %size(Buf)
    : need
    : rtn
    : QP0L_DONOT_FOLLOW_SYMLNK ) = -1);
    p_errno = sys_errno();
    MsgText = filename + ': ' + %str(strerror(errno));
    SQL_State = '38997';
    return;
    endif;

    // -------------------------------------------------
    // Parse the output from the API
    // -------------------------------------------------

    p_Attr = %addr(Buf);

    dow (p_Attr <> *null);

    select;
    when attr.Attr_ID = QP0L_ATTR_OBJTYPE;
    p_ObjType = %addr(attr.CharData);
    type = %trim(objtype);
    n_type = PARM_NOTNULL;

    when attr.Attr_ID = QP0L_ATTR_DATA_SIZE_64;
    p_DataSize64 = %addr(attr.CharData);
    size = DataSize64;
    n_size = PARM_NOTNULL;


    when attr.Attr_ID = QP0L_ATTR_CREATE_TIME;
    btime = epoch + %seconds(attr.unsData);
    n_btime = PARM_NOTNULL;

    when attr.Attr_ID = QP0L_ATTR_ACCESS_TIME;
    atime = epoch + %seconds(attr.unsData);
    n_atime = PARM_NOTNULL;

    when attr.Attr_ID = QP0L_ATTR_CHANGE_TIME;
    ctime = epoch + %seconds(attr.unsData);
    n_ctime = PARM_NOTNULL;

    when attr.Attr_ID = QP0L_ATTR_MODIFY_TIME;
    mtime = epoch + %seconds(attr.unsData);
    n_mtime = PARM_NOTNULL;

    when attr.Attr_ID = QP0L_ATTR_CHECKED_OUT;
    p_CheckedOut = %addr(attr.charData);
    if (CheckedOut.Checked_Out_Flag = QP0L_CHECKED_OUT);
    chkusr = CheckedOut.User_Name;
    n_chkusr = PARM_NOTNULL;
    else;
    chkusr = '';
    n_chkusr = PARM_NULL;
    endif;

    when attr.Attr_ID = QP0L_ATTR_CCSID;
    ccsid = attr.intData;
    n_ccsid = PARM_NOTNULL;

    when attr.Attr_ID = QP0L_ATTR_AUTH;
    p_Auth = %addr(attr.CharData);
    owner = Auth.Object_Owner;
    n_owner = PARM_NOTNULL;
    groupx = Auth.Primary_group;
    n_group = PARM_NOTNULL;
    endsl;

    if (attr.Next_Attr_Offset = 0);
    p_Attr = *NULL;
    else;
    p_Attr = %addr(Buf) + attr.Next_Attr_Offset;
    endif;

    enddo;
    endsr;

    /end-free
    P E

    *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    * Close_Event(): This is called when SQL tells us to "close"
    * our "table". We'll use it to close the dir
    *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    P Close_Event B
    D Close_Event PI
    /free
    monitor;
    callp closedir(dirh);
    on-error;
    endmon;
    return;
    /end-free
    P E

  • Guest
    Reply
    |
    Jun 17, 2016

    Creating a new RFE based on Community RFE #90136 in product IBM i.