223 } |
223 } |
224 |
224 |
225 jlong |
225 jlong |
226 winFileHandleOpen(JNIEnv *env, jstring path, int flags) |
226 winFileHandleOpen(JNIEnv *env, jstring path, int flags) |
227 { |
227 { |
228 /* To implement O_APPEND, we use the strategy from |
|
229 http://msdn2.microsoft.com/en-us/library/aa363858.aspx |
|
230 "You can get atomic append by opening a file with |
|
231 FILE_APPEND_DATA access and _without_ FILE_WRITE_DATA access. |
|
232 If you do this then all writes will ignore the current file |
|
233 pointer and be done at the end-of file." */ |
|
234 const DWORD access = |
228 const DWORD access = |
235 (flags & O_APPEND) ? (FILE_GENERIC_WRITE & ~FILE_WRITE_DATA) : |
|
236 (flags & O_WRONLY) ? GENERIC_WRITE : |
229 (flags & O_WRONLY) ? GENERIC_WRITE : |
237 (flags & O_RDWR) ? (GENERIC_READ | GENERIC_WRITE) : |
230 (flags & O_RDWR) ? (GENERIC_READ | GENERIC_WRITE) : |
238 GENERIC_READ; |
231 GENERIC_READ; |
239 const DWORD sharing = |
232 const DWORD sharing = |
240 FILE_SHARE_READ | FILE_SHARE_WRITE; |
233 FILE_SHARE_READ | FILE_SHARE_WRITE; |
509 return -1; |
502 return -1; |
510 } |
503 } |
511 return read; |
504 return read; |
512 } |
505 } |
513 |
506 |
514 JNIEXPORT |
507 static size_t writeInternal(jlong fd, const void *buf, jint len, jboolean append) |
515 size_t |
|
516 handleWrite(jlong fd, const void *buf, jint len) |
|
517 { |
508 { |
518 BOOL result = 0; |
509 BOOL result = 0; |
519 DWORD written = 0; |
510 DWORD written = 0; |
520 HANDLE h = (HANDLE)fd; |
511 HANDLE h = (HANDLE)fd; |
521 if (h != INVALID_HANDLE_VALUE) { |
512 if (h != INVALID_HANDLE_VALUE) { |
522 result = WriteFile(h, /* File handle to write */ |
513 OVERLAPPED ov; |
523 buf, /* pointers to the buffers */ |
514 LPOVERLAPPED lpOv; |
524 len, /* number of bytes to write */ |
515 if (append == JNI_TRUE) { |
525 &written, /* receives number of bytes written */ |
516 ov.Offset = (DWORD)0xFFFFFFFF; |
526 NULL); /* no overlapped struct */ |
517 ov.OffsetHigh = (DWORD)0xFFFFFFFF; |
|
518 ov.hEvent = NULL; |
|
519 lpOv = &ov; |
|
520 } else { |
|
521 lpOv = NULL; |
|
522 } |
|
523 result = WriteFile(h, /* File handle to write */ |
|
524 buf, /* pointers to the buffers */ |
|
525 len, /* number of bytes to write */ |
|
526 &written, /* receives number of bytes written */ |
|
527 lpOv); /* overlapped struct */ |
527 } |
528 } |
528 if ((h == INVALID_HANDLE_VALUE) || (result == 0)) { |
529 if ((h == INVALID_HANDLE_VALUE) || (result == 0)) { |
529 return -1; |
530 return -1; |
530 } |
531 } |
531 return written; |
532 return (size_t)written; |
|
533 } |
|
534 |
|
535 JNIEXPORT |
|
536 size_t handleWrite(jlong fd, const void *buf, jint len) { |
|
537 return writeInternal(fd, buf, len, JNI_FALSE); |
|
538 } |
|
539 |
|
540 JNIEXPORT |
|
541 size_t handleAppend(jlong fd, const void *buf, jint len) { |
|
542 return writeInternal(fd, buf, len, JNI_TRUE); |
532 } |
543 } |
533 |
544 |
534 jint |
545 jint |
535 handleClose(JNIEnv *env, jobject this, jfieldID fid) |
546 handleClose(JNIEnv *env, jobject this, jfieldID fid) |
536 { |
547 { |