Changeset 2439


Ignore:
Timestamp:
Nov 13, 2005, 12:59:18 PM (20 years ago)
Author:
bird
Message:

Created proper backend for fcntl removing F_GETOSFD in the process. Using fcntl to set O_NONBLOCK on sockets works now.

Location:
trunk/src/emx
Files:
1 added
9 edited

Legend:

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

    r2438 r2439  
    88          Kudos to Yuri for tracking down the places which required attention.
    99    - libc:
     10        o Created proper backend for fcntl removing F_GETOSFD in the process. Using
     11          fcntl to set O_NONBLOCK on sockets works now.
    1012        o Fixed a generic error handling bug in ioctl, write, read, dup and dup
    1113          which was causing incorrect errnos.
  • TabularUnified trunk/src/emx/include/InnoTekLIBC/backend.h

    r2438 r2439  
    465465ssize_t __libc_Back_ioDirGetEntries(int fh, void *pvBuf, size_t cbBuf, __off_t *poff);
    466466
     467/**
     468 * File Control.
     469 *
     470 * Deals with file descriptor flags, file descriptor duplication and locking.
     471 *
     472 * @returns 0 on success and *piRet set.
     473 * @returns Negated errno on failure and *piRet set to -1.
     474 * @param   fh          File handle (descriptor).
     475 * @param   iRequest    Which file file descriptior request to perform.
     476 * @param   iArg        Argument which content is specific to each
     477 *                      iRequest operation.
     478 * @param   prc         Where to store the value which upon success is
     479 *                      returned to the caller.
     480 */
     481int __libc_Back_ioFileControl(int fh, int iRequest, intptr_t iArg, int *prc);
     482
     483/**
     484 * File Control operation - OS/2 standard handle.
     485 *
     486 * @returns 0 on success.
     487 * @returns OS/2 error code or negated errno on failure.
     488 *
     489 * @param   pFH         Pointer to the handle structure to operate on.
     490 * @param   fh          It's associated filehandle.
     491 * @param   iRequest    Which file file descriptior request to perform.
     492 * @param   iArg        Argument which content is specific to each
     493 *                      iRequest operation.
     494 * @param   prc         Where to store the value which upon success is
     495 *                      returned to the caller.
     496 */
     497int __libc_Back_ioFileControlStandard(__LIBC_PFH pFH, int fh, int iRequest, intptr_t iArg, int *prc);
     498   
    467499/**
    468500 * Try resolve a filehandle to a path.
  • TabularUnified trunk/src/emx/include/emx/io.h

    r2438 r2439  
    7777#define __LIBC_FH_FDFLAGS_MASK      0xf0000000
    7878
     79/** The mask of flags settable using fcntl(,F_SETFL,). */
     80#define __LIBC_FH_SETFL_MASK        (O_NONBLOCK | O_APPEND /*| O_ASYNC*/ | O_SYNC | O_DIRECT | O_BINARY | O_TEXT)
     81/** The mask of flags gettable using fcntl(,F_GETFL,). */
     82#define __LIBC_FH_GETFL_MASK        (__LIBC_FH_SETFL_MASK | O_ACCMODE | O_NOINHERIT)
     83
    7984/** @} */
    8085
  • TabularUnified trunk/src/emx/include/emx/syscalls.h

    r2438 r2439  
    132132int __execname (char *buf, size_t bufsize);
    133133void __exit (int ret) __attribute__ ((__noreturn__));
    134 int __fcntl (int handle, int request, int arg);
     134/*int __fcntl (int handle, int request, int arg);*/
    135135int __filesys (__const__ char *drive, char *name, size_t size);
    136136int __findfirst (__const__ char *name, int attr, struct _find *fp);
  • TabularUnified trunk/src/emx/include/sys/fcntl.h

    r2438 r2439  
    287287#endif
    288288
    289 /* fcntl command */
    290 /* bird: EMX specifics - start */
    291 #define F_GETOSFD       20 /* RSXNT */  /* F_GETOSFD used to be 6 */
    292 /* bird: EMX specifics - end */
    293 
    294 
    295289#if !defined (F_OK) /* bird: Really defined in unistd.h, but Linux and EMX does it here too. */
    296290/* access function */
  • TabularUnified trunk/src/emx/src/lib/io/fcntl.c

    r2438 r2439  
    1 /* fcntl.c (emx+gcc) -- Copyright (c) 1992-1998 by Eberhard Mattes
    2                      -- Copyright (c) 2003 by Knut St. Osmunden */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * LIBC - fcntl().
     5 *
     6 * Copyright (c) 1992-1998 by Eberhard Mattes
     7 * Copyright (c) 2003-2005 knut st. osmundsen <bird@innotek.de>
     8 *
     9 *
     10 * This file is part of InnoTek LIBC.
     11 *
     12 * InnoTek LIBC is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU General Public License as published by
     14 * the Free Software Foundation; either version 2 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * InnoTek LIBC is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU General Public License
     23 * along with InnoTek LIBC; if not, write to the Free Software
     24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     25 *
     26 */
    327
     28
     29/*******************************************************************************
     30*   Header Files                                                               *
     31*******************************************************************************/
    432#include "libc-alias.h"
    533#include <stdarg.h>
     
    836#include <fcntl.h>
    937#include <errno.h>
    10 #include <limits.h>
    1138#include <sys/ioctl.h>
    1239#include <emx/io.h>
    13 #include <emx/syscalls.h>
    14 
    15 #define FLAGS (O_APPEND | O_NDELAY)
    16 
    17 /* Replace some bits in an lvalue */
    18 
    19 #define SETBITS(dst,mask,newb) ((dst) = ((dst) & ~(mask)) | ((newb) & (mask)))
     40#include <InnoTekLIBC/backend.h>
     41#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_IO
     42#include <InnoTekLIBC/logstrict.h>
    2043
    2144
    22 /* Create a new file descriptor for HANDLE that is the lowest numbered
    23    available file descriptor greater than or equal to HANDLE2. */
     45/*******************************************************************************
     46*   Internal Functions                                                         *
     47*******************************************************************************/
     48static int dupfd(int fh, int fhMin);
    2449
    25 static int dupfd (int handle, int handle2)
     50int _STD(fcntl)(int fh, int iRequest, ...)
    2651{
    27   int *handles;
    28   int n, fd, e;
     52    LIBCLOG_ENTER("fh=%d iRequest=%d\n", fh, iRequest);
     53    int rc;
     54    int rcSuccess = 0;
     55    switch (iRequest)
     56    {
     57        /*
     58         * No arg.
     59         */
     60        case F_GETFD:
     61        case F_GETFL:
     62            rc = __libc_Back_ioFileControl(fh, iRequest, 0, &rcSuccess);
     63            break;
    2964
    30   /* TODO: Use sysconf()? */
    31   /** @todo Define a max handles or something */
     65        /*
     66         * int arg.
     67         */
     68        case F_SETFL:
     69        case F_SETFD:
     70        {
     71            va_list Args;
     72            va_start(Args, iRequest);
     73            int fFlags = va_arg(Args, int);
     74            va_end(Args);
     75            rc = __libc_Back_ioFileControl(fh, iRequest, fFlags, &rcSuccess);
     76            break;
     77        }
     78       
     79        /*
     80         * struct flock * argument.
     81         */
     82        case F_GETLK:   /* get record locking information */
     83        case F_SETLK:   /* set record locking information */
     84        case F_SETLKW:  /* F_SETLK; wait if blocked */
     85        {
     86            va_list Args;
     87            va_start(Args, iRequest);
     88            struct flock *pFlock = va_arg(Args, struct flock *);
     89            va_end(Args);
     90            rc = __libc_Back_ioFileControl(fh, iRequest, (intptr_t)pFlock, &rcSuccess);
     91            break;
     92        }
    3293
    33   if (handle2 < 0 || handle2 >= /*_POSIX_OPEN_MAX */ 10000)
    34     {
    35       errno = EINVAL;
    36       return -1;
     94        /*
     95         * Handled here.
     96         */
     97        case F_DUPFD:
     98        {
     99            va_list Args;
     100            va_start(Args, iRequest);
     101            int fhMin = va_arg(Args, int);
     102            va_end(Args);
     103            rc = dupfd(fh, fhMin);
     104            if (rc >= 0)
     105                LIBCLOG_RETURN_INT(rc);
     106            break;
     107        }
     108
     109
     110        default:
     111            errno = -EINVAL;
     112            LIBCLOG_ERROR_RETURN_MSG(-1, "ret -1 - iRequest=%d\n", iRequest);
    37113    }
    38   handles = alloca (handle2 * sizeof (int));
    39   n = 0;
    40   for (;;)
    41     {
    42       fd = dup (handle);
    43       if (fd < 0 || fd >= handle2)
    44         break;
    45       if (n >= handle2)
    46         {
    47           /* Avoid writing beyond the end of handles[] if dup()
    48              happens not to work as advertised. */
    49114
    50           close (fd);
    51           fd = -1; errno = EMFILE;
    52           break;
    53         }
    54       handles[n++] = fd;
    55     }
    56   e = errno;
    57   while (n > 0)
    58     close (handles[--n]);
    59   errno = e;
    60   return fd;
     115    if (!rc)
     116        LIBCLOG_RETURN_INT(rcSuccess);
     117    errno = -rc;
     118    LIBCLOG_ERROR_RETURN_INT(-1);
    61119}
    62120
    63121
    64 int _STD(fcntl) (int handle, int request, ...)
     122/**
     123 * Create a new file handle for 'fh' that is the lowest numbered
     124 * available file handle greater than or equal to 'fhMin'.
     125 *
     126 * @returns New file handle on success.
     127 * @returns -1 and errno on failure.
     128 * @param   fh      The file handle to duplicate.
     129 * @param   fhMin   The minimum file handle number.
     130 */
     131static int dupfd(int fh, int fhMin)
    65132{
    66   va_list va;
    67   int arg;
    68   PLIBCFH   pFH;
     133    LIBCLOG_ENTER("fh=%d fhMin=%d\n", fh, fhMin);
    69134
    70   /*
    71    * Get filehandle.
    72    */
    73   pFH = __libc_FH(handle);
    74   if (!pFH)
    75   {
    76       errno = EBADF;
    77       return -1;
    78   }
    79 
    80   /** @todo Let __fcntl handle the flags. */
    81 
    82   switch (request)
     135    /*
     136     * Check filehandle range.
     137     */
     138    /** @todo Define a max handles or something, get it dynamically is probably right idea. */
     139    if (fhMin < 0 || fhMin >= /*_POSIX_OPEN_MAX */ 10000)
    83140    {
    84     case F_GETFL:
    85       return __fcntl(handle, request, 0);
    86     case F_SETFL:
    87       va_start (va, request);
    88       arg = va_arg (va, int);
    89       va_end (va);
    90       if (arg & ~FLAGS)
    91         break;
    92       if (__fcntl (handle, request, arg) == -1)
    93         return -1;
    94       SETBITS (pFH->fFlags, FLAGS, arg);
    95       return 0;
    96 
    97     case F_GETFD:
    98     case F_SETFD:
    99       va_start (va, request);
    100       arg = va_arg (va, int);
    101       va_end (va);
    102       return __fcntl (handle, request, arg);
    103 
    104     case F_DUPFD:
    105       va_start (va, request);
    106       arg = va_arg (va, int);
    107       va_end (va);
    108       if (arg < 0)
    109         {
    110           errno = EINVAL;
    111           return -1;
    112         }
    113       return dupfd (handle, arg);
    114 
    115     case F_GETOSFD:
    116       return __fcntl (handle, request, 0);
    117 
    118     case F_GETLK:   /* get record locking information */
    119     case F_SETLK:   /* set record locking information */
    120     case F_SETLKW:  /* F_SETLK; wait if blocked */
    121       va_start (va, request);
    122       arg = va_arg (va, /*struct flock **/ int);
    123       va_end (va);
    124       return __fcntl (handle, request, arg);
     141        errno = EINVAL;
     142        LIBCLOG_ERROR_RETURN_INT(-1);
    125143    }
    126144
    127   errno = EINVAL;
    128   return -1;
     145    /*
     146     * Brute force, duplicate till we get what we want.
     147     */
     148    int    *paFHs = alloca(fhMin * sizeof(int));
     149    int     e = errno;
     150    int     i = 0;
     151    int     fhNew;
     152    for (;;)
     153    {
     154        fhNew = dup(fh);
     155        if (fhNew < 0 || fhNew >= fhMin)
     156            break;
     157        if (i >= fhMin)
     158        {
     159            /* Avoid writing beyond the end of paFHs[] if dup()
     160               happens not to work as advertised. */
     161
     162            close(fhNew);
     163            fhNew = -1;
     164            errno = EMFILE;
     165            break;
     166        }
     167        paFHs[i++] = fhNew;
     168    }
     169
     170    /*
     171     * Clean up, save errno again on failure.
     172     */
     173    if (fhNew < 0)
     174        e = errno;
     175    while (i > 0)
     176        close(paFHs[--i]);
     177    errno = e;
     178
     179    LIBCLOG_MIX_RETURN_INT(fhNew);
    129180}
     181
     182
     183
  • TabularUnified trunk/src/emx/src/lib/libc.def

    r2438 r2439  
    227227    "___exit" @240
    228228    "___expand_table" @241
    229     "___fcntl" @242
     229    "___libc_Back_ioFileControl" @242
    230230    "___find_bigpair" @243
    231231    "___find_last_page" @244
     
    19521952    "___libc_Back_ioDirGetEntries" @1950
    19531953    "__std_getdirents" @1951
     1954    "___libc_Back_ioFileControlStandard" @1952
  • TabularUnified trunk/src/emx/src/lib/sys/__fcntl.c

    r2438 r2439  
    1 /* sys/fcntl.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes
    2                          -- Copyright (c) 2003 by Knut St. Osmunden */
     1/* dead */
    32
    4 #include "libc-alias.h"
    5 #include <fcntl.h>
    6 #include <errno.h>
    7 #include <limits.h>
    8 #include <io.h>
    9 #include <string.h>
    10 #define INCL_ERRORS
    11 #define INCL_FSMACROS
    12 #include <os2emx.h>
    13 #include "b_fs.h"
    14 #include <386/builtin.h>
    15 #include <emx/io.h>
    16 #include <emx/syscalls.h>
    17 #include "syscalls.h"
    18 #define __LIBC_LOG_GROUP    __LIBC_LOG_GRP_IO
    19 #include <InnoTekLIBC/logstrict.h>
    20 
    21 
    22 /*******************************************************************************
    23 *   Internal Functions                                                         *
    24 *******************************************************************************/
    25 static int __fcntl_getfd(__LIBC_PFH pFH, int hFile);
    26 static int __fcntl_setfd(__LIBC_PFH pFH, int hFile, int arg);
    27 static int __fcntl_locking(int hFile, int iRequest, struct flock *pFlock);
    28 
    29 
    30 int __fcntl(int hFile, int iRequest, int arg)
    31 {
    32     LIBCLOG_ENTER("hFile=%d iRequest=%#x arg=%#x\n", hFile, iRequest, arg);
    33     int         rc;
    34     __LIBC_PFH  pFH;
    35 
    36     /*
    37      * Get the file hFile data.
    38      */
    39     pFH = __libc_FH(hFile);
    40     if (!pFH)
    41     {
    42         errno = EBADF;
    43         LIBCLOG_ERROR_RETURN_INT(-1);
    44     }
    45 
    46     if (!pFH->pOps)
    47     {
    48         /*
    49          * Standard OS/2 File hFile.
    50          */
    51         switch (iRequest)
    52         {
    53             /*
    54              * Get file status flags and access modes.
    55              */
    56             case F_GETFL:
    57             {
    58                 unsigned fFlags = pFH->fFlags & (O_ACCMODE | O_APPEND | O_NONBLOCK | O_SYNC /*| O_*SYNC*/);
    59                 LIBCLOG_RETURN_INT(fFlags);
    60             }
    61 
    62             /*
    63              * Set file status flags.
    64              */
    65             case F_SETFL:
    66             {
    67                 /** @todo implement this properly. See FCNTLFLAGS. */
    68                 LIBCLOG_ERROR_RETURN(0, "ret 0 - F_SETFL isn't implemented but returns success. arg=%#x\n", arg);
    69             }
    70 
    71             /*
    72              * Get file descriptor flags.
    73              */
    74             case F_GETFD:
    75                 rc = __fcntl_getfd(pFH, hFile);
    76                 LIBCLOG_RETURN_INT(rc);
    77 
    78             /*
    79              * Set file descriptor flags.
    80              */
    81             case F_SETFD:
    82                 rc = __fcntl_setfd(pFH, hFile, arg);
    83                 LIBCLOG_RETURN_INT(rc);
    84 
    85             /*
    86              * File locking.
    87              */
    88             case F_GETLK:   /* get record locking information */
    89             case F_SETLK:   /* set record locking information */
    90             case F_SETLKW:  /* F_SETLK; wait if blocked */
    91             {
    92                 int rc = __fcntl_locking(hFile, iRequest, (struct flock*)arg);
    93                 LIBCLOG_RETURN_INT(rc);
    94             }
    95 
    96             default:
    97                 errno = EINVAL;
    98                 LIBCLOG_ERROR_RETURN(-1, "ret -1 - Invalid iRequest %#x\n", iRequest);
    99         }
    100     }
    101     else
    102     {
    103         /*
    104          * Non-standard hFile - call registered method.
    105          */
    106         int rcRet = 0;
    107         rc = pFH->pOps->pfnFileControl(pFH, hFile, iRequest, arg, &rcRet);
    108         if (rc)
    109         {
    110             if (rc > 0)
    111                 _sys_set_errno(rc);
    112             else
    113                 errno = -rc;
    114             LIBCLOG_RETURN_INT(-1);
    115         }
    116 
    117         /*
    118          * Post process to keep the OS/2 fake hFile up to date (on success).
    119          */
    120         switch (iRequest)
    121         {
    122             case F_SETFD:
    123                 rc = __fcntl_setfd(pFH, hFile, arg);
    124                 if (rc == -1)
    125                     LIBCLOG_RETURN_INT(-1);
    126                 break;
    127         }
    128         LIBCLOG_RETURN_INT(rcRet);
    129     }
    130 }
    131 
    132 
    133 
    134 /**
    135  * F_GETFD operation on standard OS/2 hFile.
    136  * Gets file descriptor flags, which at the moment is limited to FD_CLOEXEC.
    137  *
    138  * @returns 0 on success.
    139  * @returns -1 an errno on failure.
    140  * @param   pFH     File handler structure.
    141  * @param   hFile  File hFile.
    142  */
    143 static int __fcntl_getfd(__LIBC_PFH pFH, int hFile)
    144 {
    145     LIBCLOG_ENTER("pFH=%p hFile=%d\n", (void *)pFH, hFile);
    146     int     rc;
    147     ULONG   fulState;
    148     FS_VAR();
    149 
    150     FS_SAVE_LOAD();
    151     rc = DosQueryFHState(hFile, &fulState);
    152     FS_RESTORE();
    153     if (!rc)
    154     {
    155         unsigned fFlags = pFH->fFlags;
    156         /* flags out of sync? */
    157         if (    ( (fulState & OPEN_FLAGS_NOINHERIT) != 0 )
    158             !=  (   (fFlags & (O_NOINHERIT | (FD_CLOEXEC << __LIBC_FH_FDFLAGS_SHIFT)))
    159                  == (O_NOINHERIT | (FD_CLOEXEC << __LIBC_FH_FDFLAGS_SHIFT)) ) )
    160         {
    161             LIBC_ASSERTM_FAILED("Inherit flags are out of sync for file hFile %d (%#x)! fulState=%08lx fFlags=%08x\n",
    162                                 hFile, hFile, fulState, fFlags);
    163             if (fulState & OPEN_FLAGS_NOINHERIT)
    164                 fFlags |= O_NOINHERIT | FD_CLOEXEC;
    165             else
    166                 fFlags &= ~(O_NOINHERIT | FD_CLOEXEC);
    167             __atomic_xchg(&pFH->fFlags, fFlags);
    168         }
    169 
    170         fFlags >>= __LIBC_FH_FDFLAGS_SHIFT;
    171         LIBCLOG_RETURN_INT(fFlags);
    172     }
    173 
    174     /* failure. */
    175     _sys_set_errno(rc);
    176     LIBCLOG_RETURN_INT(-1);
    177 }
    178 
    179 
    180 /**
    181  * F_SETFD operation on standard OS/2 hFile.
    182  * Sets file descriptor flags, which at the moment is limited to FD_CLOEXEC.
    183  *
    184  * @returns 0 on success.
    185  * @returns -1 an errno on failure.
    186  * @param   pFH     File handler structure.
    187  * @param   hFile  File hFile.
    188  * @param   arg     New file descriptor flags.
    189  */
    190 static int __fcntl_setfd(__LIBC_PFH pFH, int hFile, int arg)
    191 {
    192     LIBCLOG_ENTER("pFH=%p hFile=%d arg=%#x\n", (void *)pFH, hFile, arg);
    193 
    194     /*
    195      * Calc new flags.
    196      */
    197     unsigned fFlags = pFH->fFlags;
    198     fFlags = (fFlags & ~__LIBC_FH_FDFLAGS_MASK) | (arg << __LIBC_FH_FDFLAGS_SHIFT);
    199     if (arg & FD_CLOEXEC)
    200         fFlags |= O_NOINHERIT;
    201     else
    202         fFlags &= ~O_NOINHERIT;
    203 
    204     /*
    205      * Update the flags.
    206      */
    207     int rc = __libc_FHSetFlags(pFH, hFile, fFlags);
    208     if (!rc)
    209         LIBCLOG_RETURN_INT(0);
    210     errno = -rc;
    211     LIBCLOG_RETURN_INT(-1);
    212 }
    213 
    214 
    215 /**
    216  * Handle locking requests.
    217  * @returns
    218  * @param   hFile       File hFile.
    219  * @param   iRequest     Lock iRequest.
    220  * @param   pFlock      Pointer to flock structure.
    221  */
    222 static int __fcntl_locking(int hFile, int iRequest, struct flock *pFlock)
    223 {
    224     APIRET        rc;
    225     union
    226     {
    227         FILESTATUS3     fsts3;
    228         FILESTATUS3L    fsts3L;
    229     } info;
    230 #if OFF_MAX > LONG_MAX
    231     int     fLarge = 0;
    232 #endif
    233     FS_VAR();
    234 
    235     /* check input */
    236     /** @todo: Implement F_GETLK */
    237     if (!pFlock || iRequest == F_GETLK)
    238     {
    239         errno = EINVAL;
    240         return -1;
    241     }
    242 
    243     /* check hFile & get filesize. */
    244     FS_SAVE_LOAD();
    245 #if OFF_MAX > LONG_MAX
    246     if (__libc_gpfnDosOpenL)
    247     {
    248         rc = DosQueryFileInfo(hFile, FIL_STANDARDL, &info, sizeof(info.fsts3L));
    249         fLarge = 1;
    250     }
    251     else
    252 #endif
    253         rc = DosQueryFileInfo(hFile, FIL_STANDARD, &info, sizeof(info.fsts3));
    254     FS_RESTORE();
    255     if (!rc)
    256     {
    257         ULONG       fAccess;
    258         int         fLock;
    259         ULONG       ulTimeout;
    260         off_t       cbFile;
    261         off_t       offStart;
    262         off_t       cbRange;
    263 #if OFF_MAX > LONG_MAX
    264         if (fLarge)
    265             cbFile = info.fsts3L.cbFile;
    266         else
    267 #endif
    268             cbFile = info.fsts3.cbFile;
    269 
    270         /* range */
    271         cbRange = pFlock->l_len ? pFlock->l_len : OFF_MAX;
    272 
    273         /* offset */
    274         switch (pFlock->l_whence)
    275         {
    276             case SEEK_SET:  offStart = pFlock->l_start; break;
    277             case SEEK_CUR:  offStart = tell(hFile) + pFlock->l_start; break;
    278             case SEEK_END:  offStart = cbFile - pFlock->l_start; break;
    279             default:
    280                 errno = EINVAL;
    281                 return -1;
    282         }
    283         if (    offStart < 0
    284             ||  cbRange + offStart < 0)
    285         {
    286             errno = EINVAL;
    287             return -1;
    288         }
    289 
    290         /* flags and order */
    291         fAccess = 0; /* exclusive */
    292         switch (pFlock->l_type)
    293         {
    294             case F_UNLCK:
    295                 fLock = 0;
    296                 break;
    297 
    298             case F_RDLCK:
    299                 fAccess = 1; /* shared */
    300             case F_WRLCK:
    301                 fLock = 1;
    302                 break;
    303 
    304             default:
    305                 errno = EINVAL;
    306                 return -1;
    307         }
    308 
    309         /* timeout */
    310         if (iRequest == F_SETLKW)
    311             ulTimeout = SEM_INDEFINITE_WAIT;
    312         else
    313             ulTimeout = SEM_IMMEDIATE_RETURN;
    314 
    315         /* Do work. */
    316 #if OFF_MAX > LONG_MAX
    317         rc = ERROR_INVALID_PARAMETER;
    318         if (__libc_gpfnDosSetFileLocksL)
    319         {
    320             FILELOCKL   aflock[2];
    321             bzero(&aflock[(fLock + 1) & 1], sizeof(aflock[0]));
    322             aflock[fLock].lOffset = offStart;
    323             aflock[fLock].lRange  = cbRange;
    324             FS_SAVE_LOAD();
    325             rc = __libc_gpfnDosSetFileLocksL(hFile, &aflock[0], &aflock[1], ulTimeout, fAccess);
    326             FS_RESTORE();
    327         }
    328         /* There is/was a bug in the large API which make it fail on non JFS
    329          * disks with ERROR_INVALID_PARAMETER. We need to work around this. */
    330         if (rc == ERROR_INVALID_PARAMETER)
    331 #endif
    332         {
    333             FILELOCK    aflock[2];
    334 #if OFF_MAX > LONG_MAX
    335             if (    offStart > LONG_MAX
    336                 ||  (   cbRange != OFF_MAX
    337                      && (   cbRange > LONG_MAX
    338                          || offStart + cbRange > LONG_MAX)
    339                     )
    340                )
    341             {
    342                 errno = EOVERFLOW;
    343                 return -1;
    344             }
    345 #endif
    346             bzero(&aflock[(fLock + 1) & 1], sizeof(aflock[0]));
    347             aflock[fLock].lOffset = offStart;
    348             aflock[fLock].lRange  = cbRange;
    349             FS_SAVE_LOAD();
    350             rc = DosSetFileLocks(hFile, &aflock[0], &aflock[1], ulTimeout, fAccess);
    351             FS_RESTORE();
    352         }
    353     }
    354 
    355     /* done */
    356     if (!rc)
    357         return 0;
    358     _sys_set_errno (rc);
    359     return -1;
    360 }
    361 
  • TabularUnified trunk/src/emx/src/lib/sys/tcpipver.c

    r2438 r2439  
    6767#include <InnoTekLIBC/fork.h>
    6868#include <InnoTekLIBC/thread.h>
     69#include <InnoTekLIBC/backend.h>
    6970#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SOCKET
    7071#include <InnoTekLIBC/logstrict.h>
     
    392393    LIBCLOG_ENTER("pFH=%p:{iSocket=%d} fh=%d iRequest=%#x iArg=%#x prc=%p\n",
    393394                  (void *)pFH, ((PLIBCSOCKETFH)pFH)->iSocket, fh, iRequest, iArg, (void *)prc);
    394     //PLIBCSOCKETFH   pSocketFH = (PLIBCSOCKETFH)pFH;
    395     int             rc = 0;
     395    int rc;
    396396
    397397
     
    402402    {
    403403        /*
    404          * Get file status flags and access modes.
     404         * These can be forwarded handled as-if this was a normal file.
    405405         */
    406406        case F_GETFL:
    407         {
    408             unsigned fFlags = pFH->fFlags & (O_ACCMODE | O_APPEND | O_NONBLOCK | O_SYNC /*| O_*SYNC*/);
    409             *prc = fFlags;
    410             break;
    411         }
     407        case F_GETFD:
     408        case F_SETFD:
     409            rc = __libc_Back_ioFileControlStandard(pFH, fh, iRequest, iArg, prc);
     410            break;
    412411
    413412        /*
    414          * Set file status flags.
     413         * For this one we'll have to listen in to the O_NONBLOCK flag.
    415414         */
    416415        case F_SETFL:
    417416        {
    418             /** @todo implement this properly. See FCNTLFLAGS. */
    419 #if 1
    420             LIBCLOG_ERROR("F_SETFL isn't implemented but returns success. arg=%#x\n", iArg);
    421             *prc = 0;
    422 #else
    423             pFH->fFlags= pFH->fFlags & ~(O_ACCMODE | O_APPEND | O_NONBLOCK | O_SYNC);
    424             pFH->fFlags= pFH->fFlags | fFlags;
    425             LIBCLOG_MSG("F_SETFL is implemented only partially but returns success. arg=%#x\n", pFH->fFlags);
    426             *prc = fFlags;
    427 #endif
     417            if ((iArg ^ pFH->fFlags) & O_NONBLOCK)
     418            {
     419                PLIBCSOCKETFH   pSocketFH = (PLIBCSOCKETFH)pFH;
     420                int             fFlag = (iArg & O_NONBLOCK) != 0;
     421                rc = TCPNAME(imp_os2_ioctl)(pSocketFH->iSocket, FIONBIO, (char *)&fFlag, sizeof(int));
     422                if (!rc)
     423                {
     424                    rc = __libc_Back_ioFileControlStandard(pFH, fh, iRequest, iArg, prc);
     425                    if (rc)
     426                    {
     427                        /* undo change on failure. */
     428                        fFlag = (iArg & O_NONBLOCK) == 0;
     429                        TCPNAME(imp_os2_ioctl)(pSocketFH->iSocket, FIONBIO, (char *)&fFlag, sizeof(int));
     430                    }
     431                }
     432            }
     433            else
     434                rc = __libc_Back_ioFileControlStandard(pFH, fh, iRequest, iArg, prc);
    428435            break;
    429436        }
    430437
    431438        /*
    432          * Get file descriptor flags.
     439         * Other operations are not supported on sockets.
    433440         */
    434         case F_GETFD:
    435             *prc = pFH->fFlags >> __LIBC_FH_FDFLAGS_SHIFT;
    436             break;
    437 
    438         /*
    439          * Set file descriptor flags.
    440          */
    441         case F_SETFD:
    442             if (iArg & ~(FD_CLOEXEC))
    443             {
    444                 *prc = -1;
    445                 LIBCLOG_ERROR_RETURN(-EINVAL, "Invalid argument %#x to F_SETFD\n", iArg);
    446             }
    447 
    448             unsigned fFlags = pFH->fFlags;
    449             fFlags &= ~__LIBC_FH_FDFLAGS_MASK;
    450             fFlags |= iArg << __LIBC_FH_FDFLAGS_SHIFT;
    451             __atomic_xchg(&pFH->fFlags, fFlags);
    452             *prc = 0;
    453             break;
    454 
    455441        default:
    456442            *prc = -1;
    457             LIBCLOG_ERROR_RETURN(-EINVAL, "Invalid or Unsupported request %#x\n", iRequest);
    458             break;
    459     }
    460 
    461     LIBCLOG_RETURN_INT(rc);
     443            LIBCLOG_ERROR_RETURN(-EINVAL, "Invalid or unsupported request %#x %#x\n", iRequest, iArg);
     444    }
     445
     446    LIBCLOG_MIX0_RETURN_INT(rc);
    462447}
    463448
     
    484469    switch (__IOCLW(iIOControl))
    485470    {
    486         case SIOSTATARP:
    487             rc = TCPNAME(imp_os2_ioctl)(pSocketFH->iSocket, iIOControl, pchArg, sizeof(struct oarptab));
    488             break;
    489         case SIOSTATAT:
     471        case __IOCLW(SIOSTATARP):
     472            rc = TCPNAME(imp_os2_ioctl)(pSocketFH->iSocket, SIOSTATARP, pchArg, sizeof(struct oarptab));
     473            break;
     474        case __IOCLW(SIOSTATAT):
    490475            /** this isn't really suitable for this ioctl interface!! */
    491             rc = TCPNAME(imp_os2_ioctl)(pSocketFH->iSocket, iIOControl, pchArg, sizeof(struct statatreq) + 2);
    492             break;
    493         case SIOSTATIF:
    494             rc = TCPNAME(imp_os2_ioctl)(pSocketFH->iSocket, iIOControl, pchArg, sizeof(struct ifmib));
    495             break;
    496         case SIOSTATIF42:
     476            rc = TCPNAME(imp_os2_ioctl)(pSocketFH->iSocket, SIOSTATAT, pchArg, sizeof(struct statatreq) + 2);
     477            break;
     478        case __IOCLW(SIOSTATIF):
     479            rc = TCPNAME(imp_os2_ioctl)(pSocketFH->iSocket, SIOSTATIF, pchArg, sizeof(struct ifmib));
     480            break;
     481        case __IOCLW(SIOSTATIF42):
    497482            /* What the h*** is the difference between the SIOSTATIF42 ioctl and SIOSTATIF?
    498483               The docs doesn't make sense when looking in the headers... */
    499             rc = TCPNAME(imp_os2_ioctl)(pSocketFH->iSocket, iIOControl, pchArg, sizeof(struct ifmib));
    500             break;
    501         case SIOSTATRT:
    502             rc = TCPNAME(imp_os2_ioctl)(pSocketFH->iSocket, iIOControl, pchArg, sizeof(struct rtentries));
    503             break;
    504         case SIOSTATSO:
     484            rc = TCPNAME(imp_os2_ioctl)(pSocketFH->iSocket, SIOSTATIF42, pchArg, sizeof(struct ifmib));
     485            break;
     486        case __IOCLW(SIOSTATRT):
     487            rc = TCPNAME(imp_os2_ioctl)(pSocketFH->iSocket, SIOSTATRT, pchArg, sizeof(struct rtentries));
     488            break;
     489        case __IOCLW(SIOSTATSO):
    505490            /** this isn't really suitable for this ioctl interface!! */
    506             rc = TCPNAME(imp_os2_ioctl)(pSocketFH->iSocket, iIOControl, pchArg, sizeof(struct sockaddr));
    507             break;
    508 
    509         case FIONBIO:
    510             rc = TCPNAME(imp_ioctl)(pSocketFH->iSocket, iIOControl, pchArg);
    511             if (rc)
     491            rc = TCPNAME(imp_os2_ioctl)(pSocketFH->iSocket, SIOSTATSO, pchArg, sizeof(struct sockaddr));
     492            break;
     493
     494        case __IOCLW(FIONBIO):
     495            rc = TCPNAME(imp_ioctl)(pSocketFH->iSocket, FIONBIO, pchArg);
     496            if (!rc)
    512497            {
     498                unsigned fFlags = pSocketFH->core.fFlags;
    513499                if (*(unsigned*)pchArg)
    514                     pSocketFH->core.fFlags |= O_NDELAY;
     500                    fFlags |= O_NONBLOCK;
    515501                else
    516                     pSocketFH->core.fFlags &= ~O_NDELAY;
     502                    fFlags &= ~O_NONBLOCK;
     503                rc = __libc_FHSetFlags(pFH, fh, fFlags);
    517504            }
    518505            break;
Note: See TracChangeset for help on using the changeset viewer.