| 61 | } |
| 62 | |
| 63 | static int read_object_info_from_path(struct odb_source_loose *loose, |
| 64 | const char *path, |
| 65 | const struct object_id *oid, |
| 66 | struct object_info *oi, |
| 67 | enum object_info_flags flags) |
| 68 | { |
| 69 | int ret; |
| 70 | int fd; |
| 71 | unsigned long mapsize; |
| 72 | void *map = NULL; |
| 73 | git_zstream stream, *stream_to_end = NULL; |
| 74 | char hdr[MAX_HEADER_LEN]; |
| 75 | size_t size_scratch; |
| 76 | enum object_type type_scratch; |
| 77 | struct stat st; |
| 78 | |
| 79 | /* |
| 80 | * If we don't care about type or size, then we don't |
| 81 | * need to look inside the object at all. Note that we |
| 82 | * do not optimize out the stat call, even if the |
| 83 | * caller doesn't care about the disk-size, since our |
| 84 | * return value implicitly indicates whether the |
| 85 | * object even exists. |
| 86 | */ |
| 87 | if (!oi || (!oi->typep && !oi->sizep && !oi->contentp)) { |
| 88 | struct stat st; |
| 89 | |
| 90 | if ((!oi || (!oi->disk_sizep && !oi->mtimep)) && (flags & OBJECT_INFO_QUICK)) { |
| 91 | ret = quick_has_loose(loose, oid) ? 0 : -1; |
| 92 | goto out; |
| 93 | } |
| 94 | |
| 95 | if (lstat(path, &st) < 0) { |
| 96 | ret = -1; |
| 97 | goto out; |
| 98 | } |
| 99 | |
| 100 | if (oi) { |
| 101 | if (oi->disk_sizep) |
| 102 | *oi->disk_sizep = st.st_size; |
| 103 | if (oi->mtimep) |
| 104 | *oi->mtimep = st.st_mtime; |
| 105 | } |
| 106 | |
| 107 | ret = 0; |
| 108 | goto out; |
| 109 | } |
| 110 | |
| 111 | fd = git_open(path); |
| 112 | if (fd < 0) { |
| 113 | if (errno != ENOENT) |
| 114 | error_errno(_("unable to open loose object %s"), oid_to_hex(oid)); |
| 115 | ret = -1; |
| 116 | goto out; |
| 117 | } |
| 118 | |
| 119 | if (fstat(fd, &st)) { |
| 120 | close(fd); |
no test coverage detected