author | Lars Hjemli <hjemli@gmail.com> | 2008-05-18 21:16:50 (UTC) |
---|---|---|
committer | Lars Hjemli <hjemli@gmail.com> | 2008-05-18 21:16:50 (UTC) |
commit | d402811bd2db21c7868411a279fd2d220f54c294 (patch) (unidiff) | |
tree | 1d4c4ac9bec7673652c8771f1ae55f4806cbaf8b /cache.c | |
parent | 6102bcfce46fd357566941d565b95f78510af79b (diff) | |
download | cgit-d402811bd2db21c7868411a279fd2d220f54c294.zip cgit-d402811bd2db21c7868411a279fd2d220f54c294.tar.gz cgit-d402811bd2db21c7868411a279fd2d220f54c294.tar.bz2 |
cache.c: make all io-related functions return errno on error
We'll need proper return-values from these functions to make the cache
behave correctly (which includes giving proper error messages).
Noticed-by: Jim Meyering <jim@meyering.net>
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
-rw-r--r-- | cache.c | 33 |
1 files changed, 24 insertions, 9 deletions
@@ -53,38 +53,42 @@ static int open_slot(struct cache_slot *slot) | |||
53 | 53 | ||
54 | slot->bufsize = read(slot->cache_fd, slot->buf, sizeof(slot->buf)); | 54 | slot->bufsize = read(slot->cache_fd, slot->buf, sizeof(slot->buf)); |
55 | if (slot->bufsize < 0) | 55 | if (slot->bufsize < 0) |
56 | return errno; | 56 | return errno; |
57 | 57 | ||
58 | bufz = memchr(slot->buf, 0, slot->bufsize); | 58 | bufz = memchr(slot->buf, 0, slot->bufsize); |
59 | if (bufz) | 59 | if (bufz) |
60 | bufkeylen = bufz - slot->buf; | 60 | bufkeylen = bufz - slot->buf; |
61 | 61 | ||
62 | slot->match = bufkeylen == slot->keylen && | 62 | slot->match = bufkeylen == slot->keylen && |
63 | !memcmp(slot->key, slot->buf, bufkeylen + 1); | 63 | !memcmp(slot->key, slot->buf, bufkeylen + 1); |
64 | 64 | ||
65 | return 0; | 65 | return 0; |
66 | } | 66 | } |
67 | 67 | ||
68 | /* Close the active cache slot */ | 68 | /* Close the active cache slot */ |
69 | static void close_slot(struct cache_slot *slot) | 69 | static int close_slot(struct cache_slot *slot) |
70 | { | 70 | { |
71 | int err = 0; | ||
71 | if (slot->cache_fd > 0) { | 72 | if (slot->cache_fd > 0) { |
72 | close(slot->cache_fd); | 73 | if (close(slot->cache_fd)) |
73 | slot->cache_fd = -1; | 74 | err = errno; |
75 | else | ||
76 | slot->cache_fd = -1; | ||
74 | } | 77 | } |
78 | return err; | ||
75 | } | 79 | } |
76 | 80 | ||
77 | /* Print the content of the active cache slot (but skip the key). */ | 81 | /* Print the content of the active cache slot (but skip the key). */ |
78 | static int print_slot(struct cache_slot *slot) | 82 | static int print_slot(struct cache_slot *slot) |
79 | { | 83 | { |
80 | ssize_t i, j = 0; | 84 | ssize_t i, j = 0; |
81 | 85 | ||
82 | i = lseek(slot->cache_fd, slot->keylen + 1, SEEK_SET); | 86 | i = lseek(slot->cache_fd, slot->keylen + 1, SEEK_SET); |
83 | if (i != slot->keylen + 1) | 87 | if (i != slot->keylen + 1) |
84 | return errno; | 88 | return errno; |
85 | 89 | ||
86 | while((i=read(slot->cache_fd, slot->buf, sizeof(slot->buf))) > 0) | 90 | while((i=read(slot->cache_fd, slot->buf, sizeof(slot->buf))) > 0) |
87 | j = write(STDOUT_FILENO, slot->buf, i); | 91 | j = write(STDOUT_FILENO, slot->buf, i); |
88 | 92 | ||
89 | if (j < 0) | 93 | if (j < 0) |
90 | return errno; | 94 | return errno; |
@@ -103,94 +107,105 @@ static int is_expired(struct cache_slot *slot) | |||
103 | 107 | ||
104 | /* Check if the slot has been modified since we opened it. | 108 | /* Check if the slot has been modified since we opened it. |
105 | * NB: If stat() fails, we pretend the file is modified. | 109 | * NB: If stat() fails, we pretend the file is modified. |
106 | */ | 110 | */ |
107 | static int is_modified(struct cache_slot *slot) | 111 | static int is_modified(struct cache_slot *slot) |
108 | { | 112 | { |
109 | struct stat st; | 113 | struct stat st; |
110 | 114 | ||
111 | if (stat(slot->cache_name, &st)) | 115 | if (stat(slot->cache_name, &st)) |
112 | return 1; | 116 | return 1; |
113 | return (st.st_ino != slot->cache_st.st_ino || | 117 | return (st.st_ino != slot->cache_st.st_ino || |
114 | st.st_mtime != slot->cache_st.st_mtime || | 118 | st.st_mtime != slot->cache_st.st_mtime || |
115 | st.st_size != slot->cache_st.st_size); | 119 | st.st_size != slot->cache_st.st_size); |
116 | } | 120 | } |
117 | 121 | ||
118 | /* Close an open lockfile */ | 122 | /* Close an open lockfile */ |
119 | static void close_lock(struct cache_slot *slot) | 123 | static int close_lock(struct cache_slot *slot) |
120 | { | 124 | { |
125 | int err = 0; | ||
121 | if (slot->lock_fd > 0) { | 126 | if (slot->lock_fd > 0) { |
122 | close(slot->lock_fd); | 127 | if (close(slot->lock_fd)) |
123 | slot->lock_fd = -1; | 128 | err = errno; |
129 | else | ||
130 | slot->lock_fd = -1; | ||
124 | } | 131 | } |
132 | return err; | ||
125 | } | 133 | } |
126 | 134 | ||
127 | /* Create a lockfile used to store the generated content for a cache | 135 | /* Create a lockfile used to store the generated content for a cache |
128 | * slot, and write the slot key + \0 into it. | 136 | * slot, and write the slot key + \0 into it. |
129 | * Returns 0 on success and errno otherwise. | 137 | * Returns 0 on success and errno otherwise. |
130 | */ | 138 | */ |
131 | static int lock_slot(struct cache_slot *slot) | 139 | static int lock_slot(struct cache_slot *slot) |
132 | { | 140 | { |
133 | slot->lock_fd = open(slot->lock_name, O_RDWR|O_CREAT|O_EXCL, | 141 | slot->lock_fd = open(slot->lock_name, O_RDWR|O_CREAT|O_EXCL, |
134 | S_IRUSR|S_IWUSR); | 142 | S_IRUSR|S_IWUSR); |
135 | if (slot->lock_fd == -1) | 143 | if (slot->lock_fd == -1) |
136 | return errno; | 144 | return errno; |
137 | write(slot->lock_fd, slot->key, slot->keylen + 1); | 145 | if (write(slot->lock_fd, slot->key, slot->keylen + 1) < 0) |
146 | return errno; | ||
138 | return 0; | 147 | return 0; |
139 | } | 148 | } |
140 | 149 | ||
141 | /* Release the current lockfile. If `replace_old_slot` is set the | 150 | /* Release the current lockfile. If `replace_old_slot` is set the |
142 | * lockfile replaces the old cache slot, otherwise the lockfile is | 151 | * lockfile replaces the old cache slot, otherwise the lockfile is |
143 | * just deleted. | 152 | * just deleted. |
144 | */ | 153 | */ |
145 | static int unlock_slot(struct cache_slot *slot, int replace_old_slot) | 154 | static int unlock_slot(struct cache_slot *slot, int replace_old_slot) |
146 | { | 155 | { |
147 | int err; | 156 | int err; |
148 | 157 | ||
149 | if (replace_old_slot) | 158 | if (replace_old_slot) |
150 | err = rename(slot->lock_name, slot->cache_name); | 159 | err = rename(slot->lock_name, slot->cache_name); |
151 | else | 160 | else |
152 | err = unlink(slot->lock_name); | 161 | err = unlink(slot->lock_name); |
153 | return err; | 162 | |
163 | if (err) | ||
164 | return errno; | ||
165 | |||
166 | return 0; | ||
154 | } | 167 | } |
155 | 168 | ||
156 | /* Generate the content for the current cache slot by redirecting | 169 | /* Generate the content for the current cache slot by redirecting |
157 | * stdout to the lock-fd and invoking the callback function | 170 | * stdout to the lock-fd and invoking the callback function |
158 | */ | 171 | */ |
159 | static int fill_slot(struct cache_slot *slot) | 172 | static int fill_slot(struct cache_slot *slot) |
160 | { | 173 | { |
161 | int tmp; | 174 | int tmp; |
162 | 175 | ||
163 | /* Preserve stdout */ | 176 | /* Preserve stdout */ |
164 | tmp = dup(STDOUT_FILENO); | 177 | tmp = dup(STDOUT_FILENO); |
165 | if (tmp == -1) | 178 | if (tmp == -1) |
166 | return errno; | 179 | return errno; |
167 | 180 | ||
168 | /* Redirect stdout to lockfile */ | 181 | /* Redirect stdout to lockfile */ |
169 | if (dup2(slot->lock_fd, STDOUT_FILENO) == -1) | 182 | if (dup2(slot->lock_fd, STDOUT_FILENO) == -1) |
170 | return errno; | 183 | return errno; |
171 | 184 | ||
172 | /* Generate cache content */ | 185 | /* Generate cache content */ |
173 | slot->fn(slot->cbdata); | 186 | slot->fn(slot->cbdata); |
174 | 187 | ||
175 | /* Restore stdout */ | 188 | /* Restore stdout */ |
176 | if (dup2(tmp, STDOUT_FILENO) == -1) | 189 | if (dup2(tmp, STDOUT_FILENO) == -1) |
177 | return errno; | 190 | return errno; |
178 | 191 | ||
179 | /* Close the temporary filedescriptor */ | 192 | /* Close the temporary filedescriptor */ |
180 | close(tmp); | 193 | if (close(tmp)) |
194 | return errno; | ||
195 | |||
181 | return 0; | 196 | return 0; |
182 | } | 197 | } |
183 | 198 | ||
184 | /* Crude implementation of 32-bit FNV-1 hash algorithm, | 199 | /* Crude implementation of 32-bit FNV-1 hash algorithm, |
185 | * see http://www.isthe.com/chongo/tech/comp/fnv/ for details | 200 | * see http://www.isthe.com/chongo/tech/comp/fnv/ for details |
186 | * about the magic numbers. | 201 | * about the magic numbers. |
187 | */ | 202 | */ |
188 | #define FNV_OFFSET 0x811c9dc5 | 203 | #define FNV_OFFSET 0x811c9dc5 |
189 | #define FNV_PRIME 0x01000193 | 204 | #define FNV_PRIME 0x01000193 |
190 | 205 | ||
191 | unsigned long hash_str(const char *str) | 206 | unsigned long hash_str(const char *str) |
192 | { | 207 | { |
193 | unsigned long h = FNV_OFFSET; | 208 | unsigned long h = FNV_OFFSET; |
194 | unsigned char *s = (unsigned char *)str; | 209 | unsigned char *s = (unsigned char *)str; |
195 | 210 | ||
196 | if (!s) | 211 | if (!s) |