-
Notifications
You must be signed in to change notification settings - Fork 174
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Lwt_unix.pread and pwrite (#768)
Resolves #767.
- Loading branch information
Showing
13 changed files
with
577 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* This file is part of Lwt, released under the MIT license. See LICENSE.md for | ||
details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. */ | ||
|
||
|
||
|
||
#include "lwt_config.h" | ||
|
||
#if !defined(LWT_ON_WINDOWS) | ||
|
||
#include <caml/mlvalues.h> | ||
#include <caml/unixsupport.h> | ||
|
||
CAMLprim value lwt_unix_pread(value val_fd, value val_buf, value val_file_ofs, | ||
value val_ofs, value val_len) | ||
{ | ||
long ret; | ||
ret = pread(Int_val(val_fd), &Byte(String_val(val_buf), Long_val(val_ofs)), | ||
Long_val(val_len), Long_val(val_file_ofs)); | ||
if (ret == -1) uerror("pread", Nothing); | ||
return Val_long(ret); | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/* This file is part of Lwt, released under the MIT license. See LICENSE.md for | ||
details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. */ | ||
|
||
|
||
|
||
#include "lwt_config.h" | ||
|
||
#if !defined(LWT_ON_WINDOWS) | ||
|
||
#include <caml/alloc.h> | ||
#include <caml/memory.h> | ||
#include <caml/mlvalues.h> | ||
#include <caml/unixsupport.h> | ||
#include <caml/version.h> | ||
#include <errno.h> | ||
#include <string.h> | ||
|
||
#include "lwt_unix.h" | ||
|
||
#if OCAML_VERSION < 40600 | ||
#define Bytes_val(x) String_val(x) | ||
#endif | ||
|
||
struct job_pread { | ||
struct lwt_unix_job job; | ||
/* The file descriptor. */ | ||
int fd; | ||
/* The amount of data to read. */ | ||
long length; | ||
/* The offset in the file */ | ||
off_t file_offset; | ||
/* The OCaml string. */ | ||
value string; | ||
/* The offset in the string. */ | ||
long offset; | ||
/* The result of the pread syscall. */ | ||
long result; | ||
/* The value of errno. */ | ||
int error_code; | ||
/* The temporary buffer. */ | ||
char buffer[]; | ||
}; | ||
|
||
static void worker_pread(struct job_pread *job) | ||
{ | ||
job->result = pread(job->fd, job->buffer, job->length, job->file_offset); | ||
job->error_code = errno; | ||
} | ||
|
||
static value result_pread(struct job_pread *job) | ||
{ | ||
long result = job->result; | ||
if (result < 0) { | ||
int error_code = job->error_code; | ||
caml_remove_generational_global_root(&(job->string)); | ||
lwt_unix_free_job(&job->job); | ||
unix_error(error_code, "pread", Nothing); | ||
} else { | ||
memcpy(Bytes_val(job->string) + job->offset, job->buffer, result); | ||
caml_remove_generational_global_root(&(job->string)); | ||
lwt_unix_free_job(&job->job); | ||
return Val_long(result); | ||
} | ||
} | ||
|
||
CAMLprim value lwt_unix_pread_job(value val_fd, value val_buffer, | ||
value val_file_offset, value val_offset, | ||
value val_length) | ||
{ | ||
long length = Long_val(val_length); | ||
LWT_UNIX_INIT_JOB(job, pread, length); | ||
job->fd = Int_val(val_fd); | ||
job->length = length; | ||
job->file_offset = Long_val(val_file_offset); | ||
job->string = val_buffer; | ||
job->offset = Long_val(val_offset); | ||
caml_register_generational_global_root(&(job->string)); | ||
return lwt_unix_alloc_job(&(job->job)); | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* This file is part of Lwt, released under the MIT license. See LICENSE.md for | ||
details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. */ | ||
|
||
|
||
|
||
#include "lwt_config.h" | ||
|
||
#if !defined(LWT_ON_WINDOWS) | ||
|
||
#include <caml/mlvalues.h> | ||
#include <caml/unixsupport.h> | ||
#include <unistd.h> | ||
|
||
CAMLprim value lwt_unix_pwrite(value val_fd, value val_buf, value val_file_ofs, | ||
value val_ofs, value val_len) | ||
{ | ||
long ret; | ||
ret = pwrite(Int_val(val_fd), &Byte(String_val(val_buf), Long_val(val_ofs)), | ||
Long_val(val_len), Long_val(val_file_ofs)); | ||
if (ret == -1) uerror("pwrite", Nothing); | ||
return Val_long(ret); | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* This file is part of Lwt, released under the MIT license. See LICENSE.md for | ||
details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. */ | ||
|
||
|
||
|
||
#include "lwt_config.h" | ||
|
||
#if !defined(LWT_ON_WINDOWS) | ||
|
||
#include <caml/mlvalues.h> | ||
#include <caml/unixsupport.h> | ||
#include <errno.h> | ||
#include <string.h> | ||
|
||
#include "lwt_unix.h" | ||
|
||
struct job_pwrite { | ||
struct lwt_unix_job job; | ||
int fd; | ||
long length; | ||
off_t file_offset; | ||
long result; | ||
int error_code; | ||
char buffer[]; | ||
}; | ||
|
||
static void worker_pwrite(struct job_pwrite *job) | ||
{ | ||
job->result = pwrite(job->fd, job->buffer, job->length, job->file_offset); | ||
job->error_code = errno; | ||
} | ||
|
||
static value result_pwrite(struct job_pwrite *job) | ||
{ | ||
long result = job->result; | ||
LWT_UNIX_CHECK_JOB(job, result < 0, "pwrite"); | ||
lwt_unix_free_job(&job->job); | ||
return Val_long(result); | ||
} | ||
|
||
CAMLprim value lwt_unix_pwrite_job(value val_fd, value val_string, | ||
value val_file_offset, value val_offset, | ||
value val_length) | ||
{ | ||
long length = Long_val(val_length); | ||
LWT_UNIX_INIT_JOB(job, pwrite, length); | ||
job->fd = Int_val(val_fd); | ||
job->length = length; | ||
job->file_offset = Long_val(val_file_offset); | ||
memcpy(job->buffer, String_val(val_string) + Long_val(val_offset), length); | ||
return lwt_unix_alloc_job(&(job->job)); | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* This file is part of Lwt, released under the MIT license. See LICENSE.md for | ||
details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. */ | ||
|
||
|
||
|
||
#include "lwt_config.h" | ||
|
||
#if defined(LWT_ON_WINDOWS) | ||
|
||
#include <caml/fail.h> | ||
#include <caml/memory.h> | ||
#include <caml/mlvalues.h> | ||
#include <caml/unixsupport.h> | ||
|
||
CAMLprim value lwt_unix_pread(value fd, value buf, value vfile_offset, | ||
value vofs, value vlen) | ||
{ | ||
intnat ofs, len, file_offset, written; | ||
DWORD numbytes, numwritten; | ||
DWORD err = 0; | ||
|
||
Begin_root(buf); | ||
ofs = Long_val(vofs); | ||
len = Long_val(vlen); | ||
file_offset = Long_val(vfile_offset); | ||
written = 0; | ||
if (len > 0) { | ||
numbytes = len; | ||
if (Descr_kind_val(fd) == KIND_SOCKET) { | ||
caml_invalid_argument("Lwt_unix.pread"); | ||
} else { | ||
HANDLE h = Handle_val(fd); | ||
OVERLAPPED overlapped; | ||
memset( &overlapped, 0, sizeof(overlapped)); | ||
overlapped.OffsetHigh = (DWORD)(file_offset >> 32); | ||
overlapped.Offset = (DWORD)(file_offset & 0xFFFFFFFFLL); | ||
if (!ReadFile(h, &Byte(buf, ofs), numbytes, &numwritten, | ||
&overlapped)) | ||
err = GetLastError(); | ||
} | ||
if (err) { | ||
win32_maperr(err); | ||
uerror("pread", Nothing); | ||
} | ||
written = numwritten; | ||
} | ||
End_roots(); | ||
return Val_long(written); | ||
} | ||
#endif |
Oops, something went wrong.