fortify: keep external files alive
This should eliminate sporadic failures, like the known double close in "seccomp". Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
2e7e160683
commit
eda4d612c2
@ -5,6 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewWriterTo returns a [File] that receives content from wt on fulfillment.
|
// NewWriterTo returns a [File] that receives content from wt on fulfillment.
|
||||||
@ -25,13 +26,20 @@ func (f *writeToFile) Fulfill(ctx context.Context, dispatchErr func(error)) erro
|
|||||||
f.Set(r)
|
f.Set(r)
|
||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() { _, err = f.wt.WriteTo(w); dispatchErr(err); dispatchErr(w.Close()); close(done) }()
|
go func() {
|
||||||
|
_, err = f.wt.WriteTo(w)
|
||||||
|
dispatchErr(err)
|
||||||
|
dispatchErr(w.Close())
|
||||||
|
close(done)
|
||||||
|
runtime.KeepAlive(r)
|
||||||
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case <-done:
|
||||||
dispatchErr(nil)
|
dispatchErr(nil)
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
dispatchErr(w.Close()) // this aborts WriteTo with file already closed
|
dispatchErr(w.Close()) // this aborts WriteTo with file already closed
|
||||||
|
runtime.KeepAlive(r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -83,6 +91,7 @@ func (f *statFile) Fulfill(ctx context.Context, dispatchErr func(error)) error {
|
|||||||
default:
|
default:
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
runtime.KeepAlive(w)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@ -91,6 +100,7 @@ func (f *statFile) Fulfill(ctx context.Context, dispatchErr func(error)) error {
|
|||||||
dispatchErr(nil)
|
dispatchErr(nil)
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
dispatchErr(r.Close()) // this aborts Read with file already closed
|
dispatchErr(r.Close()) // this aborts Read with file already closed
|
||||||
|
runtime.KeepAlive(w)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -27,7 +27,12 @@ func (e *exporter) prepare() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ec := make(chan error, 1)
|
ec := make(chan error, 1)
|
||||||
go func(fd uintptr) { ec <- exportFilter(fd, e.opts); close(ec); _ = e.closeWrite() }(e.w.Fd())
|
go func(fd uintptr) {
|
||||||
|
ec <- exportFilter(fd, e.opts)
|
||||||
|
close(ec)
|
||||||
|
_ = e.closeWrite()
|
||||||
|
runtime.KeepAlive(e.w)
|
||||||
|
}(e.w.Fd())
|
||||||
e.exportErr = ec
|
e.exportErr = ec
|
||||||
runtime.SetFinalizer(e, (*exporter).closeWrite)
|
runtime.SetFinalizer(e, (*exporter).closeWrite)
|
||||||
})
|
})
|
||||||
|
@ -94,6 +94,7 @@ func bindRawConn(done chan struct{}, rc syscall.RawConn, p, appID, instanceID st
|
|||||||
|
|
||||||
// keep socket alive until done is requested
|
// keep socket alive until done is requested
|
||||||
<-done
|
<-done
|
||||||
|
runtime.KeepAlive(syncPipe[1].Fd())
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
setupDone <- err
|
setupDone <- err
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ static const struct wl_registry_listener registry_listener = {
|
|||||||
.global_remove = registry_handle_global_remove,
|
.global_remove = registry_handle_global_remove,
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t bind_wayland_fd(char *socket_path, int fd, const char *app_id, const char *instance_id, int sync_fd) {
|
int32_t f_bind_wayland_fd(char *socket_path, int fd, const char *app_id, const char *instance_id, int sync_fd) {
|
||||||
int32_t res = 0; // refer to resErr for meaning
|
int32_t res = 0; // refer to resErr for meaning
|
||||||
|
|
||||||
struct wl_display *display;
|
struct wl_display *display;
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
int32_t bind_wayland_fd(char *socket_path, int fd, const char *app_id, const char *instance_id, int sync_fd);
|
int32_t f_bind_wayland_fd(char *socket_path, int fd, const char *app_id, const char *instance_id, int sync_fd);
|
2
wl/wl.go
2
wl/wl.go
@ -29,7 +29,7 @@ func bindWaylandFd(socketPath string, fd uintptr, appID, instanceID string, sync
|
|||||||
if hasNull(appID) || hasNull(instanceID) {
|
if hasNull(appID) || hasNull(instanceID) {
|
||||||
return ErrContainsNull
|
return ErrContainsNull
|
||||||
}
|
}
|
||||||
res := C.bind_wayland_fd(C.CString(socketPath), C.int(fd), C.CString(appID), C.CString(instanceID), C.int(syncFD))
|
res := C.f_bind_wayland_fd(C.CString(socketPath), C.int(fd), C.CString(appID), C.CString(instanceID), C.int(syncFD))
|
||||||
return resErr[int32(res)]
|
return resErr[int32(res)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user