summaryrefslogtreecommitdiffabout
path: root/shared.c
authorLars Hjemli <hjemli@gmail.com>2009-08-18 15:17:41 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2009-08-18 15:22:14 (UTC)
commite16f1783346a090e4ea1194dcaae7f03e813f6a2 (patch) (unidiff)
tree268f5ba231895ba3a63071497764c64d44733da5 /shared.c
parent523c133e2e5f7089a3d18ac23f2074b60991a7f0 (diff)
downloadcgit-e16f1783346a090e4ea1194dcaae7f03e813f6a2.zip
cgit-e16f1783346a090e4ea1194dcaae7f03e813f6a2.tar.gz
cgit-e16f1783346a090e4ea1194dcaae7f03e813f6a2.tar.bz2
Add and use a common readfile() function
This function is used to read the full content of a textfile into a newly allocated buffer (with zerotermination). It replaces the earlier readfile() in scan-tree.c (which was rather error-prone[1]), and is reused by read_agefile() in ui-repolist.c. 1: No checks for EINTR and EAGAIN, fixed-size buffer Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (limited to 'shared.c') (more/less context) (ignore whitespace changes)
-rw-r--r--shared.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/shared.c b/shared.c
index 911a55a..4cb9573 100644
--- a/shared.c
+++ b/shared.c
@@ -348,48 +348,69 @@ int cgit_parse_snapshots_mask(const char *str)
348 break; 348 break;
349 for (f = cgit_snapshot_formats; f->suffix; f++) { 349 for (f = cgit_snapshot_formats; f->suffix; f++) {
350 sl = strlen(f->suffix); 350 sl = strlen(f->suffix);
351 if((tl == sl && !strncmp(f->suffix, str, tl)) || 351 if((tl == sl && !strncmp(f->suffix, str, tl)) ||
352 (tl == sl-1 && !strncmp(f->suffix+1, str, tl-1))) { 352 (tl == sl-1 && !strncmp(f->suffix+1, str, tl-1))) {
353 rv |= f->bit; 353 rv |= f->bit;
354 break; 354 break;
355 } 355 }
356 } 356 }
357 str += tl; 357 str += tl;
358 } 358 }
359 return rv; 359 return rv;
360} 360}
361 361
362int cgit_open_filter(struct cgit_filter *filter) 362int cgit_open_filter(struct cgit_filter *filter)
363{ 363{
364 364
365 filter->old_stdout = chk_positive(dup(STDOUT_FILENO), 365 filter->old_stdout = chk_positive(dup(STDOUT_FILENO),
366 "Unable to duplicate STDOUT"); 366 "Unable to duplicate STDOUT");
367 chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess"); 367 chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess");
368 filter->pid = chk_non_negative(fork(), "Unable to create subprocess"); 368 filter->pid = chk_non_negative(fork(), "Unable to create subprocess");
369 if (filter->pid == 0) { 369 if (filter->pid == 0) {
370 close(filter->pipe_fh[1]); 370 close(filter->pipe_fh[1]);
371 chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO), 371 chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO),
372 "Unable to use pipe as STDIN"); 372 "Unable to use pipe as STDIN");
373 execvp(filter->cmd, filter->argv); 373 execvp(filter->cmd, filter->argv);
374 die("Unable to exec subprocess %s: %s (%d)", filter->cmd, 374 die("Unable to exec subprocess %s: %s (%d)", filter->cmd,
375 strerror(errno), errno); 375 strerror(errno), errno);
376 } 376 }
377 close(filter->pipe_fh[0]); 377 close(filter->pipe_fh[0]);
378 chk_non_negative(dup2(filter->pipe_fh[1], STDOUT_FILENO), 378 chk_non_negative(dup2(filter->pipe_fh[1], STDOUT_FILENO),
379 "Unable to use pipe as STDOUT"); 379 "Unable to use pipe as STDOUT");
380 close(filter->pipe_fh[1]); 380 close(filter->pipe_fh[1]);
381 return 0; 381 return 0;
382} 382}
383 383
384int cgit_close_filter(struct cgit_filter *filter) 384int cgit_close_filter(struct cgit_filter *filter)
385{ 385{
386 chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO), 386 chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO),
387 "Unable to restore STDOUT"); 387 "Unable to restore STDOUT");
388 close(filter->old_stdout); 388 close(filter->old_stdout);
389 if (filter->pid < 0) 389 if (filter->pid < 0)
390 return 0; 390 return 0;
391 waitpid(filter->pid, &filter->exitstatus, 0); 391 waitpid(filter->pid, &filter->exitstatus, 0);
392 if (WIFEXITED(filter->exitstatus) && !WEXITSTATUS(filter->exitstatus)) 392 if (WIFEXITED(filter->exitstatus) && !WEXITSTATUS(filter->exitstatus))
393 return 0; 393 return 0;
394 die("Subprocess %s exited abnormally", filter->cmd); 394 die("Subprocess %s exited abnormally", filter->cmd);
395} 395}
396
397/* Read the content of the specified file into a newly allocated buffer,
398 * zeroterminate the buffer and return 0 on success, errno otherwise.
399 */
400int readfile(const char *path, char **buf, size_t *size)
401{
402 int fd;
403 struct stat st;
404
405 fd = open(path, O_RDONLY);
406 if (fd == -1)
407 return errno;
408 if (fstat(fd, &st))
409 return errno;
410 if (!S_ISREG(st.st_mode))
411 return EISDIR;
412 *buf = xmalloc(st.st_size + 1);
413 *size = read_in_full(fd, *buf, st.st_size);
414 (*buf)[*size] = '\0';
415 return (*size == st.st_size ? 0 : errno);
416}