File sponge.c changed (mode: 100644) (index fc592e6..a88fe0e) |
... |
... |
static void cs_leave (struct cs_status status) { |
74 |
74 |
} |
} |
75 |
75 |
|
|
76 |
76 |
static void cleanup() { |
static void cleanup() { |
77 |
|
if(strcmp(tmpname, DEFAULT_TMP_NAME)) { |
|
78 |
|
unlink(tmpname); |
|
79 |
|
} |
|
|
77 |
|
if (strcmp(tmpname, DEFAULT_TMP_NAME)) { |
|
78 |
|
unlink(tmpname); |
|
79 |
|
} |
80 |
80 |
} |
} |
81 |
81 |
|
|
82 |
82 |
static void onexit_cleanup (void) { |
static void onexit_cleanup (void) { |
|
... |
... |
static size_t default_sponge_size (void) { |
133 |
133 |
/* Use no less than the minimum. */ |
/* Use no less than the minimum. */ |
134 |
134 |
return MAX (size, MIN_SPONGE_SIZE); |
return MAX (size, MIN_SPONGE_SIZE); |
135 |
135 |
} |
} |
136 |
|
|
|
|
136 |
|
|
137 |
137 |
void trapsignals (void) { |
void trapsignals (void) { |
138 |
138 |
ssize_t i = 0; |
ssize_t i = 0; |
139 |
139 |
static int const sig[] = { |
static int const sig[] = { |
|
... |
... |
void trapsignals (void) { |
184 |
184 |
} |
} |
185 |
185 |
|
|
186 |
186 |
static void write_buff_tmp(char* buff, size_t length, FILE *fd) { |
static void write_buff_tmp(char* buff, size_t length, FILE *fd) { |
187 |
|
if (fwrite(buff, length, 1, fd) < 1) { |
|
188 |
|
perror("error writing buffer to temporary file"); |
|
189 |
|
fclose(fd); |
|
190 |
|
exit(1); |
|
191 |
|
} |
|
|
187 |
|
if (fwrite(buff, length, 1, fd) < 1) { |
|
188 |
|
perror("error writing buffer to temporary file"); |
|
189 |
|
fclose(fd); |
|
190 |
|
exit(1); |
|
191 |
|
} |
192 |
192 |
} |
} |
|
193 |
|
|
193 |
194 |
static void write_buff_out(char* buff, size_t length, FILE *fd) { |
static void write_buff_out(char* buff, size_t length, FILE *fd) { |
194 |
|
if (fwrite(buff, length, 1, fd) < 1) { |
|
195 |
|
perror("error writing buffer to output file"); |
|
196 |
|
fclose(fd); |
|
197 |
|
exit(1); |
|
198 |
|
} |
|
|
195 |
|
if (fwrite(buff, length, 1, fd) < 1) { |
|
196 |
|
perror("error writing buffer to output file"); |
|
197 |
|
fclose(fd); |
|
198 |
|
exit(1); |
|
199 |
|
} |
199 |
200 |
} |
} |
|
201 |
|
|
200 |
202 |
static void copy_tmpfile(FILE *tmpfile, FILE *outfd) { |
static void copy_tmpfile(FILE *tmpfile, FILE *outfd) { |
201 |
|
char buf[BUFF_SIZE]; |
|
202 |
|
if (fseek(tmpfile, 0, SEEK_SET)) { |
|
203 |
|
perror("could to seek to start of temporary file"); |
|
204 |
|
fclose(tmpfile); |
|
205 |
|
exit(1); |
|
206 |
|
} |
|
207 |
|
// XXX I'd catch signals or writes errors here, but I |
|
208 |
|
// I don't think it matters as the file is overwritten |
|
209 |
|
while(fread(buf, BUFF_SIZE, 1, tmpfile) == 1) { |
|
210 |
|
write_buff_out(buf, BUFF_SIZE, outfd); |
|
211 |
|
} |
|
212 |
|
fclose(tmpfile); |
|
213 |
|
fclose(outfd); |
|
|
203 |
|
char buf[BUFF_SIZE]; |
|
204 |
|
if (fseek(tmpfile, 0, SEEK_SET)) { |
|
205 |
|
perror("could to seek to start of temporary file"); |
|
206 |
|
fclose(tmpfile); |
|
207 |
|
exit(1); |
|
208 |
|
} |
|
209 |
|
// XXX I'd catch signals or writes errors here, but I |
|
210 |
|
// I don't think it matters as the file is overwritten |
|
211 |
|
while(fread(buf, BUFF_SIZE, 1, tmpfile) == 1) { |
|
212 |
|
write_buff_out(buf, BUFF_SIZE, outfd); |
|
213 |
|
} |
|
214 |
|
fclose(tmpfile); |
|
215 |
|
fclose(outfd); |
214 |
216 |
} |
} |
215 |
217 |
|
|
216 |
218 |
int main (int argc, char **argv) { |
int main (int argc, char **argv) { |
|
... |
... |
int main (int argc, char **argv) { |
234 |
236 |
if (bufused == bufsize) { |
if (bufused == bufsize) { |
235 |
237 |
if ((bufsize*2) >= mem_available) { |
if ((bufsize*2) >= mem_available) { |
236 |
238 |
if (!tmpfile) { |
if (!tmpfile) { |
237 |
|
/* |
|
238 |
|
umask(077); FIXME: Should we be setting umask, or using default? |
|
239 |
|
*/ |
|
|
239 |
|
/* umask(077); FIXME: Should we be setting umask, or using default? */ |
240 |
240 |
struct cs_status cs = cs_enter(); |
struct cs_status cs = cs_enter(); |
241 |
241 |
int tmpfd = mkstemp(tmpname); |
int tmpfd = mkstemp(tmpname); |
242 |
242 |
atexit(onexit_cleanup); // solaris on_exit(onexit_cleanup, 0); |
atexit(onexit_cleanup); // solaris on_exit(onexit_cleanup, 0); |
243 |
|
trapsignals(); |
|
|
243 |
|
trapsignals(); |
244 |
244 |
cs_leave(cs); |
cs_leave(cs); |
245 |
245 |
if (tmpfd < 0) { |
if (tmpfd < 0) { |
246 |
246 |
perror("mkstemp failed"); |
perror("mkstemp failed"); |
|
... |
... |
int main (int argc, char **argv) { |
248 |
248 |
} |
} |
249 |
249 |
tmpfile = fdopen(tmpfd, "w+"); |
tmpfile = fdopen(tmpfd, "w+"); |
250 |
250 |
} |
} |
251 |
|
write_buff_tmp(bufstart, bufused, tmpfile); |
|
|
251 |
|
write_buff_tmp(bufstart, bufused, tmpfile); |
252 |
252 |
bufused = 0; |
bufused = 0; |
253 |
253 |
} |
} |
254 |
254 |
else { |
else { |
|
... |
... |
int main (int argc, char **argv) { |
270 |
270 |
outname = argv[1]; |
outname = argv[1]; |
271 |
271 |
} |
} |
272 |
272 |
if (tmpfile) { |
if (tmpfile) { |
273 |
|
/* write whatever we have in memory to tmpfile */ |
|
274 |
|
write_buff_tmp(bufstart, bufused, tmpfile); |
|
275 |
|
struct stat statbuf; |
|
|
273 |
|
/* write whatever we have in memory to tmpfile */ |
|
274 |
|
write_buff_tmp(bufstart, bufused, tmpfile); |
|
275 |
|
struct stat statbuf; |
276 |
276 |
if (outname && !stat(outname, &statbuf)) { |
if (outname && !stat(outname, &statbuf)) { |
277 |
|
/* regular file */ |
|
278 |
|
if(S_ISREG(statbuf.st_mode) && !fclose(tmpfile)) { |
|
279 |
|
if(rename(tmpname, outname)) { |
|
280 |
|
perror("error renaming temporary file to output file"); |
|
281 |
|
exit(1); |
|
282 |
|
} |
|
283 |
|
} |
|
284 |
|
else { |
|
285 |
|
FILE *outfd = fopen(outname, "w"); |
|
286 |
|
if (outfd < 0) { |
|
287 |
|
perror("error opening output file"); |
|
288 |
|
exit(1); |
|
289 |
|
} |
|
290 |
|
copy_tmpfile(tmpfile, outfd); |
|
291 |
|
} |
|
|
277 |
|
/* regular file */ |
|
278 |
|
if (S_ISREG(statbuf.st_mode) && !fclose(tmpfile)) { |
|
279 |
|
if (rename(tmpname, outname)) { |
|
280 |
|
perror("error renaming temporary file to output file"); |
|
281 |
|
exit(1); |
|
282 |
|
} |
|
283 |
|
} |
|
284 |
|
else { |
|
285 |
|
FILE *outfd = fopen(outname, "w"); |
|
286 |
|
if (outfd < 0) { |
|
287 |
|
perror("error opening output file"); |
|
288 |
|
exit(1); |
|
289 |
|
} |
|
290 |
|
copy_tmpfile(tmpfile, outfd); |
|
291 |
|
} |
292 |
292 |
} |
} |
293 |
293 |
else { |
else { |
294 |
|
copy_tmpfile(tmpfile, stdout); |
|
|
294 |
|
copy_tmpfile(tmpfile, stdout); |
295 |
295 |
} |
} |
296 |
296 |
} |
} |
297 |
297 |
else { |
else { |
298 |
|
FILE *outfd = stdout; |
|
|
298 |
|
FILE *outfd = stdout; |
299 |
299 |
if (outname) { |
if (outname) { |
300 |
300 |
outfd = fopen(outname, "w"); |
outfd = fopen(outname, "w"); |
301 |
301 |
if (outfd < 0) { |
if (outfd < 0) { |
|
... |
... |
int main (int argc, char **argv) { |
303 |
303 |
exit(1); |
exit(1); |
304 |
304 |
} |
} |
305 |
305 |
} |
} |
306 |
|
write_buff_out(bufstart, bufused, outfd); |
|
307 |
|
fclose(outfd); |
|
|
306 |
|
write_buff_out(bufstart, bufused, outfd); |
|
307 |
|
fclose(outfd); |
308 |
308 |
} |
} |
|
309 |
|
|
309 |
310 |
return 0; |
return 0; |
310 |
311 |
} |
} |