author | Olivier Brunel
<jjk@jjacky.com> 2022-12-26 15:26:25 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2022-12-26 15:26:25 UTC |
parent | a137a251ce0d53ad92a9a967ea12436d781402fe |
Makefile | +4 | -0 |
djbunix2.h | +15 | -0 |
main.c | +27 | -75 |
openat3.c | +11 | -0 |
openat4.c | +11 | -0 |
openat_append.c | +8 | -0 |
openat_create.c | +8 | -0 |
openat_excl.c | +8 | -0 |
openat_read.c | +8 | -0 |
openat_readb.c | +15 | -0 |
openat_trunc.c | +8 | -0 |
openat_write.c | +8 | -0 |
openatb_read.c | +8 | -0 |
diff --git a/Makefile b/Makefile index c83bc74..d970d9e 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,8 @@ SRCS = main.c output.c md4c.c + +SRCS += openat3.c openat4.c openat_append.c openatb_read.c openat_create.c \ + openat_excl.c openat_readb.c openat_read.c openat_trunc.c openat_write.c + OBJS = $(SRCS:.c=.o) DEPS = $(SRCS:.c=.d) diff --git a/djbunix2.h b/djbunix2.h new file mode 100644 index 0000000..9c38ab3 --- /dev/null +++ b/djbunix2.h @@ -0,0 +1,15 @@ +#ifndef DJBUNIX2_H +#define DJBUNIX2_H + +int openat3(int fd, const char *file, unsigned int flags); +int openat4(int fd, const char *file, unsigned int flags, unsigned int mode); +int openat_read(int fd, const char *file); +int openatb_read(int fd, const char *file); +int openat_readb(int fd, const char *file); +int openat_excl(int fd, const char *file); +int openat_append(int fd, const char *file); +int openat_create(int fd, const char *file); +int openat_trunc(int fd, const char *file); +int openat_write(int fd, const char *file); + +#endif /* DJBUNIX2_H */ diff --git a/main.c b/main.c index c59bab1..6523780 100644 --- a/main.c +++ b/main.c @@ -10,9 +10,11 @@ #include <errno.h> #include <skalibs/strerr2.h> #include <skalibs/buffer.h> +#include <skalibs/djbunix.h> #include <err.h> #include "qmdoc.h" #include "output.h" +#include "djbunix2.h" #include "md4c.h" const char *PROG = "qmdoc"; @@ -40,7 +42,7 @@ enum { }; static struct css { const char *file; - char *buf; + off_t offset; } css[NB_CSS] = { { "struct.css" }, { "common.css" }, @@ -56,6 +58,7 @@ struct page { struct ctx { int options; FILE *out; + stralloc sa_css; struct css *css; struct page *pages; int nb_pages; @@ -191,7 +194,7 @@ enter_block(MD_BLOCKTYPE type, void *details, void *ctx_) if (ctx->options & OPT_INLINE_CSS) { for (int i = 0; i < NB_CSS; ++i) { if (raw_str(f, "<style>") < 0 - || raw_str(f, ctx->css[i].buf) < 0 + || raw_str(f, ctx->sa_css.s + ctx->css[i].offset) < 0 || raw_str(f, "</style>") < 0) return ERR_IO; } @@ -633,67 +636,6 @@ convert_file(const char *file, struct ctx *ctx) return 0; } -static int -load_file(const char *file, char **dst) -{ - int fd = open(file, O_RDONLY | O_CLOEXEC | O_NONBLOCK); - if (fd < 0) ret(ERR_IO, "cannot open '%s'", file); - - struct stat st; - if (fstat(fd, &st) < 0) { - warn("cannot stat '%s'", file); - close(fd); - return ERR_IO; - } - - FILE *f = fdopen(fd, "re"); - if (!f) { - warn("cannot open '%s'", file); - close(fd); - return ERR_IO; - } - - *dst = malloc(st.st_size + 1); - if (!*dst) { - warn("cannot load '%s'", file); - fclose(f); - return ERR_MEM; - } - - if (fread(*dst, 1, st.st_size, f) != st.st_size) { - free(*dst); - fclose(f); - retx(ERR_IO, "cannot read '%s'", file); - } - (*dst)[st.st_size] = 0; - - fclose(f); - return 0; -} - -static int -write_file(int fdp, const char *path, const char *file, const char *data) -{ - int fd = openat(fdp, file, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC | O_NONBLOCK, 0644); - if (fd < 0) ret(ERR_IO, "cannot create '%s/%s'", path, file); - - FILE *f = fdopen(fd, "w"); - if (!f) { - warn("cannot open '%s/%s'", path, file); - close(fd); - return ERR_IO; - } - - size_t dlen = strlen(data); - if (fwrite(data, 1, dlen, f) != dlen) { - fclose(f); - retx(ERR_IO, "cannot write '%s/%s'", path, file); - } - - fclose(f); - return 0; -} - static int load_page_from_file(const char *file, struct page *page) { @@ -822,26 +764,36 @@ main (int argc, char *argv[]) } } + struct ctx ctx = { + .options = options, + .sa_css = STRALLOC_ZERO, + .css = css, + .pages = pages, + .nb_pages = sizeof(pages) / sizeof(*pages), + }; + if (!(options & OPT_NO_CSS)) { outs((options & OPT_INLINE_CSS) ? "Loading" : "Copying"); outse(" CSS files..."); for (int i = 0; i < NB_CSS; ++i) { - r = load_file(css[i].file, &css[i].buf); - if (r < 0) return -r; - if (!(options & OPT_INLINE_CSS)) { - r = write_file(fddest, destdir, css[i].file, css[i].buf); - if (r < 0) return -r; + if ((options & OPT_INLINE_CSS)) { + css[i].offset = ctx.sa_css.len; + if (!openreadfileclose(css[i].file, &ctx.sa_css, 0)) + strerr_diefu3sys(ERR_IO, "load CSS from '", css[i].file, "'"); + } else { + int from, to; + from = open_read(css[i].file); + if (from < 0) strerr_diefu3sys(ERR_IO, "open '", css[i].file, "'"); + to = openat_excl(fddest, css[i].file); + if (to < 0) strerr_diefu5sys(ERR_IO, "create '", destdir, "/", css[i].file, "'"); + if (fd_cat(from, to) < 0) + strerr_diefu5sys(ERR_IO, "copy CSS to '", destdir, "/", css[i].file, "'"); + fd_close(from); + fd_close(to); } } } - struct ctx ctx = { - .options = options, - .css = css, - .pages = pages, - .nb_pages = sizeof(pages) / sizeof(*pages), - }; - for (int i = optind; i < argc; ++i) { const char *sce = argv[i]; size_t scelen = strlen(sce); diff --git a/openat3.c b/openat3.c new file mode 100644 index 0000000..d54b385 --- /dev/null +++ b/openat3.c @@ -0,0 +1,11 @@ +#include <fcntl.h> +#include <errno.h> + +int +openat3(int fd, const char *file, unsigned int flags) +{ + int r; + do r = openat(fd, file, flags); + while ((r < 0 && errno == EINTR)); + return r; +} diff --git a/openat4.c b/openat4.c new file mode 100644 index 0000000..61c5100 --- /dev/null +++ b/openat4.c @@ -0,0 +1,11 @@ +#include <fcntl.h> +#include <errno.h> + +int +openat4(int fd, const char *file, unsigned int flags, unsigned int mode) +{ + int r; + do r = openat(fd, file, flags, mode); + while ((r < 0 && errno == EINTR)); + return r; +} diff --git a/openat_append.c b/openat_append.c new file mode 100644 index 0000000..5ea9cab --- /dev/null +++ b/openat_append.c @@ -0,0 +1,8 @@ +#include <fcntl.h> +#include "djbunix2.h" + +int +openat_append(int fd, const char *file) +{ + return openat4(fd, file, O_WRONLY | O_CREAT | O_APPEND | O_NONBLOCK, 0666); +} diff --git a/openat_create.c b/openat_create.c new file mode 100644 index 0000000..09a75e1 --- /dev/null +++ b/openat_create.c @@ -0,0 +1,8 @@ +#include <fcntl.h> +#include "djbunix2.h" + +int +openat_create(int fd, const char *file) +{ + return openat4(fd, file, O_WRONLY | O_CREAT | O_NONBLOCK, 0666); +} diff --git a/openat_excl.c b/openat_excl.c new file mode 100644 index 0000000..32ecfb5 --- /dev/null +++ b/openat_excl.c @@ -0,0 +1,8 @@ +#include <fcntl.h> +#include "djbunix2.h" + +int +openat_excl(int fd, const char *file) +{ + return openat4(fd, file, O_WRONLY | O_CREAT | O_EXCL | O_NONBLOCK, 0666); +} diff --git a/openat_read.c b/openat_read.c new file mode 100644 index 0000000..528a38b --- /dev/null +++ b/openat_read.c @@ -0,0 +1,8 @@ +#include <fcntl.h> +#include "djbunix2.h" + +int +openat_read(int fd, const char *file) +{ + return openat3(fd, file, O_RDONLY | O_NONBLOCK); +} diff --git a/openat_readb.c b/openat_readb.c new file mode 100644 index 0000000..45539ea --- /dev/null +++ b/openat_readb.c @@ -0,0 +1,15 @@ +#include <skalibs/djbunix.h> +#include <fcntl.h> +#include "djbunix2.h" + +int +openat_readb(int fd, const char *file) +{ + int ffd = openat_read(fd, file); + if (ffd < 0) return -1; + if (ndelay_off(ffd) < 0) { + fd_close(ffd); + return -1; + } + return ffd; +} diff --git a/openat_trunc.c b/openat_trunc.c new file mode 100644 index 0000000..8efc820 --- /dev/null +++ b/openat_trunc.c @@ -0,0 +1,8 @@ +#include <fcntl.h> +#include "djbunix2.h" + +int +openat_trunc(int fd, const char *file) +{ + return openat4(fd, file, O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK, 0666); +} diff --git a/openat_write.c b/openat_write.c new file mode 100644 index 0000000..df6ae80 --- /dev/null +++ b/openat_write.c @@ -0,0 +1,8 @@ +#include <fcntl.h> +#include "djbunix2.h" + +int +openat_write(int fd, const char *file) +{ + return openat3(fd, file, O_WRONLY | O_NONBLOCK); +} diff --git a/openatb_read.c b/openatb_read.c new file mode 100644 index 0000000..ce8d5a5 --- /dev/null +++ b/openatb_read.c @@ -0,0 +1,8 @@ +#include <fcntl.h> +#include "djbunix2.h" + +int +openatb_read(int fd, const char *file) +{ + return openat3(fd, file, O_RDONLY); +}