Changeset 2924


Ignore:
Timestamp:
Dec 30, 2006, 4:59:44 AM (19 years ago)
Author:
bird
Message:

cleanup in progress (late night session)

Location:
trunk/libc
Files:
1 added
1 deleted
8 edited
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/libc/include/klibc/backend.h

    r2922 r2924  
    420420 * @returns Negative error code (errno.h) on failure.
    421421 * @param   fh      Handle to file.
    422  * @param   Mode    The filemode.
    423  */
    424 int __libc_Back_fsFileModeSetFH(int fh, mode_t Mode);
     422 * @param   fMode   The filemode.
     423 */
     424int __libc_Back_fsFileModeSetFH(int fh, mode_t fMode);
    425425
    426426/**
     
    429429 * @returns 0 on success.
    430430 * @returns Negative error code (errno.h) on failure.
    431  * @param   pszPath The path to the file to set the times of.
    432  * @param   paTimes Two timevalue structures. If NULL the current time is used.
     431 * @param   pszPath     The path to the file to set the times of.
     432 * @param   paTimes     The two time value structures, the first is the access time and the second
     433 *                      the modification time. If NULL the current time is used.
    433434 */
    434435int __libc_Back_fsFileTimesSet(const char *pszPath, const struct timeval *paTimes);
  • trunk/libc/include/klibc/io.h

    r2922 r2924  
    194194     */
    195195    int (*pfnIOControl)(struct __libc_FileHandle *pFH, unsigned long ulIOControl, va_list va, int *prc);
     196
     197    /**
     198     * Change the mode mask associated with the file (inode).
     199     *
     200     * @returns 0 on success.
     201     * @returns Negated error code (errno.h) on failure.
     202     * @param   pFH         Pointer to the handle structure to operate on.
     203     * @param   fMode       The new mode mask.
     204     */
     205    int (*pfnSetMode)(struct __libc_FileHandle *pFH, mode_t fMode);
     206
     207    /**
     208     * Change the owner of the file (inode).
     209     *
     210     * @returns 0 on success.
     211     * @returns Negated error code (errno.h) on failure.
     212     * @param   pFH         Pointer to the handle structure to operate on.
     213     * @param   uid         The id of the new owner.
     214     */
     215    int (*pfnSetOwner)(struct __libc_FileHandle *pFH, uid_t uid);
     216
     217    /**
     218     * Change the owner of the file (inode).
     219     *
     220     * @returns 0 on success.
     221     * @returns Negated error code (errno.h) on failure.
     222     * @param   pFH         Pointer to the handle structure to operate on.
     223     * @param   paTimes     The two time value structures, the first is the access time and the second
     224     *                      the modification time. If NULL the current time is used.
     225     */
     226    int (*pfnSetTimes)(struct __libc_FileHandle *pFH, const struct timeval *paTimes);
     227
     228    /**
     229     * Get file stats.
     230     *
     231     *
     232     * @returns 0 on success.
     233     * @returns Negated error code (errno.h) on failure.
     234     * @param   pFH         Pointer to the handle structure to operate on.
     235     * @param   pStat       Where to store the stat info.
     236     */
     237    int (*pfnStat)(struct __libc_FileHandle *pFH, struct stat *pStat);
    196238
    197239    /**
  • trunk/libc/src/kNIX/Makefile.kmk

    r2922 r2924  
    4040    $(PATH_LIBC_SRC)/kNIX/b_fsSymlinkCreate.c \
    4141    $(PATH_LIBC_SRC)/kNIX/b_fsFileTimesSet.c \
     42    $(PATH_LIBC_SRC)/kNIX/b_fsFileTimesSetFH.c \
    4243    $(PATH_LIBC_SRC)/kNIX/b_fsDirRemove.c \
    4344    $(PATH_LIBC_SRC)/kNIX/b_fsFileModeSet.c \
     45    $(PATH_LIBC_SRC)/kNIX/b_fsFileModeSetFH.c \
    4446    $(PATH_LIBC_SRC)/kNIX/b_fsFileStat.c \
     47    $(PATH_LIBC_SRC)/kNIX/b_fsFileStatFH.c \
    4548    $(PATH_LIBC_SRC)/kNIX/b_fsSymlinkRead.c \
    4649    $(PATH_LIBC_SRC)/kNIX/b_fsSymlinkStat.c \
     
    8487    $(PATH_LIBC_SRC)/kNIX/os2/b_fsDriveDefaultGet.c \
    8588    $(PATH_LIBC_SRC)/kNIX/os2/b_fsDriveDefaultSet.c \
    86     $(PATH_LIBC_SRC)/kNIX/os2/b_fsFileModeSetFH.c \
    87     $(PATH_LIBC_SRC)/kNIX/os2/b_fsFileStatFH.c \
    88     $(PATH_LIBC_SRC)/kNIX/os2/b_fsFileTimesSetFH.c \
    8989    $(PATH_LIBC_SRC)/kNIX/os2/b_fsNativeFileModeSet.c \
    9090    $(PATH_LIBC_SRC)/kNIX/os2/b_fsNativeFileStat.c \
  • trunk/libc/src/kNIX/b_fsFileStatFH.c

    r2914 r2924  
    22/** @file
    33 *
    4  * kNIX - fstat, OS/2.
     4 * kNIX - fstat.
    55 *
    66 * Copyright (c) 2003-2005 knut st. osmundsen <bird-src-spam@anduin.net>
     
    4343
    4444    /*
    45      * Get filehandle.
     45     * Get filehandle and do the job.
    4646     */
    4747    __LIBC_PFH pFH;
    4848    int rc = __libc_FHGet(fh, &pFH);
    49     if (rc)
    50         LIBCLOG_ERROR_RETURN_INT(rc);
    51 
    52     const int fUnixEAs = pFH->pFsInfo && pFH->pFsInfo->fUnixEAs;
    53     if (/*!pFH->pOps*/ 1)
     49    if (!rc)
    5450    {
    5551        /*
    56          * Use query handle type to figure out the file type.
     52         * Do the job and log the result.
    5753         */
    58         bzero(pStat, sizeof(*pStat));
    59         /* fake unix stuff */
    60         //pStat->st_uid = 0;
    61         //pStat->st_gid = 0;
    62         pStat->st_ino = pFH->Inode;
    63         pStat->st_dev = pFH->Dev;
    64         //pStat->st_rdev = 0;
    65         pStat->st_nlink = 1;
    66         pStat->st_blksize = 4096*12; /* 48KB */
    67 
    68         if ((pFH->fFlags & __LIBC_FH_TYPEMASK) == F_FILE)
     54        rc = pFH->pOps->pfnStat(pFH, pStat);
     55        __libc_FHPut(pFH);
     56        if (!rc)
    6957        {
    70             /*
    71              * Regular OS/2 file.
    72              */
    73             union
    74             {
    75                 FILESTATUS4     fsts4;
    76                 FILESTATUS4L    fsts4L;
    77             } info;
    78 #if OFF_MAX > LONG_MAX
    79             int     fLarge = 0;
    80 #endif
    81             pStat->st_mode = S_IFREG;
    82 
    83             /*
    84              * Get file info.
    85              * We have a little hack here, temporarily, write only files
    86              * cannot read EAs.
    87              */
    88             FS_VAR_SAVE_LOAD();
    89 #if OFF_MAX > LONG_MAX
    90             if (__libc_gpfnDosOpenL)
    91             {
    92                 if (fUnixEAs)
    93                     rc = DosQueryFileInfo(fh, FIL_QUERYEASIZEL, &info, sizeof(info.fsts4L));
    94                 else
    95                     rc = -1;
    96                 if (rc)
    97                 {
    98                     rc = DosQueryFileInfo(fh, FIL_STANDARDL, &info, sizeof(FILESTATUS3L));
    99                     info.fsts4L.cbList = ~0;
    100                 }
    101                 fLarge = 1;
    102             }
    103             else
    104 #endif
    105             {
    106                 if (fUnixEAs)
    107                     rc = DosQueryFileInfo(fh, FIL_QUERYEASIZE, &info, sizeof(info.fsts4));
    108                 else
    109                     rc = -1;
    110                 if (rc)
    111                 {
    112                     rc = DosQueryFileInfo(fh, FIL_STANDARD, &info, sizeof(FILESTATUS3));
    113                     info.fsts4.cbList = ~0;
    114                 }
    115             }
    116             FS_RESTORE();
    117             if (rc)
    118             {
    119                 __libc_FHPut(pFH);
    120                 rc = -__libc_native2errno(rc);
    121                 LIBCLOG_ERROR_RETURN_INT(rc);
    122             }
    123 
    124             /*
    125              * Format stats struct.
    126              *      We know the info struct layouts!
    127              *      Only cbFile, cbFileAlloc and attrFile need be accessed
    128              *      using the specific structure.
    129              */
    130             /* Times: FAT might not return create and access time. */
    131             pStat->st_ctime = pStat->st_mtime = __libc_back_timeFileTime2Unix(info.fsts4.ftimeLastWrite, info.fsts4.fdateLastWrite);
    132             if (    FTIMEZEROP(info.fsts4.ftimeCreation)
    133                 &&  FDATEZEROP(info.fsts4.fdateCreation))
    134                 pStat->st_birthtime = pStat->st_mtime;
    135             else
    136                 pStat->st_birthtime = __libc_back_timeFileTime2Unix(info.fsts4.ftimeCreation, info.fsts4.fdateCreation);
    137             if (    FTIMEZEROP(info.fsts4.ftimeLastAccess)
    138                 &&  FDATEZEROP(info.fsts4.fdateLastAccess))
    139                 pStat->st_atime = pStat->st_mtime;
    140             else
    141                 pStat->st_atime = __libc_back_timeFileTime2Unix(info.fsts4.ftimeLastAccess, info.fsts4.fdateLastAccess);
    142 
    143 #if OFF_MAX > LONG_MAX
    144             if (fLarge)
    145             {
    146                 pStat->st_size = info.fsts4L.cbFile;
    147                 pStat->st_blocks = info.fsts4L.cbFileAlloc / S_BLKSIZE;
    148                 rc = info.fsts4L.attrFile;
    149             }
    150             else
    151 #endif
    152             {
    153                 pStat->st_size = info.fsts4.cbFile;
    154                 pStat->st_blocks = info.fsts4.cbFileAlloc / S_BLKSIZE;
    155                 rc = info.fsts4.attrFile;
    156             }
    157             pStat->st_attr = rc;
    158             if (rc & FILE_READONLY)
    159                 pStat->st_mode |= S_IROTH | S_IRGRP | S_IRUSR;
    160             else
    161                 pStat->st_mode |= S_IROTH | S_IRGRP | S_IRUSR | S_IWOTH | S_IWGRP | S_IWUSR;
    162 
    163             /* If in unix mode we'll check the EAs (if any). */
    164             if (   fUnixEAs
    165                 && (fLarge ? info.fsts4L.cbList : info.fsts4.cbList) >= LIBC_UNIX_EA_MIN)
    166                 __libc_back_fsUnixAttribsGet(fh, pFH->pszNativePath, pStat);
    167         }
    168         else
    169         {
    170             /*
    171              * Use the native path if we've got it.
    172              */
    173             if (pFH->pszNativePath)
    174             {
    175                 struct stat st;
    176                 rc = __libc_back_fsNativeFileStat(pFH->pszNativePath, &st);
    177                 if (!rc)
    178                 {
    179                     *pStat = st;
    180                     __libc_FHPut(pFH);
    181                     LIBCLOG_RETURN_INT(0);
    182                 }
    183             }
    184 
    185             /*
    186              * Ok, try fake something plausible from the handle data.
    187              */
    188             if ((pFH->fFlags & O_ACCMODE) == O_RDONLY)
    189                 pStat->st_mode = S_IROTH | S_IRGRP | S_IRUSR;
    190             else
    191                 pStat->st_mode = S_IROTH | S_IRGRP | S_IRUSR | S_IWOTH | S_IWGRP | S_IWUSR;
    192 
    193             switch (pFH->fFlags & __LIBC_FH_TYPEMASK)
    194             {
    195                 case F_DEV:
    196                     pStat->st_mode = S_IFCHR;
    197                     pStat->st_rdev = pFH->Inode;
    198                     break;
    199                 case F_SOCKET:
    200                     pStat->st_mode |= S_IFSOCK | S_IXUSR | S_IXGRP | S_IXOTH;
    201                     break;
    202                 case F_PIPE:
    203                     pStat->st_mode |= S_IFIFO;
    204                     pStat->st_mode &= ~(S_IRWXO | S_IRWXG);
    205                     break;
    206                 case F_DIR:
    207                     pStat->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
    208                     break;
    209                 default:
    210                     LIBC_ASSERTM_FAILED("Unknown handle type %#x\n", pFH->fFlags & __LIBC_FH_TYPEMASK);
    211                     pStat->st_mode |= S_IFREG;
    212                     break;
    213             }
     58            LIBCLOG_MSG("%02x - st_dev:       %#x\n",  offsetof(struct stat, st_dev),       pStat->st_dev);
     59            LIBCLOG_MSG("%02x - st_attr:      %#x\n",  offsetof(struct stat, st_attr),      pStat->st_attr);
     60            LIBCLOG_MSG("%02x - st_ino:       %#llx\n",offsetof(struct stat, st_ino),       (long long)pStat->st_ino);
     61            LIBCLOG_MSG("%02x - st_mode:      %#x\n",  offsetof(struct stat, st_mode),      pStat->st_mode);
     62            LIBCLOG_MSG("%02x - st_nlink:     %u\n",   offsetof(struct stat, st_nlink),     pStat->st_nlink);
     63            LIBCLOG_MSG("%02x - st_uid:       %u\n",   offsetof(struct stat, st_uid),       pStat->st_uid);
     64            LIBCLOG_MSG("%02x - st_gid:       %u\n",   offsetof(struct stat, st_gid),       pStat->st_gid);
     65            LIBCLOG_MSG("%02x - st_rdev:      %#x\n",  offsetof(struct stat, st_rdev),      pStat->st_rdev);
     66            LIBCLOG_MSG("%02x - st_lspare:    %#x\n",  offsetof(struct stat, st_lspare),    pStat->st_lspare);
     67            LIBCLOG_MSG("%02x - st_atime:     %d\n",   offsetof(struct stat, st_atime),     pStat->st_atime);
     68            LIBCLOG_MSG("%02x - st_mtime:     %d\n",   offsetof(struct stat, st_mtime),     pStat->st_mtime);
     69            LIBCLOG_MSG("%02x - st_ctime:     %d\n",   offsetof(struct stat, st_ctime),     pStat->st_ctime);
     70            LIBCLOG_MSG("%02x - st_size:      %lld\n", offsetof(struct stat, st_size),      (long long)pStat->st_size);
     71            LIBCLOG_MSG("%02x - st_blocks:    %lld\n", offsetof(struct stat, st_blocks),    (long long)pStat->st_blocks);
     72            LIBCLOG_MSG("%02x - st_blksize:   %u\n",   offsetof(struct stat, st_blksize),   pStat->st_blksize);
     73            LIBCLOG_MSG("%02x - st_flags:     %#x\n",  offsetof(struct stat, st_flags),     pStat->st_flags);
     74            LIBCLOG_MSG("%02x - st_gen:       %#x\n",  offsetof(struct stat, st_gen),       pStat->st_gen);
     75            LIBCLOG_MSG("%02x - st_birthtime: %d\n",   offsetof(struct stat, st_birthtime), pStat->st_birthtime);
     76            LIBCLOG_RETURN_INT(0);
    21477        }
    21578    }
    216     //else
    217     //{
    218     //    rc = pFH->pOps->pfnStat(pFH, fh, pStat);
    219     //    if (rc)
    220     //    {
    221     //        if (rc > 0)
    222     //            rc = -__libc_native2errno(rc);
    223     //        __libc_FHPut(pFH);
    224     //        LIBCLOG_ERROR_RETURN_INT(rc);
    225     //    }
    226     //}
    227 
    228     LIBCLOG_MSG("%02x - st_dev:       %#x\n",  offsetof(struct stat, st_dev),       pStat->st_dev);
    229     LIBCLOG_MSG("%02x - st_attr:      %#x\n",  offsetof(struct stat, st_attr),      pStat->st_attr);
    230     LIBCLOG_MSG("%02x - st_ino:       %#llx\n",offsetof(struct stat, st_ino),       (long long)pStat->st_ino);
    231     LIBCLOG_MSG("%02x - st_mode:      %#x\n",  offsetof(struct stat, st_mode),      pStat->st_mode);
    232     LIBCLOG_MSG("%02x - st_nlink:     %u\n",   offsetof(struct stat, st_nlink),     pStat->st_nlink);
    233     LIBCLOG_MSG("%02x - st_uid:       %u\n",   offsetof(struct stat, st_uid),       pStat->st_uid);
    234     LIBCLOG_MSG("%02x - st_gid:       %u\n",   offsetof(struct stat, st_gid),       pStat->st_gid);
    235     LIBCLOG_MSG("%02x - st_rdev:      %#x\n",  offsetof(struct stat, st_rdev),      pStat->st_rdev);
    236     LIBCLOG_MSG("%02x - st_lspare:    %#x\n",  offsetof(struct stat, st_lspare),    pStat->st_lspare);
    237     LIBCLOG_MSG("%02x - st_atime:     %d\n",   offsetof(struct stat, st_atime),     pStat->st_atime);
    238     LIBCLOG_MSG("%02x - st_mtime:     %d\n",   offsetof(struct stat, st_mtime),     pStat->st_mtime);
    239     LIBCLOG_MSG("%02x - st_ctime:     %d\n",   offsetof(struct stat, st_ctime),     pStat->st_ctime);
    240     LIBCLOG_MSG("%02x - st_size:      %lld\n", offsetof(struct stat, st_size),      (long long)pStat->st_size);
    241     LIBCLOG_MSG("%02x - st_blocks:    %lld\n", offsetof(struct stat, st_blocks),    (long long)pStat->st_blocks);
    242     LIBCLOG_MSG("%02x - st_blksize:   %u\n",   offsetof(struct stat, st_blksize),   pStat->st_blksize);
    243     LIBCLOG_MSG("%02x - st_flags:     %#x\n",  offsetof(struct stat, st_flags),     pStat->st_flags);
    244     LIBCLOG_MSG("%02x - st_gen:       %#x\n",  offsetof(struct stat, st_gen),       pStat->st_gen);
    245     LIBCLOG_MSG("%02x - st_birthtime: %d\n",   offsetof(struct stat, st_birthtime), pStat->st_birthtime);
    246     __libc_FHPut(pFH);
    247     LIBCLOG_RETURN_INT(0);
     79    LIBCLOG_ERROR_RETURN_INT(rc);
    24880}
    24981
  • trunk/libc/src/kNIX/b_fsFileTimesSet.c

    r2914 r2924  
    3434 * @returns 0 on success.
    3535 * @returns Negative error code (errno.h) on failure.
    36  * @param   pszPath The path to the file to set the times of.
    37  * @param   paTimes Two timevalue structures. If NULL the current time is used.
     36 * @param   pszPath     The path to the file to set the times of.
     37 * @param   paTimes     The two time value structures, the first is the access time and the second
     38 *                      the modification time. If NULL the current time is used.
    3839 */
    3940int __libc_Back_fsFileTimesSet(const char *pszPath, const struct timeval *paTimes)
  • trunk/libc/src/kNIX/b_fsFileTimesSetFH.c

    r2913 r2924  
    2525 */
    2626
    27 
    28 /*******************************************************************************
    29 *   Header Files                                                               *
    30 *******************************************************************************/
    3127#include "kNIX.h"
    3228#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_FS
     
    5349    __LIBC_PFH pFH;
    5450    int rc = __libc_FHGet(fh, &pFH);
    55     if (rc)
    56         LIBCLOG_ERROR_RETURN_INT(rc);
    57 
    58     /*
    59      * Check the type.
    60      */
    61     switch (pFH->fFlags & __LIBC_FH_TYPEMASK)
     51    if (!rc)
    6252    {
    63         /* fail */
    64         case F_SOCKET:
    65         case F_PIPE: /* treat as socket for now */
    66             __libc_FHPut(pFH);
    67             LIBCLOG_ERROR_RETURN_INT(-EINVAL);
    68         /* ignore */
    69         case F_DEV:
    70             __libc_FHPut(pFH);
    71             LIBCLOG_RETURN_INT(0);
    72 
    73         /* use the path access. */
    74         case F_DIR:
    75             if (__predict_false(!pFH->pszNativePath))
    76                 rc = -EINVAL;
    77             else
    78                 rc = __libc_back_fsNativeFileTimesSet(pFH->pszNativePath, paTimes);
    79             __libc_FHPut(pFH);
    80             if (rc)
    81                 LIBCLOG_ERROR_RETURN_INT(rc);
    82             LIBCLOG_RETURN_INT(rc);
    83 
    84         /* treat */
    85         default:
    86         case F_FILE:
    87             break;
     53        if (pFH->pOps->pfnSetTimes)
     54            rc = pFH->pOps->pfnSetTimes(pFH, paTimes);
     55        else
     56            rc = -EINVAL;
     57        __libc_FHPut(pFH);
    8858    }
    89 
    90     if (!pFH->pOps)
    91     {
    92         /*
    93          * Ok, normalize the time.
    94          */
    95         time_t aTimes[2]; /* seconds since 1970 */
    96         if (!paTimes)
    97             aTimes[1] = aTimes[0] = fibGetUnixSeconds();
    98         else
    99         {
    100             if (!__libc_gfTZInfoOk)
    101                 tzset();
    102             aTimes[0] = paTimes[0].tv_sec;
    103             _gmt2loc(&aTimes[0]);
    104             aTimes[1] = paTimes[1].tv_sec;
    105             _gmt2loc(&aTimes[1]);
    106         }
    107 
    108         /*
    109          * Standard OS/2 file handle.
    110          */
    111         FS_VAR();
    112         FS_SAVE_LOAD();
    113         FILESTATUS3     fsts3;
    114 
    115         /*
    116          * Get file info.
    117          */
    118         rc = DosQueryFileInfo(fh, FIL_STANDARD, &fsts3, sizeof(fsts3));
    119         if (rc)
    120         {
    121             __libc_FHPut(pFH);
    122             FS_RESTORE();
    123             rc = -__libc_native2errno(rc);
    124             LIBCLOG_ERROR_RETURN_INT(rc);
    125         }
    126 
    127         /*
    128          * Update OS/2 bits.
    129          */
    130         __libc_back_timeUnix2FileTime(aTimes[0], &fsts3.ftimeLastAccess, &fsts3.fdateLastAccess);
    131         __libc_back_timeUnix2FileTime(aTimes[1], &fsts3.ftimeLastWrite,  &fsts3.fdateLastWrite);
    132         rc = DosSetFileInfo(fh, FIL_STANDARD, &fsts3, sizeof(fsts3));
    133         if (rc && pFH->pszNativePath)
    134         {
    135             LIBCLOG_ERROR("DosSetFileInfo(%d,,,) -> %d\n", fh, rc);
    136             rc = DosSetPathInfo((PCSZ)pFH->pszNativePath, FIL_STANDARD, &fsts3, sizeof(fsts3), 0);
    137             if (rc)
    138                 LIBCLOG_ERROR("DosSetPathInfo('%s',,,) -> %d\n", pFH->pszNativePath, rc);
    139         }
    140         FS_RESTORE();
    141         __libc_FHPut(pFH);
    142         if (rc)
    143         {
    144             rc = -__libc_native2errno(rc);
    145             LIBCLOG_ERROR_RETURN_INT(rc);
    146         }
    147     }
    148     else
    149     {
    150         /*
    151          * Non-standard handle - fail.
    152          */
    153         __libc_FHPut(pFH);
    154         LIBCLOG_ERROR_RETURN_INT(-EOPNOTSUPP);
    155     }
    156 
    157     LIBCLOG_RETURN_INT(0);
     59    LIBCLOG_MIX_RETURN_INT(rc);
    15860}
    15961
  • trunk/libc/src/kNIX/os2/b_dir.c

    r2923 r2924  
    4040static int dirWrite(__LIBC_PFH pFH, const void *pvBuf, size_t cbWrite, size_t *pcbWritten);
    4141static int dirSetSize(__LIBC_PFH pFH, off_t cbFile, int fZero);
     42static int dirSeek(__LIBC_PFH pFH, off_t off, int iMethod, off_t *poffNew);
    4243static int dirSync(__LIBC_PFH pFH);
    4344static int dirDuplicate(__LIBC_PFH pFH, int *pfhNew);
    4445static int dirFileControl(__LIBC_PFH pFH, int iRequest, int iArg, int *prc);
    4546static int dirIOControl(__LIBC_PFH pFH, unsigned long ulIOControl, va_list va, int *prc);
    46 static int dirSeek(__LIBC_PFH pFH, off_t off, int iMethod, off_t *poffNew);
     47static int dirSetFileMode(__LIBC_PFH pFH, mode_t fMode);
     48static int dirSetOwner(__LIBC_PFH pFH, uid_t uid);
     49static int dirSetTimes(__LIBC_PFH pFH, const struct timeval *paTimes);
     50static int dirStat(__LIBC_PFH pFH, struct stat *pStat);
    4751static int dirSelect(int cFHs, struct fd_set *pRead, struct fd_set *pWrite, struct fd_set *pExcept, struct timeval *tv, int *prc);
    4852static int dirForkChild(__LIBC_PFH pFH, __LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation);
     
    6872    dirFileControl,
    6973    dirIOControl,
     74    dirSetFileMode,
     75    dirSetOwner,
     76    dirSetTimes,
     77    dirStat,
    7078    dirSelect,
    7179    NULL,
     
    148156static int dirDuplicate(__LIBC_PFH pFH, int *pfhNew)
    149157{
    150     /** @todo */
     158    /** @todo dirDuplicate */
    151159    return -EOPNOTSUPP;
    152160}
     
    168176}
    169177
     178
     179/** @copydoc __LIBC_FHOPS::pfnSetFileMode */
     180static int dirSetFileMode(__LIBC_PFH pFH, mode_t fMode)
     181{
     182    LIBCLOG_ENTER("pFH=%p:{.fd=%d} fMode=0%o (%#x)\n", (void *)pFH, pFH->fh, fMode, fMode);
     183    int rc;
     184    if (pFH->pszNativePath)
     185        rc = __libc_back_fsNativeFileModeSet(pFH->pszNativePath, fMode);
     186    else
     187        rc = -EINVAL;
     188    LIBCLOG_MIX_RETURN_INT(rc);
     189}
     190
     191
     192/** @copydoc __LIBC_FHOPS::pfnSetOwner */
     193static int dirSetOwner(__LIBC_PFH pFH, uid_t uid)
     194{
     195    LIBCLOG_ENTER("pFH=%p:{.fd=%d} uid=%d\n", (void *)pFH, pFH->fh, uid);
     196    int rc;
     197    if (pFH->pszNativePath)
     198        rc = -ENOSYS;//rc = __libc_back_fsNativeSetOwner(pFH->pszNativePath, uid);
     199    else
     200        rc = -EINVAL;
     201    LIBCLOG_MIX_RETURN_INT(rc);
     202}
     203
     204
     205/** @copydoc __LIBC_FHOPS::pfnStat */
     206static int dirStat(__LIBC_PFH pFH, struct stat *pStat)
     207{
     208    LIBCLOG_ENTER("pFH=%p:{.fd=%d} pStat=%p\n", (void *)pFH, pFH->fh, (void *)pStat);
     209    int rc;
     210    if (pFH->pszNativePath)
     211        rc = __libc_back_fsNativeFileStat(pFH->pszNativePath, pStat);
     212    else
     213        rc = -EINVAL;
     214    LIBCLOG_MIX_RETURN_INT(rc);
     215}
     216
     217
     218/** @copydoc __LIBC_FHOPS::pfnSetTimes */
     219static int dirSetTimes(__LIBC_PFH pFH, const struct timeval *paTimes)
     220{
     221    LIBCLOG_ENTER("pFH=%p:{.fd=%d} paTimes=%p:{{.tv_sec=%ld, .tv_usec=%ld}, {.tv_sec=%ld, .tv_usec=%ld}}\n",
     222                  (void *)pFH, pFH->fh, (void *)paTimes,
     223                  paTimes ? paTimes[0].tv_sec : ~0, paTimes ? paTimes[0].tv_usec : ~0,
     224                  paTimes ? paTimes[1].tv_sec : ~0, paTimes ? paTimes[1].tv_usec : ~0);
     225    int rc;
     226    if (pFH->pszNativePath)
     227        rc = __libc_back_fsNativeFileTimesSet(pFH->pszNativePath, paTimes);
     228    else
     229        rc = -EINVAL;
     230    LIBCLOG_MIX_RETURN_INT(rc);
     231}
    170232
    171233/** @copydoc __LIBC_FHOPS::pfnSeek */
  • trunk/libc/src/kNIX/os2/b_fsNativeFileTimesSet.c

    r2914 r2924  
    3535 * @returns Negative error code (errno.h) on failure.
    3636 * @param   pszNativePath   Path to the file to set the times of.
    37  * @param   paTimes         Two timevalue structures. If NULL the current time is used.
     37 * @param   paTimes     The two time value structures, the first is the access time and the second
     38 *                      the modification time. If NULL the current time is used.
    3839 */
    3940int __libc_back_fsNativeFileTimesSet(const char *pszNativePath, const struct timeval *paTimes)
  • trunk/libc/src/kNIX/os2/fhOS2File.c

    r2922 r2924  
    467467            LIBCLOG_RETURN_MSG(0, "ret 0 - *pfhNew=%d\n", *pfhNew);
    468468        }
    469         else
    470             DosClose(hNew);
     469        DosClose(hNew);
    471470    }
    472471    else
     
    554553    }
    555554
     555    if (!rc)
     556        LIBCLOG_RETURN_MSG(0, "ret 0 - *prc=%d (%#x)\n", *prc, *prc);
    556557    if (rc > 0)
    557558        rc = -__libc_back_native2errno(rc);
    558     else if (!rc)
    559         LIBCLOG_RETURN_MSG(0, "ret 0 - *prc=%d (%#x)\n", *prc, *prc);
    560559    LIBCLOG_ERROR_RETURN_INT(rc);
     560}
     561
     562
     563/** @copydoc __LIBC_FHOPS::pfnSetMode */
     564static int fhOs2FileSetMode(__LIBC_PFH pFH, mode_t fMode)
     565{
     566    LIBCLOG_ENTER("pFH=%p:{.fd=%d} fMode=0%o (%#x)\n", (void *)pFH, pFH->fh, fMode, fMode);
     567
     568    /*
     569     * Check the type.
     570     */
     571    switch (pFH->fFlags & __LIBC_FH_TYPEMASK)
     572    {
     573        /* fail */
     574        case F_SOCKET:
     575        case F_PIPE: /* treat as socket for now */
     576            LIBCLOG_ERROR_RETURN_INT(-EINVAL);
     577
     578        /* ignore */
     579        case F_DEV:
     580            LIBCLOG_RETURN_INT(0);
     581
     582        /* use the path access. */
     583        case F_DIR:
     584            LIBC_ASSERT_FAILED();
     585            LIBCLOG_RETURN_INT(-EDOOFUS);
     586
     587        /* treat */
     588        default:
     589        case F_FILE:
     590            break;
     591    }
     592
     593    /*
     594     * Get file info, we don't need EA size nor large file sizes.
     595     */
     596    FILESTATUS3 fsts3;
     597    FS_VAR_SAVE_LOAD();
     598    int rc = DosQueryFileInfo(pFH->fh, FIL_STANDARD, &fsts3, sizeof(FILESTATUS3));
     599    if (__predict_true(rc == NO_ERROR))
     600    {
     601        /*
     602         * If in unix mode we'll have to update/add the MODE too.
     603         */
     604        if (    pFH->pFsInfo
     605            &&  pFH->pFsInfo->fUnixEAs)
     606        {
     607            mode_t fCurMode;
     608            rc = __libc_back_fsUnixAttribsGetMode(pFH->fh, pFH->pszNativePath, &fCurMode);
     609            if (__predict_true(!rc))
     610            {
     611                /* correct the passed in Mode mask. */
     612                fMode &= ALLPERMS; /** @todo sticky bit and set uid/gid access validation... */
     613                fMode |= fCurMode & ~ALLPERMS;
     614
     615                /* construct FEA2 stuff. */
     616                #pragma pack(1)
     617                struct __LIBC_FSUNIXATTRIBSSETMODE
     618                {
     619                    ULONG   cbList;
     620                    ULONG   off;
     621                    BYTE    fEA;
     622                    BYTE    cbName;
     623                    USHORT  cbValue;
     624                    CHAR    szName[sizeof(EA_MODE)];
     625                    USHORT  usType;
     626                    USHORT  cbData;
     627                    uint32_t u32Mode;
     628                } EAs =
     629                {
     630                    sizeof(EAs), 0, FEA_NEEDEA, sizeof(EA_MODE) - 1, sizeof(uint32_t) + 4, EA_MODE, EAT_BINARY, sizeof(uint32_t), fMode
     631                };
     632                #pragma pack()
     633                EAOP2 EaOp2;
     634                EaOp2.fpGEA2List = NULL;
     635                EaOp2.fpFEA2List = (PFEA2LIST)&EAs;
     636                EaOp2.oError = 0;
     637
     638                /* finally, try update / add the EA. */
     639                rc = DosSetFileInfo(pFH->fh, FIL_QUERYEASIZE, &EaOp2, sizeof(EaOp2));
     640                if (__predict_false(rc != NO_ERROR))
     641                {
     642                    LIBCLOG_ERROR("DosSetFileInfo(%d,,,,) -> %d, oError=%#lx\n", pFH->fh, rc, EaOp2.oError);
     643                    if (rc != ERROR_EAS_NOT_SUPPORTED && pFH->pszNativePath)
     644                    {
     645                        EaOp2.oError = 0;
     646                        int rc2 = DosSetPathInfo((PCSZ)pFH->pszNativePath, FIL_QUERYEASIZE, &EaOp2, sizeof(EaOp2), 0);
     647                        if (rc2)
     648                            LIBCLOG_ERROR("DosSetPathInfo('%s',,,,) -> %d, oError=%#lx\n", pFH->pszNativePath, rc2, EaOp2.oError);
     649                    }
     650                    if (rc == ERROR_EAS_NOT_SUPPORTED)
     651                        rc = 0;
     652                }
     653            }
     654            else if (rc == -ENOTSUP)
     655                rc = 0;
     656        }
     657        if (!rc)
     658        {
     659            /*
     660             * Update OS/2 bits.
     661             */
     662            if (fMode & S_IWRITE)
     663                fsts3.attrFile &= ~FILE_READONLY;
     664            else
     665                fsts3.attrFile |= FILE_READONLY;
     666            rc = DosSetFileInfo(pFH->fh, FIL_STANDARD, &fsts3, sizeof(fsts3));
     667        }
     668    }
     669
     670    FS_RESTORE();
     671    if (__predict_true(!rc))
     672        LIBCLOG_RETURN_INT(0);
     673    if (rc > 0)
     674        rc = -__libc_back_native2errno(rc);
     675    LIBCLOG_ERROR_RETURN_INT(rc);
     676}
     677
     678
     679/** @copydoc __LIBC_FHOPS::pfnSetOwner */
     680static int fhOs2FileSetOwner(__LIBC_PFH pFH, uid_t uid)
     681{
     682    LIBCLOG_ENTER("pFH=%p:{.fd=%d} uid=%d\n", (void *)pFH, pFH->fh, uid);
     683    int rc;
     684    /** @todo fchown */
     685    /*if (pFH->pszNativePath)
     686        rc = -ENOSYS;//rc = __libc_back_fsNativeSetOwner(pFH->pszNativePath, uid);
     687    else
     688        rc = -EINVAL;*/
     689    rc = -ENOSYS;
     690    LIBCLOG_MIX_RETURN_INT(rc);
     691}
     692
     693
     694/** @copydoc __LIBC_FHOPS::pfnSetTimes */
     695static int fhOs2FileSetTimes(__LIBC_PFH pFH, const struct timeval *paTimes)
     696{
     697    LIBCLOG_ENTER("pFH=%p:{.fd=%d} paTimes=%p:{{.tv_sec=%ld, .tv_usec=%ld}, {.tv_sec=%ld, .tv_usec=%ld}}\n",
     698                  (void *)pFH, pFH->fh, (void *)paTimes,
     699                  paTimes ? paTimes[0].tv_sec : ~0, paTimes ? paTimes[0].tv_usec : ~0,
     700                  paTimes ? paTimes[1].tv_sec : ~0, paTimes ? paTimes[1].tv_usec : ~0);
     701    /*
     702     * Check the type.
     703     */
     704    switch (pFH->fFlags & __LIBC_FH_TYPEMASK)
     705    {
     706        /* fail */
     707        case F_SOCKET:
     708        case F_PIPE: /* treat as socket for now */
     709            LIBCLOG_ERROR_RETURN_INT(-EINVAL);
     710
     711        /* ignore */
     712        case F_DEV:
     713            LIBCLOG_RETURN_INT(0);
     714
     715        /* use the path access. */
     716        case F_DIR:
     717            LIBC_ASSERT_FAILED();
     718            LIBCLOG_RETURN_INT(-EDOOFUS);
     719
     720        /* treat */
     721        default:
     722        case F_FILE:
     723            break;
     724    }
     725
     726    /*
     727     * Ok, normalize the time.
     728     */
     729    time_t aTimes[2]; /* seconds since 1970 */
     730    if (!paTimes)
     731        aTimes[1] = aTimes[0] = fibGetUnixSeconds();
     732    else
     733    {
     734        if (!__libc_gfTZInfoOk)
     735            tzset();
     736        aTimes[0] = paTimes[0].tv_sec;
     737        _gmt2loc(&aTimes[0]);
     738        aTimes[1] = paTimes[1].tv_sec;
     739        _gmt2loc(&aTimes[1]);
     740    }
     741
     742    /*
     743     * Get file info.
     744     */
     745    FILESTATUS3 fsts3;
     746    FS_VAR_SAVE_LOAD();
     747    int rc = DosQueryFileInfo(pFH->fh, FIL_STANDARD, &fsts3, sizeof(fsts3));
     748    if (!rc)
     749    {
     750        /*
     751         * Update OS/2 bits.
     752         */
     753        __libc_back_timeUnix2FileTime(aTimes[0], &fsts3.ftimeLastAccess, &fsts3.fdateLastAccess);
     754        __libc_back_timeUnix2FileTime(aTimes[1], &fsts3.ftimeLastWrite,  &fsts3.fdateLastWrite);
     755        rc = DosSetFileInfo(pFH->fh, FIL_STANDARD, &fsts3, sizeof(fsts3));
     756        if (rc && pFH->pszNativePath)
     757        {
     758            LIBCLOG_ERROR("DosSetFileInfo(%d,,,) -> %d\n", pFH->fh, rc);
     759            rc = DosSetPathInfo((PCSZ)pFH->pszNativePath, FIL_STANDARD, &fsts3, sizeof(fsts3), 0);
     760            if (rc)
     761                LIBCLOG_ERROR("DosSetPathInfo('%s',,,) -> %d\n", pFH->pszNativePath, rc);
     762        }
     763    }
     764    FS_RESTORE();
     765    if (!rc)
     766        LIBCLOG_RETURN_INT(0);
     767    rc = -__libc_back_native2errno(rc);
     768    LIBCLOG_ERROR_RETURN_INT(rc);
     769}
     770
     771/** @copydoc __LIBC_FHOPS::pfnStat */
     772static int fhOs2FileStat(__LIBC_PFH pFH, struct stat *pStat)
     773{
     774    LIBCLOG_ENTER("pFH=%p:{.fd=%d} pStat=%p\n", (void *)pFH, pFH->fh, (void *)pStat);
     775    const int fUnixEAs = pFH->pFsInfo && pFH->pFsInfo->fUnixEAs;
     776
     777    /*
     778     * Use query handle type to figure out the file type.
     779     */
     780    bzero(pStat, sizeof(*pStat));
     781    /* fake unix stuff */
     782    //pStat->st_uid = 0;
     783    //pStat->st_gid = 0;
     784    pStat->st_ino = pFH->Inode;
     785    pStat->st_dev = pFH->Dev;
     786    //pStat->st_rdev = 0;
     787    pStat->st_nlink = 1;
     788    pStat->st_blksize = 4096*12; /* 48KB */
     789
     790    int rc;
     791    if ((pFH->fFlags & __LIBC_FH_TYPEMASK) == F_FILE)
     792    {
     793        /*
     794         * Regular OS/2 file.
     795         */
     796        union
     797        {
     798            FILESTATUS4     fsts4;
     799            FILESTATUS4L    fsts4L;
     800        } info;
     801#if OFF_MAX > LONG_MAX
     802        int     fLarge = 0;
     803#endif
     804        pStat->st_mode = S_IFREG;
     805
     806        /*
     807         * Get file info.
     808         * We have a little hack here, temporarily, write only files
     809         * cannot read EAs.
     810         */
     811        FS_VAR_SAVE_LOAD();
     812#if OFF_MAX > LONG_MAX
     813        if (__libc_gpfnDosOpenL)
     814        {
     815            if (fUnixEAs)
     816                rc = DosQueryFileInfo(pFH->fh, FIL_QUERYEASIZEL, &info, sizeof(info.fsts4L));
     817            else
     818                rc = -1;
     819            if (rc)
     820            {
     821                rc = DosQueryFileInfo(pFH->fh, FIL_STANDARDL, &info, sizeof(FILESTATUS3L));
     822                info.fsts4L.cbList = ~0;
     823            }
     824            fLarge = 1;
     825        }
     826        else
     827#endif
     828        {
     829            if (fUnixEAs)
     830                rc = DosQueryFileInfo(pFH->fh, FIL_QUERYEASIZE, &info, sizeof(info.fsts4));
     831            else
     832                rc = -1;
     833            if (rc)
     834            {
     835                rc = DosQueryFileInfo(pFH->fh, FIL_STANDARD, &info, sizeof(FILESTATUS3));
     836                info.fsts4.cbList = ~0;
     837            }
     838        }
     839        if (!rc)
     840        {
     841            /*
     842             * Format stats struct.
     843             *      We know the info struct layouts!
     844             *      Only cbFile, cbFileAlloc and attrFile need be accessed
     845             *      using the specific structure.
     846             */
     847            /* Times: FAT might not return create and access time. */
     848            pStat->st_ctime = pStat->st_mtime = __libc_back_timeFileTime2Unix(info.fsts4.ftimeLastWrite, info.fsts4.fdateLastWrite);
     849            if (    FTIMEZEROP(info.fsts4.ftimeCreation)
     850                &&  FDATEZEROP(info.fsts4.fdateCreation))
     851                pStat->st_birthtime = pStat->st_mtime;
     852            else
     853                pStat->st_birthtime = __libc_back_timeFileTime2Unix(info.fsts4.ftimeCreation, info.fsts4.fdateCreation);
     854            if (    FTIMEZEROP(info.fsts4.ftimeLastAccess)
     855                &&  FDATEZEROP(info.fsts4.fdateLastAccess))
     856                pStat->st_atime = pStat->st_mtime;
     857            else
     858                pStat->st_atime = __libc_back_timeFileTime2Unix(info.fsts4.ftimeLastAccess, info.fsts4.fdateLastAccess);
     859
     860#if OFF_MAX > LONG_MAX
     861            if (fLarge)
     862            {
     863                pStat->st_size = info.fsts4L.cbFile;
     864                pStat->st_blocks = info.fsts4L.cbFileAlloc / S_BLKSIZE;
     865                rc = info.fsts4L.attrFile;
     866            }
     867            else
     868#endif
     869            {
     870                pStat->st_size = info.fsts4.cbFile;
     871                pStat->st_blocks = info.fsts4.cbFileAlloc / S_BLKSIZE;
     872                rc = info.fsts4.attrFile;
     873            }
     874            pStat->st_attr = rc;
     875            if (rc & FILE_READONLY)
     876                pStat->st_mode |= S_IROTH | S_IRGRP | S_IRUSR;
     877            else
     878                pStat->st_mode |= S_IROTH | S_IRGRP | S_IRUSR | S_IWOTH | S_IWGRP | S_IWUSR;
     879
     880            /* If in unix mode we'll check the EAs (if any). */
     881            if (   fUnixEAs
     882                && (fLarge ? info.fsts4L.cbList : info.fsts4.cbList) >= LIBC_UNIX_EA_MIN)
     883                __libc_back_fsUnixAttribsGet(pFH->fh, pFH->pszNativePath, pStat);
     884        }
     885    }
     886    else
     887    {
     888        /*
     889         * Use the native path if we've got one.
     890         */
     891        if (pFH->pszNativePath)
     892        {
     893            struct stat st;
     894            rc = __libc_back_fsNativeFileStat(pFH->pszNativePath, &st);
     895        }
     896        if (rc)
     897        {
     898            /*
     899             * Ok, try fake something plausible from the handle data.
     900             */
     901            rc = 0;
     902            if ((pFH->fFlags & O_ACCMODE) == O_RDONLY)
     903                pStat->st_mode = S_IROTH | S_IRGRP | S_IRUSR;
     904            else
     905                pStat->st_mode = S_IROTH | S_IRGRP | S_IRUSR | S_IWOTH | S_IWGRP | S_IWUSR;
     906
     907            switch (pFH->fFlags & __LIBC_FH_TYPEMASK)
     908            {
     909                case F_DEV:
     910                    pStat->st_mode = S_IFCHR;
     911                    pStat->st_rdev = pFH->Inode;
     912                    break;
     913                case F_SOCKET:
     914                    pStat->st_mode |= S_IFSOCK | S_IXUSR | S_IXGRP | S_IXOTH;
     915                    break;
     916                case F_PIPE:
     917                    pStat->st_mode |= S_IFIFO;
     918                    pStat->st_mode &= ~(S_IRWXO | S_IRWXG);
     919                    break;
     920                case F_DIR:
     921                    pStat->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
     922                    break;
     923                default:
     924                    LIBC_ASSERTM_FAILED("Unknown handle type %#x\n", pFH->fFlags & __LIBC_FH_TYPEMASK);
     925                    pStat->st_mode |= S_IFREG;
     926                    break;
     927            }
     928        }
     929    }
     930
     931    LIBCLOG_MIX_RETURN_INT(rc);
    561932}
    562933
     
    596967    fhOs2FileFileControl,
    597968    fhOs2FileIOControl,
     969    fhOs2FileSetMode,
     970    fhOs2FileSetOwner,
     971    fhOs2FileSetTimes,
     972    fhOs2FileStat,
    598973    fhOs2FileSelect,
    599974    NULL /* fork parent */,
  • trunk/libc/src/kNIX/os2/tcpipver.c

    r2923 r2924  
    135135static int TCPNAME(ops_FileControl)(__LIBC_PFH pFH, int iIOControl, int iArg, int *prc);
    136136static int TCPNAME(ops_IOControl)(__LIBC_PFH pFH, unsigned long ulIOControl, va_list va, int *prc);
     137static int TCPNAME(ops_Stat)(__LIBC_PFH pFH, struct stat *pStat);
    137138static int TCPNAME(ops_Select)(int cFHs, struct fd_set *pRead, struct fd_set *pWrite, struct fd_set *pExcept, struct timeval *tv, int *prc);
    138139static int TCPNAME(ops_ForkChild)(struct __libc_FileHandle *pFH, __LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation);
     
    182183    TCPNAME(ops_FileControl),
    183184    TCPNAME(ops_IOControl),
     185    /* .pfnSetMode = */ NULL,
     186    /* .pfnSetOwner = */ NULL,
     187    /* .pfnSetTimes = */ NULL,
     188    TCPNAME(ops_Stat),
    184189    TCPNAME(ops_Select),
    185190    NULL /* fork parent */,
     
    730735
    731736
     737/** @copydoc __LIBC_FHOPS::pfnStat */
     738static int TCPNAME(ops_Stat)(__LIBC_PFH pFH, struct stat *pStat)
     739{
     740    LIBCLOG_ENTER("pFH=%p:{.iSocket=%d .fh=%d} pStat=%p\n", (void *)pFH, ((PLIBCSOCKETFH)pFH)->iSocket, pFH->fh, (void *)pStat);
     741
     742    /*
     743     * Just create some half plausible stuff.
     744     */
     745    bzero(pStat, sizeof(*pStat));
     746    /* fake unix stuff */
     747    //pStat->st_uid = 0;
     748    //pStat->st_gid = 0;
     749    pStat->st_ino = pFH->Inode;
     750    pStat->st_dev = pFH->Dev;
     751    //pStat->st_rdev = 0;
     752    pStat->st_nlink = 1;
     753    pStat->st_blksize = 32*1024; /* 32KB */
     754    if ((pFH->fFlags & O_ACCMODE) == O_RDONLY)
     755        pStat->st_mode = S_IROTH | S_IRGRP | S_IRUSR;
     756    else
     757        pStat->st_mode = S_IROTH | S_IRGRP | S_IRUSR | S_IWOTH | S_IWGRP | S_IWUSR;
     758    pStat->st_mode |= S_IFSOCK | S_IXUSR | S_IXGRP | S_IXOTH;
     759
     760    LIBCLOG_RETURN_INT(0);
     761}
     762
     763
    732764/** Select operation.
    733765 * The select operation is only performed if all handles have the same
Note: See TracChangeset for help on using the changeset viewer.