Changeset 2289 in kBuild for trunk/src/kash/shfile.c
- Timestamp:
- Feb 26, 2009 4:58:49 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kash/shfile.c
r2288 r2289 29 29 #include <stdlib.h> 30 30 #include <stdio.h> 31 #include <assert.h> 31 32 32 33 #if K_OS == K_OS_WINDOWS … … 35 36 # define PIPE_BUF 512 36 37 # endif 38 # include <Windows.h> 37 39 #else 38 40 # include <unistd.h> … … 46 48 47 49 50 /******************************************************************************* 51 * Defined Constants And Macros * 52 *******************************************************************************/ 53 /** @def SHFILE_IN_USE 54 * Whether the file descriptor table stuff is actually in use or not. 55 */ 56 #if !defined(SH_PURE_STUB_MODE) \ 57 && ( K_OS == K_OS_WINDOWS \ 58 || ( !defined(SH_STUB_MODE) \ 59 && !defined(SH_FORKED_MODE)) \ 60 ) 61 # define SHFILE_IN_USE 62 #endif 63 /** The max file table size. */ 64 #define SHFILE_MAX 1024 65 /** The file table growth rate. */ 66 #define SHFILE_GROW 64 67 /** The min native unix file descriptor. */ 68 #define SHFILE_UNIX_MIN_FD 32 69 /** The path buffer size we use. */ 70 #define SHFILE_MAX_PATH 4096 71 72 /** Set errno and return. Doing a trace in debug build. */ 73 #define RETURN_ERROR(rc, err, msg) \ 74 do { \ 75 TRACE2((NULL, "%s: " ## msg ## " - returning %d / %d\n", __FUNCTION__, (rc), (err))); \ 76 errno = (err); \ 77 return (rc); \ 78 } while (0) 79 80 81 #ifdef SHFILE_IN_USE 82 83 /** 84 * Close the specified native handle. 85 * 86 * @param native The native file handle. 87 * @param flags The flags in case they might come in handy later. 88 */ 89 static void shfile_native_close(intptr_t native, unsigned flags) 90 { 91 #if K_OS == K_OS_WINDOWS 92 BOOL fRc = CloseHandle((HANDLE)native); 93 assert(fRc); (void)fRc; 94 #else 95 int s = errno; 96 close(native); 97 errno = s; 98 #endif 99 (void)flags; 100 } 101 102 /** 103 * Inserts the file into the descriptor table. 104 * 105 * If we're out of memory and cannot extend the table, we'll close the 106 * file, set errno to EMFILE and return -1. 107 * 108 * @returns The file descriptor number. -1 and errno on failure. 109 * @param pfdtab The file descriptor table. 110 * @param native The native file handle. 111 * @param flags The flags the it was created with. 112 * @param fdMin The minimum file descriptor number, pass -1 if any is ok. 113 * @param who Who we're doing this for (for logging purposes). 114 */ 115 static int shfile_insert(shfdtab *pfdtab, intptr_t native, unsigned flags, int fdMin, const char *who) 116 { 117 shmtxtmp tmp; 118 int fd; 119 int i; 120 121 /* 122 * Fend of bad stuff. 123 */ 124 if (fdMin >= SHFILE_MAX) 125 { 126 errno = EMFILE; 127 return -1; 128 } 129 130 shmtx_enter(&pfdtab->mtx, &tmp); 131 132 /* 133 * Search for a fitting unused location. 134 */ 135 fd = -1; 136 for (i = 0; (unsigned)i < pfdtab->size; i++) 137 if ( i >= fdMin 138 && pfdtab->tab[i].fd == -1) 139 { 140 fd = i; 141 break; 142 } 143 if (fd == -1) 144 { 145 /* 146 * Grow the descriptor table. 147 */ 148 shfile *new_tab; 149 int new_size = pfdtab->size + SHFILE_GROW; 150 while (new_size < fdMin) 151 new_size += SHFILE_GROW; 152 new_tab = realloc(pfdtab->tab, new_size * sizeof(shfile)); 153 if (new_tab) 154 { 155 fd = i = pfdtab->size; 156 if (fd < fdMin) 157 fd = fdMin; 158 for (i = pfdtab->size; i < new_size; i++) 159 { 160 new_tab[i].fd = -1; 161 new_tab[i].flags = 0; 162 new_tab[i].native = -1; 163 } 164 165 pfdtab->tab = new_tab; 166 pfdtab->size = new_size; 167 } 168 } 169 170 /* 171 * Fill in the entry if we've found one. 172 */ 173 if (fd != -1) 174 { 175 pfdtab->tab[fd].fd = fd; 176 pfdtab->tab[fd].flags = flags; 177 pfdtab->tab[fd].cloexec = 0; 178 pfdtab->tab[fd].native = native; 179 } 180 else 181 shfile_native_close(native, flags); 182 183 shmtx_leave(&pfdtab->mtx, &tmp); 184 185 if (fd == -1) 186 errno = EMFILE; 187 (void)who; 188 return fd; 189 } 190 191 /** 192 * Gets a file descriptor and lock the file descriptor table. 193 * 194 * @returns Pointer to the file and table ownership on success, 195 * NULL and errno set to EBADF on failure. 196 * @param pfdtab The file descriptor table. 197 * @param fd The file descriptor number. 198 * @param ptmp See shmtx_enter. 199 */ 200 static shfile *shfile_get(shfdtab *pfdtab, int fd, shmtxtmp *ptmp) 201 { 202 shfile *file = NULL; 203 if ( fd >= 0 204 && (unsigned)fd < pfdtab->size) 205 { 206 shmtx_enter(&pfdtab->mtx, ptmp); 207 if ((unsigned)fd < pfdtab->size 208 && pfdtab->tab[fd].fd != -1) 209 file = &pfdtab->tab[fd]; 210 else 211 shmtx_leave(&pfdtab->mtx, ptmp); 212 } 213 if (!file) 214 errno = EBADF; 215 return file; 216 } 217 218 /** 219 * Puts back a file descriptor and releases the table ownership. 220 * 221 * @param pfdtab The file descriptor table. 222 * @param file The file. 223 * @param ptmp See shmtx_leave. 224 */ 225 static void shfile_put(shfdtab *pfdtab, shfile *file, shmtxtmp *ptmp) 226 { 227 shmtx_leave(&pfdtab->mtx, ptmp); 228 assert(file); 229 (void)file; 230 } 231 232 233 /** 234 * Constructs a path from the current directory and the passed in path. 235 * 236 * @returns 0 on success, -1 and errno set to ENAMETOOLONG or EINVAL on failure. 237 * 238 * @param pfdtab The file descriptor table 239 * @param path The path the caller supplied. 240 * @param buf Where to put the path. This is assumed to be SHFILE_MAX_PATH 241 * chars in size. 242 */ 243 int shfile_make_path(shfdtab *pfdtab, const char *path, char *buf) 244 { 245 size_t path_len = strlen(path); 246 if (path_len == 0) 247 { 248 errno = EINVAL; 249 return -1; 250 } 251 if (path_len >= SHFILE_MAX_PATH) 252 { 253 errno = ENAMETOOLONG; 254 return -1; 255 } 256 if ( *path == '/' 257 #if K_OS == K_OS_WINDOWS || K_OS == K_OS_OS2 258 || *path == '\\' 259 || ( !*path 260 && path[1] == ':' 261 && ( (*path >= 'A' && *path <= 'Z') 262 || (*path >= 'a' && *path <= 'z'))) 263 #endif 264 ) 265 { 266 memcpy(buf, path, path_len + 1); 267 } 268 else 269 { 270 size_t cwd_len; 271 shmtxtmp tmp; 272 273 shmtx_enter(&pfdtab->mtx, &tmp); 274 275 cwd_len = strlen(pfdtab->cwd); 276 memcpy(buf, pfdtab->cwd, cwd_len); 277 278 shmtx_leave(&pfdtab->mtx, &tmp); 279 280 if (cwd_len + path_len + 1 >= SHFILE_MAX_PATH) 281 { 282 errno = ENAMETOOLONG; 283 return -1; 284 } 285 if ( !cwd_len 286 || buf[cwd_len - 1] != '/') 287 buf[cwd_len++] = '/'; 288 memcpy(buf + cwd_len, path, path_len + 1); 289 } 290 291 #if K_OS == K_OS_WINDOWS || K_OS == K_OS_OS2 292 if (!strcmp(buf, "/dev/null")) 293 strcpy(buf, "NUL"); 294 #endif 295 return 0; 296 } 297 298 # if K_OS == K_OS_WINDOWS 299 /** 300 * Converts a DOS(/Windows) error code to errno, 301 * assigning it to errno. 302 * 303 * @returns -1 304 * @param err The DOS error. 305 */ 306 static int shfile_dos2errno(int err) 307 { 308 switch (err) 309 { 310 case ERROR_BAD_ENVIRONMENT: errno = E2BIG; break; 311 case ERROR_ACCESS_DENIED: errno = EACCES; break; 312 case ERROR_CURRENT_DIRECTORY: errno = EACCES; break; 313 case ERROR_LOCK_VIOLATION: errno = EACCES; break; 314 case ERROR_NETWORK_ACCESS_DENIED: errno = EACCES; break; 315 case ERROR_CANNOT_MAKE: errno = EACCES; break; 316 case ERROR_FAIL_I24: errno = EACCES; break; 317 case ERROR_DRIVE_LOCKED: errno = EACCES; break; 318 case ERROR_SEEK_ON_DEVICE: errno = EACCES; break; 319 case ERROR_NOT_LOCKED: errno = EACCES; break; 320 case ERROR_LOCK_FAILED: errno = EACCES; break; 321 case ERROR_NO_PROC_SLOTS: errno = EAGAIN; break; 322 case ERROR_MAX_THRDS_REACHED: errno = EAGAIN; break; 323 case ERROR_NESTING_NOT_ALLOWED: errno = EAGAIN; break; 324 case ERROR_INVALID_HANDLE: errno = EBADF; break; 325 case ERROR_INVALID_TARGET_HANDLE: errno = EBADF; break; 326 case ERROR_DIRECT_ACCESS_HANDLE: errno = EBADF; break; 327 case ERROR_WAIT_NO_CHILDREN: errno = ECHILD; break; 328 case ERROR_CHILD_NOT_COMPLETE: errno = ECHILD; break; 329 case ERROR_FILE_EXISTS: errno = EEXIST; break; 330 case ERROR_ALREADY_EXISTS: errno = EEXIST; break; 331 case ERROR_INVALID_FUNCTION: errno = EINVAL; break; 332 case ERROR_INVALID_ACCESS: errno = EINVAL; break; 333 case ERROR_INVALID_DATA: errno = EINVAL; break; 334 case ERROR_INVALID_PARAMETER: errno = EINVAL; break; 335 case ERROR_NEGATIVE_SEEK: errno = EINVAL; break; 336 case ERROR_TOO_MANY_OPEN_FILES: errno = EMFILE; break; 337 case ERROR_FILE_NOT_FOUND: errno = ENOENT; break; 338 case ERROR_PATH_NOT_FOUND: errno = ENOENT; break; 339 case ERROR_INVALID_DRIVE: errno = ENOENT; break; 340 case ERROR_NO_MORE_FILES: errno = ENOENT; break; 341 case ERROR_BAD_NETPATH: errno = ENOENT; break; 342 case ERROR_BAD_NET_NAME: errno = ENOENT; break; 343 case ERROR_BAD_PATHNAME: errno = ENOENT; break; 344 case ERROR_FILENAME_EXCED_RANGE: errno = ENOENT; break; 345 case ERROR_BAD_FORMAT: errno = ENOEXEC; break; 346 case ERROR_ARENA_TRASHED: errno = ENOMEM; break; 347 case ERROR_NOT_ENOUGH_MEMORY: errno = ENOMEM; break; 348 case ERROR_INVALID_BLOCK: errno = ENOMEM; break; 349 case ERROR_NOT_ENOUGH_QUOTA: errno = ENOMEM; break; 350 case ERROR_DISK_FULL: errno = ENOSPC; break; 351 case ERROR_DIR_NOT_EMPTY: errno = ENOTEMPTY; break; 352 case ERROR_BROKEN_PIPE: errno = EPIPE; break; 353 case ERROR_NOT_SAME_DEVICE: errno = EXDEV; break; 354 default: errno = EINVAL; break; 355 } 356 return -1; 357 } 358 # endif /* K_OS == K_OS_WINDOWS */ 359 360 #endif /* SHFILE_IN_USE */ 361 362 /** 363 * Initializes a file descriptor table. 364 * 365 * @returns 0 on success, -1 and errno on failure. 366 * @param pfdtab The table to initialize. 367 * @param inherit File descriptor table to inherit from. If not specified 368 * we will inherit from the current process as it were. 369 */ 370 int shfile_init(shfdtab *pfdtab, shfdtab *inherit) 371 { 372 int rc; 373 374 pfdtab->cwd = NULL; 375 pfdtab->size = 0; 376 pfdtab->tab = NULL; 377 rc = shmtx_init(&pfdtab->mtx); 378 if (!rc) 379 { 380 #ifdef SHFILE_IN_USE 381 char buf[SHFILE_MAX_PATH]; 382 if (getcwd(buf, sizeof(buf))) 383 { 384 pfdtab->cwd = strdup(buf); 385 if (!inherit) 386 { 387 # if K_OS == K_OS_WINDOWS 388 static const struct 389 { 390 DWORD dwStdHandle; 391 unsigned flags; 392 } aStdHandles[3] = 393 { 394 { STD_INPUT_HANDLE, _O_RDONLY }, 395 { STD_OUTPUT_HANDLE, _O_WRONLY }, 396 { STD_ERROR_HANDLE, _O_WRONLY } 397 }; 398 unsigned i; 399 STARTUPINFO Info; 400 401 rc = 0; 402 403 /* Try pick up the Visual C++ CRT file descriptor info. */ 404 __try { 405 GetStartupInfo(&Info); 406 } __except (EXCEPTION_EXECUTE_HANDLER) { 407 memset(&Info, 0, sizeof(Info)); 408 } 409 if ( Info.cbReserved2 <= sizeof(int) 410 && (uintptr_t)Info.lpReserved2 >= 0x1000 411 && *(int *)Info.lpReserved2 * (sizeof(int) + sizeof(intptr_t)) + 4 <= Info.cbReserved2 412 && *(int *)Info.lpReserved2 <= 2048 413 && *(int *)Info.lpReserved2 >= 1) 414 { 415 unsigned c = *(int *)Info.lpReserved2; 416 char *aosfile = (char *)Info.lpReserved2 + sizeof(int); 417 intptr_t *aosfhnd = (intptr_t *)(aosfile + c); 418 419 /** @todo process */ 420 421 } 422 423 /* Check the three standard handles. */ 424 for (i = 0; i < 3; i++) 425 { 426 HANDLE hFile = GetStdHandle(aStdHandles[i].dwStdHandle); 427 if ( hFile != INVALID_HANDLE_VALUE 428 && ( (unsigned)i >= pfdtab->size 429 || pfdtab->tab[i].fd == -1)) 430 { 431 int fd2 = shfile_insert(pfdtab, (intptr_t)hFile, aStdHandles[i].flags, i, "shtab_init"); 432 assert(fd2 == i); (void)fd2; 433 if (fd2 != i) 434 rc = -1; 435 } 436 } 437 # else 438 # endif 439 } 440 else 441 { 442 /** @todo */ 443 errno = ENOSYS; 444 rc = -1; 445 } 446 } 447 else 448 rc = -1; 449 #endif 450 } 451 return rc; 452 } 453 454 /** 455 * open(). 456 */ 48 457 int shfile_open(shfdtab *pfdtab, const char *name, unsigned flags, mode_t mode) 49 458 { 50 459 int fd; 51 52 #ifdef SH_PURE_STUB_MODE 460 #ifdef SHFILE_IN_USE 461 char absname[SHFILE_MAX_PATH]; 462 # if K_OS == K_OS_WINDOWS 463 HANDLE hFile; 464 DWORD dwDesiredAccess; 465 DWORD dwShareMode; 466 DWORD dwCreationDisposition; 467 DWORD dwFlagsAndAttributes; 468 SECURITY_ATTRIBUTES SecurityAttributes; 469 470 # ifndef _O_ACCMODE 471 # define _O_ACCMODE (_O_RDONLY|_O_WRONLY|_O_RDWR) 472 # endif 473 switch (flags & (_O_ACCMODE | _O_APPEND)) 474 { 475 case _O_RDONLY: dwDesiredAccess = GENERIC_READ; break; 476 case _O_RDONLY | _O_APPEND: dwDesiredAccess = GENERIC_READ; break; 477 case _O_WRONLY: dwDesiredAccess = GENERIC_WRITE; break; 478 case _O_WRONLY | _O_APPEND: dwDesiredAccess = (FILE_GENERIC_WRITE & ~FILE_WRITE_DATA); break; 479 case _O_RDWR: dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; break; 480 case _O_RDWR | _O_APPEND: dwDesiredAccess = GENERIC_READ | (FILE_GENERIC_WRITE & ~FILE_WRITE_DATA); break; 481 482 default: 483 RETURN_ERROR(-1, EINVAL, "invalid mode"); 484 } 485 486 dwShareMode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE; 487 488 SecurityAttributes.nLength = sizeof(SecurityAttributes); 489 SecurityAttributes.lpSecurityDescriptor = NULL; 490 SecurityAttributes.bInheritHandle = (flags & _O_NOINHERIT) == 0; 491 492 if (flags & _O_CREAT) 493 { 494 if ((flags & (_O_EXCL | _O_TRUNC)) == (_O_EXCL | _O_TRUNC)) 495 RETURN_ERROR(-1, EINVAL, "_O_EXCL | _O_TRUNC"); 496 497 if (flags & _O_TRUNC) 498 dwCreationDisposition = CREATE_ALWAYS; /* not 100%, but close enough */ 499 else if (flags & _O_EXCL) 500 dwCreationDisposition = CREATE_NEW; 501 else 502 dwCreationDisposition = OPEN_ALWAYS; 503 } 504 else if (flags & _O_TRUNC) 505 dwCreationDisposition = TRUNCATE_EXISTING; 506 else 507 dwCreationDisposition = OPEN_EXISTING; 508 509 if (!(flags & _O_CREAT) || (mode & 0222)) 510 dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; 511 else 512 dwFlagsAndAttributes = FILE_ATTRIBUTE_READONLY; 513 514 fd = shfile_make_path(pfdtab, name, &absname[0]); 515 if (!fd) 516 { 517 SetLastError(0); 518 hFile = CreateFileA(absname, 519 dwDesiredAccess, 520 dwShareMode, 521 &SecurityAttributes, 522 dwCreationDisposition, 523 dwFlagsAndAttributes, 524 NULL /* hTemplateFile */); 525 if (hFile != INVALID_HANDLE_VALUE) 526 fd = shfile_insert(pfdtab, (intptr_t)hFile, flags, -1, "shfile_open"); 527 else 528 fd = shfile_dos2errno(GetLastError()); 529 } 530 531 # else /* K_OS != K_OS_WINDOWS */ 532 fd = shfile_make_path(pfdtab, name, &absname[0]); 533 if (!fd) 534 { 535 fd = open(absname, flag, mode); 536 if (fd != -1) 537 { 538 int native = fcntl(fd, F_DUPFD, SHFILE_UNIX_MIN_FD); 539 int s = errno; 540 close(fd); 541 errno = s; 542 if (native != -1) 543 fd = shfile_insert(pfdtab, native, flags, -1, "shfile_open"); 544 else 545 fd = -1; 546 } 547 } 548 549 # endif /* K_OS != K_OS_WINDOWS */ 550 551 #elif defined(SH_PURE_STUB_MODE) 53 552 fd = -1; 54 #elif defined(SH_STUB_MODE) 553 errno = ENOSYS; 554 555 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 55 556 fd = open(name, flags, mode); 56 #else57 557 #endif 58 558 … … 69 569 return -1; 70 570 71 #elif defined(SH_STUB_MODE) 571 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 72 572 # ifdef _MSC_VER 73 573 return _pipe(fds, PIPE_BUF, O_BINARY); … … 86 586 rc = -1; 87 587 88 #elif defined(SH_STUB_MODE) 588 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 89 589 rc = dup(fd); 90 590 … … 96 596 } 97 597 598 /** 599 * close(). 600 */ 98 601 int shfile_close(shfdtab *pfdtab, unsigned fd) 99 602 { 100 int rc; 101 102 #ifdef SH_PURE_STUB_MODE 603 int rc; 604 #ifdef SHFILE_IN_USE 605 shmtxtmp tmp; 606 shfile *file = shfile_get(pfdtab, fd, &tmp); 607 if (file) 608 { 609 shfile_native_close(file->native, file->flags); 610 611 file->fd = -1; 612 file->flags = 0; 613 file->native = -1; 614 615 shfile_put(pfdtab, file, &tmp); 616 rc = 0; 617 } 618 else 619 rc = -1; 620 621 #elif defined(SH_PURE_STUB_MODE) 103 622 rc = -1; 104 623 105 #elif defined(SH_STUB_MODE) 624 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 106 625 rc = close(fd); 107 108 #else109 626 #endif 110 627 … … 113 630 } 114 631 632 /** 633 * read(). 634 */ 115 635 long shfile_read(shfdtab *pfdtab, int fd, void *buf, size_t len) 116 636 { 117 #ifdef SH_PURE_STUB_MODE 118 return -1; 119 120 #elif defined(SH_STUB_MODE) 637 long rc; 638 #ifdef SHFILE_IN_USE 639 shmtxtmp tmp; 640 shfile *file = shfile_get(pfdtab, fd, &tmp); 641 if (file) 642 { 643 # if K_OS == K_OS_WINDOWS 644 DWORD dwRead = 0; 645 if (ReadFile((HANDLE)file->native, buf, (DWORD)len, &dwRead, NULL)) 646 rc = dwRead; 647 else 648 rc = shfile_dos2errno(GetLastError()); 649 # else 650 rc = read(file->native, buf, len); 651 # endif 652 653 shfile_put(pfdtab, file, &tmp); 654 } 655 else 656 rc = -1; 657 658 #elif defined(SH_PURE_STUB_MODE) 659 rc = -1; 660 661 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 121 662 # ifdef _MSC_VER 122 return read(fd, buf, (unsigned)len); 123 # else 124 return read(fd, buf, len); 125 # endif 126 127 #else 128 #endif 129 } 130 663 rc = read(fd, buf, (unsigned)len); 664 # else 665 rc = read(fd, buf, len); 666 # endif 667 #endif 668 return rc; 669 } 670 671 /** 672 * write(). 673 */ 131 674 long shfile_write(shfdtab *pfdtab, int fd, const void *buf, size_t len) 132 675 { 133 #ifdef SH_PURE_STUB_MODE 134 return -1; 135 136 #elif defined(SH_STUB_MODE) 676 long rc; 677 #ifdef SHFILE_IN_USE 678 shmtxtmp tmp; 679 shfile *file = shfile_get(pfdtab, fd, &tmp); 680 if (file) 681 { 682 # if K_OS == K_OS_WINDOWS 683 DWORD dwWritten = 0; 684 if (WriteFile((HANDLE)file->native, buf, (DWORD)len, &dwWritten, NULL)) 685 rc = dwWritten; 686 else 687 rc = shfile_dos2errno(GetLastError()); 688 # else 689 rc = write(file->native, buf, len); 690 # endif 691 692 shfile_put(pfdtab, file, &tmp); 693 } 694 else 695 rc = -1; 696 697 #elif defined(SH_PURE_STUB_MODE) 698 rc = -1; 699 700 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 137 701 # ifdef _MSC_VER 138 return write(fd, buf, (unsigned)len); 139 # else 140 return write(fd, buf, len); 141 # endif 142 143 #else 144 #endif 145 } 146 702 rc = write(fd, buf, (unsigned)len); 703 # else 704 rc = write(fd, buf, len); 705 # endif 706 #endif 707 return rc; 708 } 709 710 /** 711 * lseek(). 712 */ 147 713 long shfile_lseek(shfdtab *pfdtab, int fd, long off, int whench) 148 714 { 149 #ifdef SH_PURE_STUB_MODE 150 return -1; 151 152 #elif defined(SH_STUB_MODE) 153 return lseek(fd, off, whench); 154 155 #else 156 #endif 715 long rc; 716 #ifdef SHFILE_IN_USE 717 shmtxtmp tmp; 718 shfile *file = shfile_get(pfdtab, fd, &tmp); 719 if (file) 720 { 721 # if K_OS == K_OS_WINDOWS 722 assert(SEEK_SET == FILE_BEGIN); 723 assert(SEEK_CUR == FILE_CURRENT); 724 assert(SEEK_END == FILE_END); 725 rc = SetFilePointer((HANDLE)file->native, off, NULL, whench); 726 if (rc == INVALID_SET_FILE_POINTER) 727 rc = shfile_dos2errno(GetLastError()); 728 # else 729 rc = lseek(file->native, off, whench); 730 # endif 731 732 shfile_put(pfdtab, file, &tmp); 733 } 734 else 735 rc = -1; 736 737 #elif defined(SH_PURE_STUB_MODE) 738 rc = -1; 739 740 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 741 rc = lseek(fd, off, whench); 742 #endif 743 744 return rc; 157 745 } 158 746 … … 160 748 { 161 749 int rc; 162 #ifdef SH_PURE_STUB_MODE 750 #ifdef SHFILE_IN_USE 751 shmtxtmp tmp; 752 shfile *file = shfile_get(pfdtab, fd, &tmp); 753 if (file) 754 { 755 switch (cmd) 756 { 757 case F_GETFL: 758 rc = file->flags; 759 break; 760 761 case F_SETFL: 762 { 763 unsigned mask = O_NONBLOCK | O_APPEND | O_BINARY | O_TEXT; 764 # ifdef O_DIRECT 765 mask |= O_DIRECT; 766 # endif 767 # ifdef O_ASYNC 768 mask |= O_ASYNC; 769 # endif 770 # ifdef O_SYNC 771 mask |= O_SYNC; 772 # endif 773 if ((file->flags & mask) == (arg & mask)) 774 rc = 0; 775 else 776 { 777 # if K_OS == K_OS_WINDOWS 778 assert(0); 779 errno = EINVAL; 780 rc = -1; 781 # else 782 rc = fcntl(file->native, F_SETFL, arg); 783 if (rc != -1) 784 file->flags = (file->flags & ~mask) | (arg & mask); 785 # endif 786 } 787 break; 788 } 789 790 case F_DUPFD: 791 { 792 # if K_OS == K_OS_WINDOWS 793 HANDLE hNew = INVALID_HANDLE_VALUE; 794 if (DuplicateHandle(GetCurrentProcess(), 795 (HANDLE)file->native, 796 GetCurrentProcess(), 797 &hNew, 798 0, 799 TRUE /* bInheritHandle */, 800 DUPLICATE_SAME_ACCESS)) 801 rc = shfile_insert(pfdtab, (intptr_t)hNew, file->flags, arg, "shfile_fcntl"); 802 else 803 rc = shfile_dos2errno(GetLastError()); 804 # else 805 int nativeNew = fcntl(file->native F_DUPFD, SHFILE_UNIX_MIN_FD); 806 if (nativeNew != -1) 807 rc = shfile_insert(pfdtab, nativeNew, file->flags, arg, "shfile_fcntl"); 808 # endif 809 break; 810 } 811 812 default: 813 errno = -EINVAL; 814 rc = -1; 815 break; 816 } 817 818 shfile_put(pfdtab, file, &tmp); 819 } 820 else 821 rc = -1; 822 823 #elif defined(SH_PURE_STUB_MODE) 163 824 rc = -1; 164 825 … … 194 855 case F_DUPFD: 195 856 { 196 # if 1197 857 /* the brute force approach. */ 198 858 int i = 0; … … 213 873 rc = -1; 214 874 } 215 # else216 /* A much quick approach which is spoiled by crash validation in the CRT. */217 int fdnew = arg;218 rc = -2;219 for (fdnew = arg; fdnew < 1024; fdnew++)220 {221 /* is the file open? */222 errno = 0;223 _isatty(fdnew);224 if (errno == EBADF)225 {226 rc = _dup2(fd, fdnew);227 break;228 }229 }230 if (rc == -2)231 {232 errno = EMFILE;233 rc = -1;234 }235 # endif236 875 break; 237 876 } … … 240 879 rc = fcntl(fd, cmd, arg); 241 880 # endif 242 243 #else244 881 #endif 245 882 … … 270 907 return -1; 271 908 272 #elif defined(SH_STUB_MODE) 909 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 273 910 return stat(path, pst); 274 911 … … 282 919 return -1; 283 920 284 #elif defined(SH_STUB_MODE) 921 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 285 922 # ifdef _MSC_VER 286 923 return stat(link, pst); … … 298 935 return -1; 299 936 300 #elif defined(SH_STUB_MODE) 937 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 301 938 # ifdef _MSC_VER //??? 302 939 return chdir(path); … … 314 951 return NULL; 315 952 316 #elif defined(SH_STUB_MODE) 953 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 317 954 return getcwd(buf, len); 318 955 … … 326 963 return -1; 327 964 328 #elif defined(SH_STUB_MODE) 965 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 329 966 # ifdef _MSC_VER 330 967 type &= ~X_OK; … … 344 981 #ifdef SH_PURE_STUB_MODE 345 982 rc = 0; 346 #elif defined(SH_STUB_MODE) 983 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 347 984 rc = isatty(fd); 348 985 #else … … 361 998 rc = -1; 362 999 363 #elif defined(SH_STUB_MODE) 1000 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 364 1001 # ifdef _MSC_VER 365 1002 errno = ENOSYS; … … 385 1022 rc = -1; 386 1023 387 #elif defined(SH_STUB_MODE) 1024 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 388 1025 # ifdef _MSC_VER 389 1026 errno = ENOSYS; … … 406 1043 return 022; 407 1044 408 #elif defined(SH_STUB_MODE) 1045 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 409 1046 return 022; 410 1047 … … 419 1056 return NULL; 420 1057 421 #elif defined(SH_STUB_MODE) 1058 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 422 1059 # ifdef _MSC_VER 423 1060 errno = ENOSYS; … … 436 1073 return NULL; 437 1074 438 #elif defined(SH_STUB_MODE) 1075 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 439 1076 # ifdef _MSC_VER 440 1077 errno = ENOSYS; … … 454 1091 return NULL; 455 1092 456 #elif defined(SH_STUB_MODE) 1093 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 457 1094 # ifdef _MSC_VER 458 1095 errno = ENOSYS;
Note:
See TracChangeset
for help on using the changeset viewer.