461 return 0; 462 } 463 464 465 int 466 handleSetLength(jlong fd, jlong length) { 467 HANDLE h = (HANDLE)fd; 468 long high = (long)(length >> 32); 469 DWORD ret; 470 471 if (h == (HANDLE)(-1)) return -1; 472 ret = SetFilePointer(h, (long)(length), &high, FILE_BEGIN); 473 if (ret == 0xFFFFFFFF && GetLastError() != NO_ERROR) { 474 return -1; 475 } 476 if (SetEndOfFile(h) == FALSE) return -1; 477 return 0; 478 } 479 480 JNIEXPORT 481 size_t 482 handleRead(jlong fd, void *buf, jint len) 483 { 484 DWORD read = 0; 485 BOOL result = 0; 486 HANDLE h = (HANDLE)fd; 487 if (h == INVALID_HANDLE_VALUE) { 488 return -1; 489 } 490 result = ReadFile(h, /* File handle to read */ 491 buf, /* address to put data */ 492 len, /* number of bytes to read */ 493 &read, /* number of bytes read */ 494 NULL); /* no overlapped struct */ 495 if (result == 0) { 496 int error = GetLastError(); 497 if (error == ERROR_BROKEN_PIPE) { 498 return 0; /* EOF */ 499 } 500 return -1; 501 } 502 return read; 503 } 504 505 static size_t writeInternal(jlong fd, const void *buf, jint len, jboolean append) 506 { 507 BOOL result = 0; 508 DWORD written = 0; 509 HANDLE h = (HANDLE)fd; 510 if (h != INVALID_HANDLE_VALUE) { 511 OVERLAPPED ov; 512 LPOVERLAPPED lpOv; 513 if (append == JNI_TRUE) { 514 ov.Offset = (DWORD)0xFFFFFFFF; 515 ov.OffsetHigh = (DWORD)0xFFFFFFFF; 516 ov.hEvent = NULL; 517 lpOv = &ov; 518 } else { 519 lpOv = NULL; 520 } 521 result = WriteFile(h, /* File handle to write */ 522 buf, /* pointers to the buffers */ 523 len, /* number of bytes to write */ 524 &written, /* receives number of bytes written */ 525 lpOv); /* overlapped struct */ 526 } 527 if ((h == INVALID_HANDLE_VALUE) || (result == 0)) { 528 return -1; 529 } 530 return (size_t)written; 531 } 532 533 JNIEXPORT 534 size_t handleWrite(jlong fd, const void *buf, jint len) { 535 return writeInternal(fd, buf, len, JNI_FALSE); 536 } 537 538 JNIEXPORT 539 size_t handleAppend(jlong fd, const void *buf, jint len) { 540 return writeInternal(fd, buf, len, JNI_TRUE); 541 } 542 543 jint 544 handleClose(JNIEnv *env, jobject this, jfieldID fid) 545 { 546 FD fd = GET_FD(this, fid); 547 HANDLE h = (HANDLE)fd; 548 549 if (h == INVALID_HANDLE_VALUE) { 550 return 0; 551 } 552 553 /* Set the fd to -1 before closing it so that the timing window 554 * of other threads using the wrong fd (closed but recycled fd, 555 * that gets re-opened with some other filename) is reduced. 556 * Practically the chance of its occurance is low, however, we are 557 * taking extra precaution over here. 558 */ 559 SET_FD(this, -1, fid); | 461 return 0; 462 } 463 464 465 int 466 handleSetLength(jlong fd, jlong length) { 467 HANDLE h = (HANDLE)fd; 468 long high = (long)(length >> 32); 469 DWORD ret; 470 471 if (h == (HANDLE)(-1)) return -1; 472 ret = SetFilePointer(h, (long)(length), &high, FILE_BEGIN); 473 if (ret == 0xFFFFFFFF && GetLastError() != NO_ERROR) { 474 return -1; 475 } 476 if (SetEndOfFile(h) == FALSE) return -1; 477 return 0; 478 } 479 480 JNIEXPORT 481 jint 482 handleRead(jlong fd, void *buf, jint len) 483 { 484 DWORD read = 0; 485 BOOL result = 0; 486 HANDLE h = (HANDLE)fd; 487 if (h == INVALID_HANDLE_VALUE) { 488 return -1; 489 } 490 result = ReadFile(h, /* File handle to read */ 491 buf, /* address to put data */ 492 len, /* number of bytes to read */ 493 &read, /* number of bytes read */ 494 NULL); /* no overlapped struct */ 495 if (result == 0) { 496 int error = GetLastError(); 497 if (error == ERROR_BROKEN_PIPE) { 498 return 0; /* EOF */ 499 } 500 return -1; 501 } 502 return (jint)read; 503 } 504 505 static jint writeInternal(jlong fd, const void *buf, jint len, jboolean append) 506 { 507 BOOL result = 0; 508 DWORD written = 0; 509 HANDLE h = (HANDLE)fd; 510 if (h != INVALID_HANDLE_VALUE) { 511 OVERLAPPED ov; 512 LPOVERLAPPED lpOv; 513 if (append == JNI_TRUE) { 514 ov.Offset = (DWORD)0xFFFFFFFF; 515 ov.OffsetHigh = (DWORD)0xFFFFFFFF; 516 ov.hEvent = NULL; 517 lpOv = &ov; 518 } else { 519 lpOv = NULL; 520 } 521 result = WriteFile(h, /* File handle to write */ 522 buf, /* pointers to the buffers */ 523 len, /* number of bytes to write */ 524 &written, /* receives number of bytes written */ 525 lpOv); /* overlapped struct */ 526 } 527 if ((h == INVALID_HANDLE_VALUE) || (result == 0)) { 528 return -1; 529 } 530 return (jint)written; 531 } 532 533 JNIEXPORT 534 jint handleWrite(jlong fd, const void *buf, jint len) { 535 return writeInternal(fd, buf, len, JNI_FALSE); 536 } 537 538 JNIEXPORT 539 jint handleAppend(jlong fd, const void *buf, jint len) { 540 return writeInternal(fd, buf, len, JNI_TRUE); 541 } 542 543 jint 544 handleClose(JNIEnv *env, jobject this, jfieldID fid) 545 { 546 FD fd = GET_FD(this, fid); 547 HANDLE h = (HANDLE)fd; 548 549 if (h == INVALID_HANDLE_VALUE) { 550 return 0; 551 } 552 553 /* Set the fd to -1 before closing it so that the timing window 554 * of other threads using the wrong fd (closed but recycled fd, 555 * that gets re-opened with some other filename) is reduced. 556 * Practically the chance of its occurance is low, however, we are 557 * taking extra precaution over here. 558 */ 559 SET_FD(this, -1, fid); |