blob: c9d46d174259f42a3e2a2eb073475aba517044be [file] [log] [blame]
Junio C Hamano4050c0d2005-12-05 11:54:29 -08001#include "../git-compat-util.h"
Johannes Schindelin730d48a2005-10-08 15:54:36 -07002
Shawn O. Pearced6779122006-12-24 00:45:37 -05003void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
Johannes Schindelin730d48a2005-10-08 15:54:36 -07004{
Shawn O. Pearce8e554422006-12-24 00:45:47 -05005 size_t n = 0;
Johannes Schindelin730d48a2005-10-08 15:54:36 -07006
Junio C Hamanof48000f2005-10-08 15:54:36 -07007 if (start != NULL || !(flags & MAP_PRIVATE))
Shawn O. Pearced6779122006-12-24 00:45:37 -05008 die("Invalid usage of mmap when built with NO_MMAP");
Johannes Schindelin730d48a2005-10-08 15:54:36 -07009
Johannes Schindelin730d48a2005-10-08 15:54:36 -070010 start = xmalloc(length);
Junio C Hamanof48000f2005-10-08 15:54:36 -070011 if (start == NULL) {
Johannes Schindelin730d48a2005-10-08 15:54:36 -070012 errno = ENOMEM;
13 return MAP_FAILED;
14 }
15
Junio C Hamanof48000f2005-10-08 15:54:36 -070016 while (n < length) {
Shawn O. Pearce8e554422006-12-24 00:45:47 -050017 ssize_t count = pread(fd, (char *)start + n, length - n, offset + n);
Johannes Schindelin730d48a2005-10-08 15:54:36 -070018
Junio C Hamanof48000f2005-10-08 15:54:36 -070019 if (count == 0) {
Shawn O. Pearce8e554422006-12-24 00:45:47 -050020 memset((char *)start+n, 0, length-n);
Johannes Schindelin730d48a2005-10-08 15:54:36 -070021 break;
22 }
23
Junio C Hamanof48000f2005-10-08 15:54:36 -070024 if (count < 0) {
Shawn O. Pearce8e554422006-12-24 00:45:47 -050025 if (errno == EAGAIN || errno == EINTR)
26 continue;
Johannes Schindelin730d48a2005-10-08 15:54:36 -070027 free(start);
28 errno = EACCES;
29 return MAP_FAILED;
30 }
31
32 n += count;
33 }
34
Johannes Schindelin730d48a2005-10-08 15:54:36 -070035 return start;
36}
37
Shawn O. Pearced6779122006-12-24 00:45:37 -050038int git_munmap(void *start, size_t length)
Johannes Schindelin730d48a2005-10-08 15:54:36 -070039{
Johannes Schindelin730d48a2005-10-08 15:54:36 -070040 free(start);
Johannes Schindelin730d48a2005-10-08 15:54:36 -070041 return 0;
42}