commit 012b6addd19104dcaee9a9df1d116ac7da4926fb
parent 2597446a7de2a063b985341ddbc1b02ab30943fb
Author: gearsix <gearsix@tuta.io>
Date: Wed, 24 Nov 2021 14:52:24 +0000
new copy.go#CopyFile, uses copyf (C func) - around x2 faster
Diffstat:
M | Makefile | | | 2 | +- |
A | copy.go | | | 74 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | page.go | | | 21 | --------------------- |
M | pagr.go | | | 2 | +- |
4 files changed, 76 insertions(+), 23 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,5 +1,5 @@
OUT=./pagr
-SRC=pagr.go config.go page.go template.go
+SRC=pagr.go config.go page.go template.go copy.go
all:
go clean
diff --git a/copy.go b/copy.go
@@ -0,0 +1,74 @@
+package main
+
+/*
+#include <stdio.h>
+#include <stdlib.h>
+
+int copyf(const char *src, const char *dst)
+{
+ int ret = EXIT_FAILURE;
+
+ FILE *srcf, *dstf;
+ if ((!(srcf = fopen(src, "r"))) ||
+ (!(dstf = fopen(dst, "w"))))
+ goto ABORT;
+
+ char buf[BUFSIZ];
+ int n;
+ do {
+ n = fread(buf, sizeof(char), BUFSIZ, srcf);
+ if (ferror(srcf)) perror("fread failure");
+ else {
+ fwrite(buf, sizeof(char), n, dstf);
+ if (ferror(dstf)) perror("fwrite failure");
+ }
+ } while (!feof(srcf) && !ferror(srcf) && !ferror(dstf));
+ ret = EXIT_SUCCESS;
+
+ABORT:
+ if (srcf) fclose(srcf);
+ if (dstf) fclose(dstf);
+ return ret;
+}
+*/
+import "C"
+import (
+ "fmt"
+ "path/filepath"
+ "os"
+ "unsafe"
+)
+
+func CopyFile(src, dst string) (err error) {
+ var srcfi, dstfi os.FileInfo
+
+ if err = os.MkdirAll(filepath.Dir(dst), 0777); err != nil {
+ return err
+ }
+
+ if srcfi, err = os.Stat(src); err != nil {
+ return err
+ } else if !srcfi.Mode().IsRegular() {
+ return fmt.Errorf("cannot copy from non-regular source file %s (%q)",
+ srcfi.Name(), srcfi.Mode().String())
+ }
+
+ if dstfi, err = os.Stat(dst); err != nil && !os.IsNotExist(err) {
+ return err
+ } else if !dstfi.Mode().IsRegular() {
+ return fmt.Errorf("cannot copy to non-regular destination file %s (%q)",
+ dstfi.Name(), dstfi.Mode().String())
+ } else if os.SameFile(srcfi, dstfi) {
+ return nil
+ }
+
+ cSrc := C.CString(src)
+ cDst := C.CString(dst)
+ if uint32(C.copyf(cSrc, cDst)) != 0 {
+ err = fmt.Errorf("copyf failed ('%s' -> '%s')", src, dst)
+ }
+ C.free(unsafe.Pointer(cSrc))
+ C.free(unsafe.Pointer(cDst))
+
+ return
+}
diff --git a/page.go b/page.go
@@ -346,27 +346,6 @@ func (p *Page) CopyAssets(srcDir, outDir string) (err error) {
return
}
-func CopyFile(src, dst string) (err error) {
- if err = os.MkdirAll(filepath.Dir(dst), 0777); err != nil {
- return err
- }
-
- var srcf, dstf *os.File
- if srcf, err = os.Open(src); err != nil {
- return err
- }
- defer srcf.Close()
- if dstf, err = os.OpenFile(dst, os.O_RDWR|os.O_CREATE, 0644); err != nil {
- return err
- }
- defer dstf.Close()
-
- if _, err = io.Copy(dstf, srcf); err != nil {
- return err
- }
- return dstf.Sync()
-}
-
func (p *Page) Build(outDir string, t suti.Template) (out string, err error) {
var buf bytes.Buffer
if buf, err = t.Execute(p); err == nil {
diff --git a/pagr.go b/pagr.go
@@ -124,7 +124,7 @@ func copyAssets(wg sync.WaitGroup, cfg Config) (n int) {
a = filepath.Clean(a)
path := strings.TrimPrefix(src, a)
n++
- CopyFile(src, filepath.Join(cfg.Output, path))
+ check(CopyFile(src, filepath.Join(cfg.Output, path)))
vlog("-> %s", path)
}
return err