diff options
author | Alex Budovski <abudovski@gmail.com> | 2011-01-11 16:07:45 +1100 |
---|---|---|
committer | Alex Budovski <abudovski@gmail.com> | 2011-01-11 18:31:55 +1100 |
commit | f0bde7fac0796bb6d7bfe794bd049041f2133905 (patch) | |
tree | 8d0b13c20236ca2faa2017fe9ca4fa69b9efb0a5 | |
parent | e0c23b88c57a5d765e5572d8ed317a4ba4da102a (diff) | |
download | libgit2-f0bde7fac0796bb6d7bfe794bd049041f2133905.tar.gz |
Revised platform types to use 'best supported' size.
This will allow graceful migration to 64 bit file sizes and timestamps should
git's binary interface be extended to allow this.
-rw-r--r-- | src/common.h | 1 | ||||
-rw-r--r-- | src/fileops.c | 6 | ||||
-rw-r--r-- | src/fileops.h | 4 | ||||
-rw-r--r-- | src/git2.h | 1 | ||||
-rw-r--r-- | src/git2/compat.h | 70 | ||||
-rw-r--r-- | src/git2/index.h | 5 | ||||
-rw-r--r-- | src/index.c | 11 | ||||
-rw-r--r-- | src/map.h | 2 | ||||
-rw-r--r-- | src/mingw-compat.h | 1 | ||||
-rw-r--r-- | src/msvc-compat.h | 3 | ||||
-rw-r--r-- | src/odb_pack.c | 32 | ||||
-rw-r--r-- | src/unix/map.c | 2 | ||||
-rw-r--r-- | src/util.h | 4 | ||||
-rw-r--r-- | src/win32/map.c | 8 |
14 files changed, 107 insertions, 43 deletions
diff --git a/src/common.h b/src/common.h index 287df60e2..addad6a98 100644 --- a/src/common.h +++ b/src/common.h @@ -47,6 +47,7 @@ typedef SSIZE_T ssize_t; #endif #include "git2/common.h" +#include "git2/compat.h" #include "util.h" #include "thread-utils.h" #include "bswap.h" diff --git a/src/fileops.c b/src/fileops.c index 68f45c25a..1d680f354 100644 --- a/src/fileops.c +++ b/src/fileops.c @@ -89,7 +89,7 @@ int gitfo_exists(const char *path) return access(path, F_OK); } -off_t gitfo_size(git_file fd) +git_off_t gitfo_size(git_file fd) { struct stat sb; if (gitfo_fstat(fd, &sb)) @@ -101,7 +101,7 @@ int gitfo_read_file(gitfo_buf *obj, const char *path) { git_file fd; size_t len; - off_t size; + git_off_t size; unsigned char *buff; assert(obj && path && *path); @@ -155,7 +155,7 @@ int gitfo_move_file(char *from, char *to) return GIT_EOSERR; } -int gitfo_map_ro(git_map *out, git_file fd, off_t begin, size_t len) +int gitfo_map_ro(git_map *out, git_file fd, git_off_t begin, size_t len) { if (git__mmap(out, len, GIT_PROT_READ, GIT_MAP_SHARED, fd, begin) < GIT_SUCCESS) return GIT_EOSERR; diff --git a/src/fileops.h b/src/fileops.h index 6656cdf43..fa446e36a 100644 --- a/src/fileops.h +++ b/src/fileops.h @@ -64,7 +64,7 @@ extern int gitfo_mkdir_recurs(const char *path, int mode); extern int gitfo_read(git_file fd, void *buf, size_t cnt); extern int gitfo_write(git_file fd, void *buf, size_t cnt); #define gitfo_lseek(f,n,w) lseek(f, n, w) -extern off_t gitfo_size(git_file fd); +extern git_off_t gitfo_size(git_file fd); extern int gitfo_read_file(gitfo_buf *obj, const char *path); extern void gitfo_free_buf(gitfo_buf *obj); @@ -100,7 +100,7 @@ extern int gitfo_move_file(char *from, char *to); extern int gitfo_map_ro( git_map *out, git_file fd, - off_t begin, + git_off_t begin, size_t len); /** diff --git a/src/git2.h b/src/git2.h index 9eb9294df..fbd972b03 100644 --- a/src/git2.h +++ b/src/git2.h @@ -27,6 +27,7 @@ #define INCLUDE_git_git_h__ #include "git2/common.h" +#include "git2/compat.h" #include "git2/errors.h" #include "git2/zlib.h" diff --git a/src/git2/compat.h b/src/git2/compat.h new file mode 100644 index 000000000..76efae0ab --- /dev/null +++ b/src/git2/compat.h @@ -0,0 +1,70 @@ +/* + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, + * as published by the Free Software Foundation. + * + * In addition to the permissions in the GNU General Public License, + * the authors give you unlimited permission to link the compiled + * version of this file into combinations with other programs, + * and to distribute those combinations without any restriction + * coming from the use of this file. (The General Public License + * restrictions do apply in other respects; for example, they cover + * modification of the file, and distribution when not linked into + * a combined executable.) + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDE_git_compat_h__ +#define INCLUDE_git_compat_h__ + +/** + * @file git2/compat.h + * @brief Type compatibility layer necessary for clients of the library. + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +// NOTE: This needs to be in a public header so that both the library +// implementation and client applications both agree on the same types. +// Otherwise we get undefined behavior. +// +// Use the "best" types that each platform provides. Currently we truncate +// these intermediate representations for compatibility with the git ABI, but +// if and when it changes to support 64 bit types, our code will naturally +// adapt. +// +// NOTE: These types should match those that are returned by our internal +// stat() functions, for all platforms. +#if defined(_MSC_VER) + +typedef __int64 git_off_t; +typedef __time64_t git_time_t; + +#elif defined(__MINGW32__) + +typedef off64_t git_off_t; +typedef time_t git_time_t; + +#else // POSIX + +// Note: Can't use off_t since if a client program includes <sys/types.h> +// before us (directly or indirectly), they'll get 32 bit off_t in their client +// app, even though /we/ define _FILE_OFFSET_BITS=64. +typedef long long git_off_t; +typedef time_t git_time_t; + +#endif + +/** @} */ +GIT_END_DECL + +#endif diff --git a/src/git2/index.h b/src/git2/index.h index f0cae09b1..f1716fead 100644 --- a/src/git2/index.h +++ b/src/git2/index.h @@ -45,7 +45,8 @@ GIT_BEGIN_DECL /** Time used in a git index entry */ typedef struct { - unsigned int seconds; + git_time_t seconds; + /* nsec should not be stored as time_t compatible */ unsigned int nanoseconds; } git_index_time; @@ -59,7 +60,7 @@ typedef struct git_index_entry { unsigned int mode; unsigned int uid; unsigned int gid; - unsigned int file_size; + git_off_t file_size; git_oid oid; diff --git a/src/index.c b/src/index.c index e861d7982..6fdb46e18 100644 --- a/src/index.c +++ b/src/index.c @@ -303,12 +303,8 @@ int git_index_add(git_index *index, const char *rel_path, int stage) memset(&entry, 0x0, sizeof(git_index_entry)); - /* Note: this won't wrap around at 2038 because we're not storing signed - * 32-bit integers, but unsigned ones. We're converting from signed 64-bit - * integers (on platforms that use 64bit time_t) to unsigned 32-bit integers, - * which will represent up to 2^32 - 1 seconds after the epoch */ - entry.ctime.seconds = (unsigned int)st.st_ctime; - entry.mtime.seconds = (unsigned int)st.st_mtime; + entry.ctime.seconds = st.st_ctime; + entry.mtime.seconds = st.st_mtime; /* entry.mtime.nanoseconds = st.st_mtimensec; */ /* entry.ctime.nanoseconds = st.st_ctimensec; */ entry.dev= st.st_rdev; @@ -316,8 +312,7 @@ int git_index_add(git_index *index, const char *rel_path, int stage) entry.mode = st.st_mode; entry.uid = st.st_uid; entry.gid = st.st_gid; - /* Note: the following restricts blobs to 4GB in size */ - entry.file_size = (unsigned int)st.st_size; + entry.file_size = st.st_size; /* write the blob to disk and get the oid */ if ((error = git_blob_writefile(&entry.oid, index->repository, full_path)) < GIT_SUCCESS) @@ -25,7 +25,7 @@ typedef struct { /* memory mapped buffer */ #endif } git_map; -extern int git__mmap(git_map *out, size_t len, int prot, int flags, int fd, off_t offset); +extern int git__mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset); extern int git__munmap(git_map *map); #endif /* INCLUDE_map_h__ */ diff --git a/src/mingw-compat.h b/src/mingw-compat.h index e3805dff2..b7919c2e8 100644 --- a/src/mingw-compat.h +++ b/src/mingw-compat.h @@ -4,7 +4,6 @@ #if defined(__MINGW32__) /* use a 64-bit file offset type */ -# define off_t off64_t # define lseek _lseeki64 # define stat _stati64 # define fstat _fstati64 diff --git a/src/msvc-compat.h b/src/msvc-compat.h index 09492ba7a..d4c031d2d 100644 --- a/src/msvc-compat.h +++ b/src/msvc-compat.h @@ -8,9 +8,6 @@ # define W_OK 2 /* write mode check */ # define R_OK 4 /* read mode check */ -/* use a 64-bit file offset type */ -typedef __int64 off64_t; -# define off_t off64_t # define lseek _lseeki64 # define stat _stat64 # define fstat _fstat64 diff --git a/src/odb_pack.c b/src/odb_pack.c index d59c419a5..6141c57ef 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -58,8 +58,8 @@ struct pack_backend; typedef struct { uint32_t n; unsigned char *oid; - off_t offset; - off_t size; + git_off_t offset; + git_off_t size; } index_entry; typedef struct { /* '.pack' file header */ @@ -80,7 +80,7 @@ typedef struct git_pack { int (*idx_search_offset)( uint32_t *, struct git_pack *, - off_t); + git_off_t); int (*idx_get)( index_entry *, struct git_pack *, @@ -107,7 +107,7 @@ typedef struct git_pack { git_map pack_map; /** The size of the .pack file. */ - off_t pack_size; + git_off_t pack_size; /** The mtime of the .pack file. */ time_t pack_mtime; @@ -291,7 +291,7 @@ static int check_pack_hdr(git_pack *p) static int check_pack_sha1(git_pack *p) { unsigned char *data = p->idx_map.data; - off_t pack_sha1_off = p->pack_size - GIT_OID_RAWSZ; + git_off_t pack_sha1_off = p->pack_size - GIT_OID_RAWSZ; size_t idx_pack_sha1_off = p->idx_map.len - 2 * GIT_OID_RAWSZ; git_oid pack_id, idx_pack_id; @@ -550,7 +550,7 @@ static int locate_packfile(pack_location *location, pack_backend *backend, const static int pack_openidx_map(git_pack *p) { char pb[GIT_PATH_MAX]; - off_t len; + git_off_t len; if (git__fmt(pb, sizeof(pb), "%s/pack/%s.idx", p->backend->objects_dir, @@ -571,7 +571,7 @@ static int pack_openidx_map(git_pack *p) } typedef struct { - off_t offset; + git_off_t offset; uint32_t n; } offset_idx_info; @@ -584,7 +584,7 @@ static int cmp_offset_idx_info(const void *lhs, const void *rhs) static int make_offset_index(git_pack *p, offset_idx_info *data) { - off_t min_off = 3 * 4, max_off = p->pack_size - GIT_OID_RAWSZ; + git_off_t min_off = 3 * 4, max_off = p->pack_size - GIT_OID_RAWSZ; uint32_t *idx, *next; uint32_t j; @@ -636,7 +636,7 @@ static int idxv1_search(uint32_t *out, git_pack *p, const git_oid *id) return GIT_ENOTFOUND; } -static int idxv1_search_offset(uint32_t *out, git_pack *p, off_t offset) +static int idxv1_search_offset(uint32_t *out, git_pack *p, git_off_t offset) { if (offset > 0 && offset < (p->pack_size - GIT_OID_RAWSZ)) { uint32_t lo = 0, hi = p->obj_cnt+1; @@ -646,7 +646,7 @@ static int idxv1_search_offset(uint32_t *out, git_pack *p, off_t offset) uint32_t mid = (lo + hi) >> 1; uint32_t n = idx[mid]; uint32_t pos = n * (GIT_OID_RAWSZ + 4); - off_t here = decode32(data + pos); + git_off_t here = decode32(data + pos); if (offset < here) hi = mid; else if (offset == here) { @@ -666,7 +666,7 @@ static int idxv1_get(index_entry *e, git_pack *p, uint32_t n) if (n < p->obj_cnt) { uint32_t pos = n * (GIT_OID_RAWSZ + 4); - off_t next_off = p->pack_size - GIT_OID_RAWSZ; + git_off_t next_off = p->pack_size - GIT_OID_RAWSZ; e->n = n; e->oid = data + pos + 4; e->offset = decode32(data + pos); @@ -758,7 +758,7 @@ static int idxv2_search(uint32_t *out, git_pack *p, const git_oid *id) return GIT_ENOTFOUND; } -static int idxv2_search_offset(uint32_t *out, git_pack *p, off_t offset) +static int idxv2_search_offset(uint32_t *out, git_pack *p, git_off_t offset) { if (offset > 0 && offset < (p->pack_size - GIT_OID_RAWSZ)) { uint32_t lo = 0, hi = p->obj_cnt+1; @@ -767,7 +767,7 @@ static int idxv2_search_offset(uint32_t *out, git_pack *p, off_t offset) uint32_t mid = (lo + hi) >> 1; uint32_t n = idx[mid]; uint32_t o32 = decode32(p->im_offset32 + n); - off_t here = o32; + git_off_t here = o32; if (o32 & 0x80000000) { uint32_t o64_idx = (o32 & ~0x80000000); @@ -793,7 +793,7 @@ static int idxv2_get(index_entry *e, git_pack *p, uint32_t n) if (n < p->obj_cnt) { uint32_t o32 = decode32(p->im_offset32 + n); - off_t next_off = p->pack_size - GIT_OID_RAWSZ; + git_off_t next_off = p->pack_size - GIT_OID_RAWSZ; e->n = n; e->oid = data + n * GIT_OID_RAWSZ; e->offset = o32; @@ -863,7 +863,7 @@ static int pack_openidx_v2(git_pack *p) o64_len = o64_sz / 8; for (j = 0; j < p->obj_cnt; j++) { uint32_t o32 = decode32(p->im_offset32 + j); - off_t offset = o32; + git_off_t offset = o32; if (o32 & 0x80000000) { uint32_t o64_idx = (o32 & ~0x80000000); if (o64_idx >= o64_len) { @@ -992,7 +992,7 @@ static int unpack_object(git_rawobj *out, git_pack *p, index_entry *e) case GIT_OBJ_OFS_DELTA: { - off_t delta_offset; + git_off_t delta_offset; index_entry entry; byte = *buffer++ & 0xFF; diff --git a/src/unix/map.c b/src/unix/map.c index 3008008a6..4780bd23c 100644 --- a/src/unix/map.c +++ b/src/unix/map.c @@ -4,7 +4,7 @@ #include <errno.h> -int git__mmap(git_map *out, size_t len, int prot, int flags, int fd, off_t offset) +int git__mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset) { int mprot = 0; int mflag = 0; diff --git a/src/util.h b/src/util.h index 5e6c7d28b..99c4f5a84 100644 --- a/src/util.h +++ b/src/util.h @@ -27,10 +27,10 @@ extern uint32_t git__hash(const void *key, int len, uint32_t seed); /** @return true if p fits into the range of a size_t */ -GIT_INLINE(int) git__is_sizet(off_t p) +GIT_INLINE(int) git__is_sizet(git_off_t p) { size_t r = (size_t)p; - return p == (off_t)r; + return p == (git_off_t)r; } /* 32-bit cross-platform rotl */ diff --git a/src/win32/map.c b/src/win32/map.c index 388e9c621..e5f8e559a 100644 --- a/src/win32/map.c +++ b/src/win32/map.c @@ -16,7 +16,7 @@ static DWORD get_page_size(void) return page_size; } -int git__mmap(git_map *out, size_t len, int prot, int flags, int fd, off_t offset) +int git__mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset) { HANDLE fh = (HANDLE)_get_osfhandle(fd); DWORD page_size = get_page_size(); @@ -24,8 +24,8 @@ int git__mmap(git_map *out, size_t len, int prot, int flags, int fd, off_t offse DWORD view_prot = 0; DWORD off_low = 0; DWORD off_hi = 0; - off_t page_start; - off_t page_offset; + git_off_t page_start; + git_off_t page_offset; assert((out != NULL) && (len > 0)); @@ -77,7 +77,7 @@ int git__mmap(git_map *out, size_t len, int prot, int flags, int fd, off_t offse return GIT_ERROR; } - assert(sizeof(off_t) == 8); + assert(sizeof(git_off_t) == 8); off_low = (DWORD)(page_start); off_hi = (DWORD)(page_start >> 32); out->data = MapViewOfFile(out->fmh, view_prot, off_hi, off_low, len); |