Changeset 2439
- Timestamp:
- Nov 13, 2005, 12:59:18 PM (20 years ago)
- Location:
- trunk/src/emx
- Files:
-
- 1 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/emx/ChangeLog.LIBC ¶
r2438 r2439 8 8 Kudos to Yuri for tracking down the places which required attention. 9 9 - 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. 10 12 o Fixed a generic error handling bug in ioctl, write, read, dup and dup 11 13 which was causing incorrect errnos. -
TabularUnified trunk/src/emx/include/InnoTekLIBC/backend.h ¶
r2438 r2439 465 465 ssize_t __libc_Back_ioDirGetEntries(int fh, void *pvBuf, size_t cbBuf, __off_t *poff); 466 466 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 */ 481 int __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 */ 497 int __libc_Back_ioFileControlStandard(__LIBC_PFH pFH, int fh, int iRequest, intptr_t iArg, int *prc); 498 467 499 /** 468 500 * Try resolve a filehandle to a path. -
TabularUnified trunk/src/emx/include/emx/io.h ¶
r2438 r2439 77 77 #define __LIBC_FH_FDFLAGS_MASK 0xf0000000 78 78 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 79 84 /** @} */ 80 85 -
TabularUnified trunk/src/emx/include/emx/syscalls.h ¶
r2438 r2439 132 132 int __execname (char *buf, size_t bufsize); 133 133 void __exit (int ret) __attribute__ ((__noreturn__)); 134 int __fcntl (int handle, int request, int arg); 134 /*int __fcntl (int handle, int request, int arg);*/ 135 135 int __filesys (__const__ char *drive, char *name, size_t size); 136 136 int __findfirst (__const__ char *name, int attr, struct _find *fp); -
TabularUnified trunk/src/emx/include/sys/fcntl.h ¶
r2438 r2439 287 287 #endif 288 288 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 295 289 #if !defined (F_OK) /* bird: Really defined in unistd.h, but Linux and EMX does it here too. */ 296 290 /* 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 */ 3 27 28 29 /******************************************************************************* 30 * Header Files * 31 *******************************************************************************/ 4 32 #include "libc-alias.h" 5 33 #include <stdarg.h> … … 8 36 #include <fcntl.h> 9 37 #include <errno.h> 10 #include <limits.h>11 38 #include <sys/ioctl.h> 12 39 #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> 20 43 21 44 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 *******************************************************************************/ 48 static int dupfd(int fh, int fhMin); 24 49 25 static int dupfd (int handle, int handle2)50 int _STD(fcntl)(int fh, int iRequest, ...) 26 51 { 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; 29 64 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 } 32 93 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); 37 113 } 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. */49 114 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); 61 119 } 62 120 63 121 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 */ 131 static int dupfd(int fh, int fhMin) 65 132 { 66 va_list va; 67 int arg; 68 PLIBCFH pFH; 133 LIBCLOG_ENTER("fh=%d fhMin=%d\n", fh, fhMin); 69 134 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) 83 140 { 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); 125 143 } 126 144 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); 129 180 } 181 182 183 -
TabularUnified trunk/src/emx/src/lib/libc.def ¶
r2438 r2439 227 227 "___exit" @240 228 228 "___expand_table" @241 229 "___ fcntl" @242229 "___libc_Back_ioFileControl" @242 230 230 "___find_bigpair" @243 231 231 "___find_last_page" @244 … … 1952 1952 "___libc_Back_ioDirGetEntries" @1950 1953 1953 "__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 */ 3 2 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_ERRORS11 #define INCL_FSMACROS12 #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_IO19 #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 else102 {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 else113 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 else166 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 else202 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 * @returns218 * @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 union226 {227 FILESTATUS3 fsts3;228 FILESTATUS3L fsts3L;229 } info;230 #if OFF_MAX > LONG_MAX231 int fLarge = 0;232 #endif233 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_MAX246 if (__libc_gpfnDosOpenL)247 {248 rc = DosQueryFileInfo(hFile, FIL_STANDARDL, &info, sizeof(info.fsts3L));249 fLarge = 1;250 }251 else252 #endif253 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_MAX264 if (fLarge)265 cbFile = info.fsts3L.cbFile;266 else267 #endif268 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 < 0284 || 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 else313 ulTimeout = SEM_IMMEDIATE_RETURN;314 315 /* Do work. */316 #if OFF_MAX > LONG_MAX317 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 JFS329 * disks with ERROR_INVALID_PARAMETER. We need to work around this. */330 if (rc == ERROR_INVALID_PARAMETER)331 #endif332 {333 FILELOCK aflock[2];334 #if OFF_MAX > LONG_MAX335 if ( offStart > LONG_MAX336 || ( cbRange != OFF_MAX337 && ( cbRange > LONG_MAX338 || offStart + cbRange > LONG_MAX)339 )340 )341 {342 errno = EOVERFLOW;343 return -1;344 }345 #endif346 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 67 67 #include <InnoTekLIBC/fork.h> 68 68 #include <InnoTekLIBC/thread.h> 69 #include <InnoTekLIBC/backend.h> 69 70 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SOCKET 70 71 #include <InnoTekLIBC/logstrict.h> … … 392 393 LIBCLOG_ENTER("pFH=%p:{iSocket=%d} fh=%d iRequest=%#x iArg=%#x prc=%p\n", 393 394 (void *)pFH, ((PLIBCSOCKETFH)pFH)->iSocket, fh, iRequest, iArg, (void *)prc); 394 //PLIBCSOCKETFH pSocketFH = (PLIBCSOCKETFH)pFH; 395 int rc = 0; 395 int rc; 396 396 397 397 … … 402 402 { 403 403 /* 404 * Get file status flags and access modes.404 * These can be forwarded handled as-if this was a normal file. 405 405 */ 406 406 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; 412 411 413 412 /* 414 * Set file status flags.413 * For this one we'll have to listen in to the O_NONBLOCK flag. 415 414 */ 416 415 case F_SETFL: 417 416 { 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); 428 435 break; 429 436 } 430 437 431 438 /* 432 * Get file descriptor flags.439 * Other operations are not supported on sockets. 433 440 */ 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 455 441 default: 456 442 *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); 462 447 } 463 448 … … 484 469 switch (__IOCLW(iIOControl)) 485 470 { 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): 490 475 /** 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): 497 482 /* What the h*** is the difference between the SIOSTATIF42 ioctl and SIOSTATIF? 498 483 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): 505 490 /** 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) 512 497 { 498 unsigned fFlags = pSocketFH->core.fFlags; 513 499 if (*(unsigned*)pchArg) 514 pSocketFH->core.fFlags |= O_NDELAY;500 fFlags |= O_NONBLOCK; 515 501 else 516 pSocketFH->core.fFlags &= ~O_NDELAY; 502 fFlags &= ~O_NONBLOCK; 503 rc = __libc_FHSetFlags(pFH, fh, fFlags); 517 504 } 518 505 break;
Note:
See TracChangeset
for help on using the changeset viewer.