Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 192 lines (171 sloc) 4.143 kB
c38138c git-pack-objects: write the pack files with a SHA1 csum
Linus Torvalds authored
1 /*
2 * csum-file.c
3 *
4 * Copyright (C) 2005 Linus Torvalds
5 *
6 * Simple file write infrastructure for writing SHA1-summed
7 * files. Useful when you write a file that you want to be
8 * able to verify hasn't been messed with afterwards.
9 */
10 #include "cache.h"
2a128d6 add throughput display to git-push
Nicolas Pitre authored
11 #include "progress.h"
c38138c git-pack-objects: write the pack files with a SHA1 csum
Linus Torvalds authored
12 #include "csum-file.h"
13
e337a04 @gitster index-pack: --verify
authored
14 static void flush(struct sha1file *f, void *buf, unsigned int count)
c38138c git-pack-objects: write the pack files with a SHA1 csum
Linus Torvalds authored
15 {
e337a04 @gitster index-pack: --verify
authored
16 if (0 <= f->check_fd && count) {
17 unsigned char check_buffer[8192];
18 ssize_t ret = read_in_full(f->check_fd, check_buffer, count);
19
20 if (ret < 0)
21 die_errno("%s: sha1 file read error", f->name);
22 if (ret < count)
23 die("%s: sha1 file truncated", f->name);
24 if (memcmp(buf, check_buffer, count))
25 die("sha1 file '%s' validation error", f->name);
26 }
27
c38138c git-pack-objects: write the pack files with a SHA1 csum
Linus Torvalds authored
28 for (;;) {
1c15afb xread/xwrite: do not worry about EINTR at calling sites.
Junio C Hamano authored
29 int ret = xwrite(f->fd, buf, count);
c38138c git-pack-objects: write the pack files with a SHA1 csum
Linus Torvalds authored
30 if (ret > 0) {
218558a make display of total transferred more accurate
Nicolas Pitre authored
31 f->total += ret;
32 display_throughput(f->tp, f->total);
1d7f171 Remove all void-pointer arithmetic.
Florian Forster authored
33 buf = (char *) buf + ret;
c38138c git-pack-objects: write the pack files with a SHA1 csum
Linus Torvalds authored
34 count -= ret;
35 if (count)
36 continue;
78b713a Make sha1flush void and remove conditional return.
David Rientjes authored
37 return;
c38138c git-pack-objects: write the pack files with a SHA1 csum
Linus Torvalds authored
38 }
39 if (!ret)
e180884 csum-file interface updates: return resulting SHA1
Linus Torvalds authored
40 die("sha1 file '%s' write error. Out of diskspace", f->name);
d824cbb @trast Convert existing die(..., strerror(errno)) to die_errno()
trast authored
41 die_errno("sha1 file '%s' write error", f->name);
c38138c git-pack-objects: write the pack files with a SHA1 csum
Linus Torvalds authored
42 }
43 }
44
838cd34 fix pread()'s short read in index-pack
Nicolas Pitre authored
45 void sha1flush(struct sha1file *f)
c38138c git-pack-objects: write the pack files with a SHA1 csum
Linus Torvalds authored
46 {
47 unsigned offset = f->offset;
4c81b03 @torvalds Make pack creation always fsync() the result
torvalds authored
48
c38138c git-pack-objects: write the pack files with a SHA1 csum
Linus Torvalds authored
49 if (offset) {
9126f00 fix openssl headers conflicting with custom SHA1 implementations
Nicolas Pitre authored
50 git_SHA1_Update(&f->ctx, f->buffer, offset);
e782e12 @spearce Merge branch 'maint'
spearce authored
51 flush(f, f->buffer, offset);
f021536 Alter sha1close() 3rd argument to request flush only
Dana L. How authored
52 f->offset = 0;
c38138c git-pack-objects: write the pack files with a SHA1 csum
Linus Torvalds authored
53 }
838cd34 fix pread()'s short read in index-pack
Nicolas Pitre authored
54 }
55
56 int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
57 {
58 int fd;
59
60 sha1flush(f);
9126f00 fix openssl headers conflicting with custom SHA1 implementations
Nicolas Pitre authored
61 git_SHA1_Final(f->buffer, &f->ctx);
ac0463e pack-objects: use fixup_pack_header_footer()'s validation mode
Nicolas Pitre authored
62 if (result)
63 hashcpy(result, f->buffer);
4c81b03 @torvalds Make pack creation always fsync() the result
torvalds authored
64 if (flags & (CSUM_CLOSE | CSUM_FSYNC)) {
7ba502c pack-objects.c: fix some global variable abuse and memory leaks
Nicolas Pitre authored
65 /* write checksum and close fd */
e782e12 @spearce Merge branch 'maint'
spearce authored
66 flush(f, f->buffer, 20);
4c81b03 @torvalds Make pack creation always fsync() the result
torvalds authored
67 if (flags & CSUM_FSYNC)
68 fsync_or_die(f->fd, f->name);
7ba502c pack-objects.c: fix some global variable abuse and memory leaks
Nicolas Pitre authored
69 if (close(f->fd))
d824cbb @trast Convert existing die(..., strerror(errno)) to die_errno()
trast authored
70 die_errno("%s: sha1 file error on close", f->name);
7ba502c pack-objects.c: fix some global variable abuse and memory leaks
Nicolas Pitre authored
71 fd = 0;
72 } else
73 fd = f->fd;
e337a04 @gitster index-pack: --verify
authored
74 if (0 <= f->check_fd) {
75 char discard;
76 int cnt = read_in_full(f->check_fd, &discard, 1);
77 if (cnt < 0)
78 die_errno("%s: error when reading the tail of sha1 file",
79 f->name);
80 if (cnt)
81 die("%s: sha1 file has trailing garbage", f->name);
82 if (close(f->check_fd))
83 die_errno("%s: sha1 file error on close", f->name);
84 }
7bf058f @sigprof [PATCH] Plug memory leak in sha1close()
sigprof authored
85 free(f);
7ba502c pack-objects.c: fix some global variable abuse and memory leaks
Nicolas Pitre authored
86 return fd;
c38138c git-pack-objects: write the pack files with a SHA1 csum
Linus Torvalds authored
87 }
88
89 int sha1write(struct sha1file *f, void *buf, unsigned int count)
90 {
91 while (count) {
92 unsigned offset = f->offset;
93 unsigned left = sizeof(f->buffer) - offset;
94 unsigned nr = count > left ? left : count;
a8032d1 sha1write: don't copy full sized buffers
Nicolas Pitre authored
95 void *data;
96
97 if (f->do_crc)
98 f->crc32 = crc32(f->crc32, buf, nr);
99
100 if (nr == sizeof(f->buffer)) {
101 /* process full buffer directly without copy */
102 data = buf;
103 } else {
104 memcpy(f->buffer + offset, buf, nr);
105 data = f->buffer;
106 }
c38138c git-pack-objects: write the pack files with a SHA1 csum
Linus Torvalds authored
107
108 count -= nr;
109 offset += nr;
1d7f171 Remove all void-pointer arithmetic.
Florian Forster authored
110 buf = (char *) buf + nr;
c38138c git-pack-objects: write the pack files with a SHA1 csum
Linus Torvalds authored
111 left -= nr;
112 if (!left) {
9126f00 fix openssl headers conflicting with custom SHA1 implementations
Nicolas Pitre authored
113 git_SHA1_Update(&f->ctx, data, offset);
e782e12 @spearce Merge branch 'maint'
spearce authored
114 flush(f, data, offset);
c38138c git-pack-objects: write the pack files with a SHA1 csum
Linus Torvalds authored
115 offset = 0;
116 }
117 f->offset = offset;
118 }
119 return 0;
120 }
121
4397f01 csum-file: add "sha1fd()" to create a SHA1 csum file from an existing…
Linus Torvalds authored
122 struct sha1file *sha1fd(int fd, const char *name)
123 {
2a128d6 add throughput display to git-push
Nicolas Pitre authored
124 return sha1fd_throughput(fd, name, NULL);
125 }
126
e337a04 @gitster index-pack: --verify
authored
127 struct sha1file *sha1fd_check(const char *name)
128 {
129 int sink, check;
130 struct sha1file *f;
131
132 sink = open("/dev/null", O_WRONLY);
133 if (sink < 0)
134 return NULL;
135 check = open(name, O_RDONLY);
136 if (check < 0) {
137 int saved_errno = errno;
138 close(sink);
139 errno = saved_errno;
140 return NULL;
141 }
142 f = sha1fd(sink, name);
143 f->check_fd = check;
144 return f;
145 }
146
2a128d6 add throughput display to git-push
Nicolas Pitre authored
147 struct sha1file *sha1fd_throughput(int fd, const char *name, struct progress *tp)
148 {
ec640ed remove dead code from the csum-file interface
Nicolas Pitre authored
149 struct sha1file *f = xmalloc(sizeof(*f));
4397f01 csum-file: add "sha1fd()" to create a SHA1 csum file from an existing…
Linus Torvalds authored
150 f->fd = fd;
e337a04 @gitster index-pack: --verify
authored
151 f->check_fd = -1;
4397f01 csum-file: add "sha1fd()" to create a SHA1 csum file from an existing…
Linus Torvalds authored
152 f->offset = 0;
218558a make display of total transferred more accurate
Nicolas Pitre authored
153 f->total = 0;
2a128d6 add throughput display to git-push
Nicolas Pitre authored
154 f->tp = tp;
ec640ed remove dead code from the csum-file interface
Nicolas Pitre authored
155 f->name = name;
78d1e84 compute a CRC32 for each object as stored in a pack
Nicolas Pitre authored
156 f->do_crc = 0;
9126f00 fix openssl headers conflicting with custom SHA1 implementations
Nicolas Pitre authored
157 git_SHA1_Init(&f->ctx);
4397f01 csum-file: add "sha1fd()" to create a SHA1 csum file from an existing…
Linus Torvalds authored
158 return f;
159 }
160
6c52614 @gitster csum-file: introduce sha1file_checkpoint
authored
161 void sha1file_checkpoint(struct sha1file *f, struct sha1file_checkpoint *checkpoint)
162 {
163 sha1flush(f);
164 checkpoint->offset = f->total;
165 checkpoint->ctx = f->ctx;
166 }
167
168 int sha1file_truncate(struct sha1file *f, struct sha1file_checkpoint *checkpoint)
169 {
170 off_t offset = checkpoint->offset;
171
172 if (ftruncate(f->fd, offset) ||
173 lseek(f->fd, offset, SEEK_SET) != offset)
174 return -1;
175 f->total = offset;
176 f->ctx = checkpoint->ctx;
177 f->offset = 0; /* sha1flush() was called in checkpoint */
178 return 0;
179 }
180
78d1e84 compute a CRC32 for each object as stored in a pack
Nicolas Pitre authored
181 void crc32_begin(struct sha1file *f)
182 {
1e4cd68 @bebarino sparse: Fix errors and silence warnings
bebarino authored
183 f->crc32 = crc32(0, NULL, 0);
78d1e84 compute a CRC32 for each object as stored in a pack
Nicolas Pitre authored
184 f->do_crc = 1;
185 }
c38138c git-pack-objects: write the pack files with a SHA1 csum
Linus Torvalds authored
186
78d1e84 compute a CRC32 for each object as stored in a pack
Nicolas Pitre authored
187 uint32_t crc32_end(struct sha1file *f)
188 {
189 f->do_crc = 0;
190 return f->crc32;
191 }
Something went wrong with that request. Please try again.