@@ -981,3 +981,73 @@ int p_inet_pton(int af, const char *src, void *dst)
981981 errno = EINVAL ;
982982 return -1 ;
983983}
984+
985+ ssize_t p_pread (int fd , void * data , size_t size , off64_t offset )
986+ {
987+ HANDLE fh ;
988+ DWORD rsize = 0 ;
989+ OVERLAPPED ov = {0 };
990+ LARGE_INTEGER pos = {0 };
991+ off64_t final_offset = 0 ;
992+
993+ /* Fail if the final offset would have overflowed to match POSIX semantics. */
994+ if (!git__is_ssizet (size ) || git__add_int64_overflow (& final_offset , offset , (int64_t )size )) {
995+ errno = EINVAL ;
996+ return -1 ;
997+ }
998+
999+ /*
1000+ * Truncate large writes to the maximum allowable size: the caller
1001+ * needs to always call this in a loop anyways.
1002+ */
1003+ if (size > INT32_MAX ) {
1004+ size = INT32_MAX ;
1005+ }
1006+
1007+ pos .QuadPart = offset ;
1008+ ov .Offset = pos .LowPart ;
1009+ ov .OffsetHigh = pos .HighPart ;
1010+ fh = (HANDLE )_get_osfhandle (fd );
1011+
1012+ if (ReadFile (fh , data , (DWORD )size , & rsize , & ov )) {
1013+ return (ssize_t )rsize ;
1014+ }
1015+
1016+ set_errno ();
1017+ return -1 ;
1018+ }
1019+
1020+ ssize_t p_pwrite (int fd , const void * data , size_t size , off64_t offset )
1021+ {
1022+ HANDLE fh ;
1023+ DWORD wsize = 0 ;
1024+ OVERLAPPED ov = {0 };
1025+ LARGE_INTEGER pos = {0 };
1026+ off64_t final_offset = 0 ;
1027+
1028+ /* Fail if the final offset would have overflowed to match POSIX semantics. */
1029+ if (!git__is_ssizet (size ) || git__add_int64_overflow (& final_offset , offset , (int64_t )size )) {
1030+ errno = EINVAL ;
1031+ return -1 ;
1032+ }
1033+
1034+ /*
1035+ * Truncate large writes to the maximum allowable size: the caller
1036+ * needs to always call this in a loop anyways.
1037+ */
1038+ if (size > INT32_MAX ) {
1039+ size = INT32_MAX ;
1040+ }
1041+
1042+ pos .QuadPart = offset ;
1043+ ov .Offset = pos .LowPart ;
1044+ ov .OffsetHigh = pos .HighPart ;
1045+ fh = (HANDLE )_get_osfhandle (fd );
1046+
1047+ if (WriteFile (fh , data , (DWORD )size , & wsize , & ov )) {
1048+ return (ssize_t )wsize ;
1049+ }
1050+
1051+ set_errno ();
1052+ return -1 ;
1053+ }
0 commit comments