Skip to content

Commit df3f9df

Browse files
authored
Merge pull request #127 from kolyshkin/eintr
go-selinux: retry on EINTR
2 parents bca2471 + 505b9d3 commit df3f9df

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

go-selinux/selinux_linux.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ func verifySELinuxfsMount(mnt string) bool {
111111
if err == nil {
112112
break
113113
}
114-
if err == unix.EAGAIN {
114+
if err == unix.EAGAIN || err == unix.EINTR {
115115
continue
116116
}
117117
return false
@@ -251,9 +251,15 @@ func getSELinuxPolicyRoot() string {
251251

252252
func isProcHandle(fh *os.File) error {
253253
var buf unix.Statfs_t
254-
err := unix.Fstatfs(int(fh.Fd()), &buf)
255-
if err != nil {
256-
return errors.Wrapf(err, "statfs(%q) failed", fh.Name())
254+
255+
for {
256+
err := unix.Fstatfs(int(fh.Fd()), &buf)
257+
if err == nil {
258+
break
259+
}
260+
if err != unix.EINTR {
261+
return errors.Wrapf(err, "statfs(%q) failed", fh.Name())
262+
}
257263
}
258264
if buf.Type != unix.PROC_SUPER_MAGIC {
259265
return errors.Errorf("file %q is not on procfs", fh.Name())
@@ -307,9 +313,16 @@ func setFileLabel(fpath string, label string) error {
307313
if fpath == "" {
308314
return ErrEmptyPath
309315
}
310-
if err := unix.Lsetxattr(fpath, xattrNameSelinux, []byte(label), 0); err != nil {
311-
return errors.Wrapf(err, "failed to set file label on %s", fpath)
316+
for {
317+
err := unix.Lsetxattr(fpath, xattrNameSelinux, []byte(label), 0)
318+
if err == nil {
319+
break
320+
}
321+
if err != unix.EINTR {
322+
return errors.Wrapf(err, "failed to set file label on %s", fpath)
323+
}
312324
}
325+
313326
return nil
314327
}
315328

go-selinux/xattrs.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,35 @@ import (
66
"golang.org/x/sys/unix"
77
)
88

9-
// Returns a []byte slice if the xattr is set and nil otherwise
10-
// Requires path and its attribute as arguments
11-
func lgetxattr(path string, attr string) ([]byte, error) {
9+
// lgetxattr returns a []byte slice containing the value of
10+
// an extended attribute attr set for path.
11+
func lgetxattr(path, attr string) ([]byte, error) {
1212
// Start with a 128 length byte array
1313
dest := make([]byte, 128)
14-
sz, errno := unix.Lgetxattr(path, attr, dest)
14+
sz, errno := doLgetxattr(path, attr, dest)
1515
for errno == unix.ERANGE {
1616
// Buffer too small, use zero-sized buffer to get the actual size
17-
sz, errno = unix.Lgetxattr(path, attr, []byte{})
17+
sz, errno = doLgetxattr(path, attr, []byte{})
1818
if errno != nil {
1919
return nil, errno
2020
}
2121

2222
dest = make([]byte, sz)
23-
sz, errno = unix.Lgetxattr(path, attr, dest)
23+
sz, errno = doLgetxattr(path, attr, dest)
2424
}
2525
if errno != nil {
2626
return nil, errno
2727
}
2828

2929
return dest[:sz], nil
3030
}
31+
32+
// doLgetxattr is a wrapper that retries on EINTR
33+
func doLgetxattr(path, attr string, dest []byte) (int, error) {
34+
for {
35+
sz, err := unix.Lgetxattr(path, attr, dest)
36+
if err != unix.EINTR {
37+
return sz, err
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)