Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Developer
Posts: 93
Registered: ‎05-31-2012
My Device: BlackBerry Playbook
My Carrier: Bell
Accepted Solution

dirent extra data always invalid?

Hello BB NDK devs,

 

The dirent structure provided by the BB C libs is documented as having stat data stored in the extra data, accessible and iteratable via:

 

for( dirent_extra* extra = _DEXTRA_FIRST(dp); _DEXTRA_VALID(extra, dp) ); extra = _DEXTRA_NEXT(extra) )

{

////

}

 

However, _DEXTRA_FIRST never returns a valid extra block.

 

Are these not implemented in BB QNX? Or is something special required to enable them?

 

Thanks!

Developer
Posts: 1,068
Registered: ‎11-24-2011
My Device: PlayBook
My Carrier: x

Re: dirent extra data always invalid?

Can you post more code including how you open the dir?

Developer
Posts: 93
Registered: ‎05-31-2012
My Device: BlackBerry Playbook
My Carrier: Bell

Re: dirent extra data always invalid?

Hi BGMot,

 

Here is the code, including alternate implementation which we've used as a workaround (not using DIRENT_EXTRA_DATA) that works:

 

void Directory::GetContents( RT::Vector<TypedEntry>& rContents, const char* szDirPath )
{
    DIR* pDir = opendir(szDirPath);
    assert(pDir);

    dirent* dp;
    rContents.Reset();
    
    while((dp = readdir(pDir)) != NULL)
    {
        TypedEntry* pEntry = NULL;

#ifdef DIRENT_EXTRA_DATA
        dirent_extra* extra = _DEXTRA_FIRST(dp);
        while( _DEXTRA_VALID(extra, dp) )
        {
            if(extra->d_type == _DTYPE_LSTAT )
            {
                mode_t mode = ((dirent_extra_stat*)extra)->d_stat.st_mode;
#else
                char file[256];
                snprintf(file, sizeof(file), "%s/%s", szDirPath, dp->d_name);

                struct stat status;
                stat(file, &status);
                mode_t mode = status.st_mode;
#endif
                if( S_ISDIR(mode) )
                {
                    pEntry = &rContents.Acquire();
                    pEntry->type = TypedEntry:Smiley Very HappyIR;
                }
                else
                if( S_ISREG(mode) )
                {
                    pEntry = &rContents.Acquire();
                    pEntry->type = TypedEntry::FILE;
                }
#ifdef DIRENT_EXTRA_DATA
            }
            extra = _DEXTRA_NEXT(extra);
        }
#endif
        if( pEntry )
        {
            strcpy(pEntry->name, dp->d_name);
        }
    }
    closedir(pDir);
}

 

Thanks!

Retired
Posts: 499
Registered: ‎05-07-2012
My Device: developer
My Carrier: developer

Re: dirent extra data always invalid?

Did you enable the extra stat info?

 

I added the following to HelloWorldDisplay after the init() in main():

 

    DIR* dir = opendir(".");
    if (dir != 0)
    {
        printf("Yay!\n");
        int rc = dircntl(dir, D_GETFLAG);
        if (rc != -1)
        {
            if (rc & D_FLAG_STAT)
            {
                printf("Servers ARE asked for extra stat info\n");
            }
            else
            {
                printf("Servers are NOT asked for extra state info.  Enabling...\n");
                rc = dircntl(dir, D_SETFLAG, D_FLAG_STAT);
                if (rc == -1)
                {
                    printf("...enable failed\n");
                }
                else
                {
                    printf("...enable succeeded\n");
                }
            }
        }

        struct dirent* entry = 0;
        int count = 0;
        while ((entry = readdir(dir)) != 0)
        {
            ++count;
            printf("Yay!  found directory %s\n", entry->d_name);
            fflush(stdout);
            struct dirent_extra* extra = _DEXTRA_FIRST(entry);
            if (extra != 0)
            {
                printf("Yay! Extra!\n");
                for (;  _DEXTRA_VALID(extra, entry); extra = _DEXTRA_NEXT(extra) )
                {
                    printf("...%d byte%s of extra data\n", extra->d_datalen, (extra->d_datalen == 1)? "" : "s");
                }
            }
            else
                printf("Boo! No extra.\n");
        }
        printf("%d entr%s found.", count, (count==1)? "y" : "ies");
        closedir(dir);
    }
    else
    {
        printf("Boo!\n");
    }
    fflush(stdout);

This gives the following trace:

Yay!
Servers are NOT asked for extra state info.  Enabling...
...enable succeeded
Yay!  found directory .
Yay! Extra!
...72 bytes of extra data
Yay!  found directory ..
Yay! Extra!
...72 bytes of extra data
Yay!  found directory data
Yay! Extra!
...72 bytes of extra data
Yay!  found directory tmp
Yay! Extra!
...72 bytes of extra data
Yay!  found directory logs
Yay! Extra!
...72 bytes of extra data
Yay!  found directory pps
Yay! Extra!
Yay!  found directory db
Yay! Extra!
Yay!  found directory shared
Yay! Extra!
Yay!  found directory app
Yay! Extra!
9 entries found.

 

Stuart

Developer
Posts: 93
Registered: ‎05-31-2012
My Device: BlackBerry Playbook
My Carrier: Bell

Re: dirent extra data always invalid?

Thanks Stuart,

 

rc = dircntl(dir, D_SETFLAG, D_FLAG_STAT); is exactly what I was looking for. I realize I totally missed that little bit of info at the bottom of the extra data documentation. My bad!

 

Thanks again for the support!

Highlighted
Retired
Posts: 499
Registered: ‎05-07-2012
My Device: developer
My Carrier: developer

Re: dirent extra data always invalid?

np.

I wasn't aware of this extension (I'm primarily looking at Cascades), and it took me a while to notice it too.

 

Thanks for accepting the solution so quickly.