Changeset 2424


Ignore:
Timestamp:
Oct 26, 2005, 11:32:29 PM (20 years ago)
Author:
bird
Message:

Implemented getdirents().

Location:
trunk/src/emx
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/emx/ChangeLog.LIBC

    r2423 r2424  
    22
    33TODO: open replace on RAMFS fails with error 32!
     4
     52005-10-26: knut st. osmundsen <bird-gccos2-spam@anduin.net>
     6    - libc:
     7        o Implemented getdirents().
    48
    592005-09-26: knut st. osmundsen <bird-gccos2-spam@anduin.net>
  • trunk/src/emx/include/InnoTekLIBC/backend.h

    r2423 r2424  
    447447 */
    448448int __libc_Back_ioFileSizeSet(int fh, __off_t cbFile, int fZero);
     449
     450/**
     451 * Reads directory entries from an open directory.
     452 *
     453 * @returns Number of bytes read.
     454 * @returns Negative error code (errno.h) on failure.
     455 *
     456 * @param   fh      The file handle of an open directory.
     457 * @param   pvBuf   Where to store the directory entries.
     458 *                  The returned data is a series of dirent structs with
     459 *                  variable name size. d_reclen must be used the offset
     460 *                  to the next struct (from the start of the current one).
     461 * @param   cbBuf   Size of the buffer.
     462 * @param   poff    Where to store the lseek offset of the first entry.
     463 *
     464 */
     465ssize_t __libc_Back_ioDirGetEntries(int fh, void *pvBuf, size_t cbBuf, __off_t *poff);
    449466
    450467/**
  • trunk/src/emx/include/dirent.h

    r2423 r2424  
    128128/** @todo DIR   *__opendir2(const char *, int); */
    129129/** @todo int    alphasort(const void *, const void *); */
    130 /** @todo int    getdents(int, char *, int); */
    131 /** @todo int    getdirentries(int, char *, int, long *); */
     130int      getdents(int, char *, int);
     131int      getdirentries(int, char *, int, long *);
    132132#endif
    133133DIR     *opendir(const char *);
  • trunk/src/emx/src/lib/libc.def

    r2423 r2424  
    19501950    "___libc_Back_fsDirCurrentSetFH" @1948
    19511951    "__std_fchdir" @1949
     1952    "___libc_Back_ioDirGetEntries" @1950
     1953    "__std_getdirents" @1951
  • trunk/src/emx/src/lib/sys/b_dir.c

    r2423 r2424  
    4444#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_IO
    4545#include <InnoTekLIBC/logstrict.h>
     46#include <InnoTekLIBC/libc.h>
    4647
    4748
     
    132133static int dirRead(__LIBC_PFH pFH, int fh, void *pvBuf, size_t cbRead, size_t *pcbRead)
    133134{
    134     /** @todo */
    135     return -ENOSYS;
     135    LIBCLOG_ENTER("pFH=%p fh=%d pvBuf=%p cbRead=%d pcbRead=%p\n", (void *)pFH, fh, pvBuf, cbRead, (void *)pcbRead);
     136    if (cbRead >= sizeof(struct dirent))
     137    {
     138        ssize_t cb = __libc_back_dirGetEntries((__LIBC_PFHDIR)pFH, pvBuf, cbRead);
     139        if (cb >= 0)
     140        {
     141            *pcbRead = cb;
     142            LIBCLOG_RETURN_INT(0);
     143        }
     144        LIBCLOG_ERROR_RETURN_INT(cb);
     145    }
     146    LIBCLOG_ERROR_RETURN_INT(-EOVERFLOW); /* not a proper read error, but it's the best I can think of for this situation. */
    136147}
    137148
     
    308319    return 0;
    309320}
    310 
    311 
    312 
    313 int __libc_Back_dirOpen(const char *pszPath);
    314321
    315322
     
    509516}
    510517
     518
     519
     520/**
     521 * Reads directory entries.
     522 *
     523 * @returns Number of bytes read.
     524 * @returns Negative error code (errno.h) on failure.
     525 *
     526 * @param   fh      The file handle of an open directory.
     527 * @param   pvBuf   Where to store the directory entries.
     528 *                  The returned data is a series of dirent structs with
     529 *                  variable name size. d_reclen must be used the offset
     530 *                  to the next struct (from the start of the current one).
     531 * @param   cbBuf   Size of the buffer.
     532 *
     533 */
     534ssize_t __libc_back_dirGetEntries(__LIBC_PFHDIR pFHDir, void *pvBuf, size_t cbBuf)
     535{
     536    /* prepare the native path */
     537    char szNativePath[PATH_MAX + 5];
     538    size_t cch = strlen(pFHDir->Core.pszNativePath);
     539    memcpy(szNativePath, pFHDir->Core.pszNativePath, cch);
     540    szNativePath[cch++] = '/';
     541
     542    /* copy data */
     543    ssize_t cbRet = 0;
     544    while (cbBuf >= sizeof(struct dirent))
     545    {
     546        /*
     547         * Fill the buffer?
     548         */
     549        if (pFHDir->cFiles <= 0)
     550        {
     551            FS_VAR_SAVE_LOAD();
     552            pFHDir->cFiles = pFHDir->cbBuf / 40;
     553#if OFF_MAX > LONG_MAX
     554            if (pFHDir->fType == FIL_QUERYEASIZEL)  /* the L version is buggy!! Make sure there is enough space. */
     555                pFHDir->cFiles = pFHDir->cbBuf / sizeof(FILEFINDBUF4L);
     556#endif
     557            pFHDir->uCur.pv = pFHDir->uBuf.pv;
     558
     559            int rc = DosFindNext(pFHDir->hDir,
     560                                 pFHDir->uBuf.pv,
     561                                 pFHDir->cbBuf,
     562                                 &pFHDir->cFiles);
     563            FS_RESTORE();
     564            if (rc)
     565            {
     566                /** @todo verify that ERROR_NO_MORE_FILES is returned repeatedly. */
     567                if (!cbRet && rc != ERROR_NO_MORE_FILES)
     568                    cbRet = -__libc_native2errno(rc);
     569                pFHDir->cFiles = 0;
     570                break;
     571            }
     572            LIBC_ASSERT(pFHDir->cFiles);
     573            if (!pFHDir->cFiles) /* paranoia */
     574                break;
     575        }
     576
     577        /*
     578         * Fill the return buffer.
     579         */
     580        struct dirent *pDir = (struct dirent *)pvBuf;
     581        pDir->d_reclen = sizeof(struct dirent);
     582        pDir->d_type = DT_UNKNOWN;
     583        pDir->d_fileno = -1; /** @todo */
     584        int fMayHaveEAs;
     585        if (__predict_true(pFHDir->fType == FIL_QUERYEASIZEL))
     586        {
     587            fMayHaveEAs = pFHDir->uCur.p4L->cbList > sizeof(USHORT) * 2 + 1;
     588            if (pFHDir->uCur.p4L->attrFile & FILE_DIRECTORY)
     589                pDir->d_type = DT_DIR;
     590            pDir->d_namlen = pFHDir->uCur.p4L->cchName;
     591            memcpy(&pDir->d_name[0], &pFHDir->uCur.p4L->achName[0], pDir->d_namlen);
     592        }
     593        else
     594        {
     595            LIBC_ASSERT(pFHDir->fType == FIL_QUERYEASIZE);
     596            fMayHaveEAs = pFHDir->uCur.p4->cbList > sizeof(USHORT) * 2 + 1;
     597            if (pFHDir->uCur.p4->attrFile & FILE_DIRECTORY)
     598                pDir->d_type = DT_DIR;
     599            pDir->d_namlen = pFHDir->uCur.p4->cchName;
     600            memcpy(&pDir->d_name[0], &pFHDir->uCur.p4->achName[0], pDir->d_namlen);
     601        }
     602        pDir->d_name[pDir->d_namlen] = '\0';
     603
     604        /*
     605         * Get unix attributes mode and ino, try EAs first.
     606         */
     607        memcpy(&szNativePath[cch], pDir->d_name, pDir->d_namlen + 1);
     608        if (fMayHaveEAs)
     609        {
     610            if (!__libc_gfNoUnix)
     611            {
     612                /** @todo */
     613                /** @todo */
     614                fMayHaveEAs = 0;
     615            }
     616            else
     617                fMayHaveEAs = 0;
     618        }
     619        if (!fMayHaveEAs)
     620        {
     621            ino_t Inode; /** @todo use d_ino directly when we've corrected the structure. */
     622            __libc_back_fsPathCalcInodeAndDev(szNativePath, &Inode);
     623            pDir->d_fileno = Inode;
     624            if (pDir->d_type == DT_UNKNOWN)
     625                pDir->d_type = DT_REG;
     626        }
     627
     628        /*
     629         * Advance buffers.
     630         */
     631        cbBuf -= sizeof(struct dirent);
     632        cbRet += sizeof(struct dirent);
     633        pvBuf = (char *)pvBuf + sizeof(struct dirent);
     634        pFHDir->cFiles--;
     635        pFHDir->uCur.pu8 += pFHDir->uCur.p4->oNextEntryOffset;
     636    }
     637    return cbRet;
     638}
     639
  • trunk/src/emx/src/lib/sys/b_dir.h

    r2423 r2424  
    7575int __libc_back_dirInherit(int fh, const char *pszNativePath, unsigned fInUnixTree, unsigned fFlags,
    7676                           ino_t Inode, dev_t Dev, unsigned uCurEntry);
    77 
     77ssize_t __libc_back_dirGetEntries(__LIBC_PFHDIR pFHDir, void *pvBuf, size_t cbBuf);
    7878
    7979#endif
  • trunk/src/emx/src/lib/sys/b_ioFileOpen.c

    r2423 r2424  
    198198                    rc = __libc_Back_dirOpenNative(szNativePath, fInUnixTree, fLibc, &st);
    199199                    if (rc >= 0)
     200                    {
     201                        if (ppFH)
     202                            *ppFH = __libc_FH(rc);
    200203                        LIBCLOG_RETURN_INT(rc);
     204                    }
    201205                    LIBCLOG_ERROR_RETURN_INT(rc);
    202206                    break;
Note: See TracChangeset for help on using the changeset viewer.