| 130 | }; |
| 131 | |
| 132 | int reftable_block_source_from_file(struct reftable_block_source *bs, |
| 133 | const char *name) |
| 134 | { |
| 135 | struct file_block_source *p = NULL; |
| 136 | struct stat st; |
| 137 | int fd, err; |
| 138 | |
| 139 | fd = open(name, O_RDONLY); |
| 140 | if (fd < 0) { |
| 141 | if (errno == ENOENT) |
| 142 | return REFTABLE_NOT_EXIST_ERROR; |
| 143 | err = -1; |
| 144 | goto out; |
| 145 | } |
| 146 | |
| 147 | if (fstat(fd, &st) < 0) { |
| 148 | err = REFTABLE_IO_ERROR; |
| 149 | goto out; |
| 150 | } |
| 151 | |
| 152 | REFTABLE_CALLOC_ARRAY(p, 1); |
| 153 | if (!p) { |
| 154 | err = REFTABLE_OUT_OF_MEMORY_ERROR; |
| 155 | goto out; |
| 156 | } |
| 157 | |
| 158 | err = reftable_mmap(&p->mmap, fd, st.st_size); |
| 159 | if (err < 0) |
| 160 | goto out; |
| 161 | |
| 162 | assert(!bs->ops); |
| 163 | bs->ops = &file_vtable; |
| 164 | bs->arg = p; |
| 165 | |
| 166 | err = 0; |
| 167 | |
| 168 | out: |
| 169 | if (fd >= 0) |
| 170 | close(fd); |
| 171 | if (err < 0) |
| 172 | reftable_free(p); |
| 173 | return err; |
| 174 | } |