Update all modules/deps (#288)

pull/284/head^2
Simon Roberts 3 years ago committed by GitHub
parent 2d9b1501c6
commit 62ce8e1adb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -6,13 +6,13 @@ require (
github.com/BurntSushi/toml v0.4.1 github.com/BurntSushi/toml v0.4.1
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/antonmedv/expr v1.9.0 github.com/antonmedv/expr v1.9.0
github.com/creack/pty v1.1.16 github.com/creack/pty v1.1.17
github.com/fatih/color v1.13.0 github.com/fatih/color v1.13.0
github.com/gdamore/tcell/v2 v2.4.0 github.com/gdamore/tcell/v2 v2.4.0
github.com/gen2brain/beeep v0.0.0-20210529141713-5586760f0cc1 github.com/gen2brain/beeep v0.0.0-20210529141713-5586760f0cc1
github.com/gliderlabs/ssh v0.3.3 github.com/gliderlabs/ssh v0.3.3
github.com/goodsign/monday v1.0.0 github.com/goodsign/monday v1.0.0
github.com/jeandeaual/go-locale v0.0.0-20210323163322-5cf4ff553a8d github.com/jeandeaual/go-locale v0.0.0-20211014152413-b809787f45c8
github.com/mattn/go-runewidth v0.0.13 github.com/mattn/go-runewidth v0.0.13
github.com/miguelmota/go-coinmarketcap v0.1.8 github.com/miguelmota/go-coinmarketcap v0.1.8
github.com/mitchellh/go-wordwrap v1.0.1 github.com/mitchellh/go-wordwrap v1.0.1
@ -20,27 +20,27 @@ require (
github.com/patrickmn/go-cache v2.1.0+incompatible github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/sirupsen/logrus v1.8.1 github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.2.1 github.com/spf13/cobra v1.2.1
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871
golang.org/x/text v0.3.7 golang.org/x/text v0.3.7
) )
require ( require (
github.com/anaskhan96/soup v1.0.1 // indirect github.com/anaskhan96/soup v1.2.4 // indirect
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
github.com/gdamore/encoding v1.0.0 // indirect github.com/gdamore/encoding v1.0.0 // indirect
github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 // indirect github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 // indirect
github.com/godbus/dbus/v5 v5.0.4 // indirect github.com/godbus/dbus/v5 v5.0.6 // indirect
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect github.com/gopherjs/gopherjs v0.0.0-20211111143520-d0d5ecc1a356 // indirect
github.com/gopherjs/gopherwasm v1.1.0 // indirect github.com/gopherjs/gopherwasm v1.1.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/lucasb-eyer/go-colorful v1.0.3 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-colorable v0.1.9 // indirect github.com/mattn/go-colorable v0.1.11 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-isatty v0.0.14 // indirect
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
github.com/rivo/uniseg v0.2.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4 // indirect
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 // indirect
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
) )

@ -47,8 +47,9 @@ github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9/go.mod
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
github.com/anaskhan96/soup v1.0.1 h1:3p9zOr7o2weHqDakRA1uR0SZNr6VhH5qPkm6p3gvS6o=
github.com/anaskhan96/soup v1.0.1/go.mod h1:pT5vs4HXDwA5y4KQCsKvnkpQd3D+joP7IqpiGskfWW0= github.com/anaskhan96/soup v1.0.1/go.mod h1:pT5vs4HXDwA5y4KQCsKvnkpQd3D+joP7IqpiGskfWW0=
github.com/anaskhan96/soup v1.2.4 h1:or+sKs9QbzJGZVTYFmTs2VBateEywoq00a6K14z331E=
github.com/anaskhan96/soup v1.2.4/go.mod h1:6YnEp9A2yywlYdM4EgDz9NEHclocMepEtku7wg6Cq3s=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
@ -70,8 +71,8 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnht
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.16 h1:vfetlOf3A+9YKggibynnX9mnFjuSVvkRj+IWpcTSLEQ= github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
github.com/creack/pty v1.1.16/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -108,8 +109,9 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200625191551-73d3c3675aa3/go.mod h1:tQ2
github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 h1:qZNfIGkIANxGv/OqtnntR4DfOY2+BgwR60cAcu/i3SE= github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 h1:qZNfIGkIANxGv/OqtnntR4DfOY2+BgwR60cAcu/i3SE=
github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4/go.mod h1:kW3HQ4UdaAyrUCSSDR4xUzBKW6O2iA4uHhk7AtyYp10= github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4/go.mod h1:kW3HQ4UdaAyrUCSSDR4xUzBKW6O2iA4uHhk7AtyYp10=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.6 h1:mkgN1ofwASrYnJ5W6U/BxG15eXXXjirgZc7CLqkcaro=
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff/go.mod h1:wfqRWLHRBsRgkp5dmbG56SA0DmVtwrF5N3oPdI8t+Aw= github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff/go.mod h1:wfqRWLHRBsRgkp5dmbG56SA0DmVtwrF5N3oPdI8t+Aw=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@ -156,6 +158,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@ -176,8 +179,9 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20211111143520-d0d5ecc1a356 h1:d3wWSjdOuGrMHa8+Tvw3z9EGPzATpzVq1BmGK3+IyeU=
github.com/gopherjs/gopherjs v0.0.0-20211111143520-d0d5ecc1a356/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI=
github.com/gopherjs/gopherwasm v1.1.0 h1:fA2uLoctU5+T3OhOn2vYP0DVT6pxc7xhTlBB1paATqQ= github.com/gopherjs/gopherwasm v1.1.0 h1:fA2uLoctU5+T3OhOn2vYP0DVT6pxc7xhTlBB1paATqQ=
github.com/gopherjs/gopherwasm v1.1.0/go.mod h1:SkZ8z7CWBz5VXbhJel8TxCmAcsQqzgWGR/8nMhyhZSI= github.com/gopherjs/gopherwasm v1.1.0/go.mod h1:SkZ8z7CWBz5VXbhJel8TxCmAcsQqzgWGR/8nMhyhZSI=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
@ -206,8 +210,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526/go.mod h1:UQkeMHVoNcyXYq9otUupF7/h/2tmHlhrS2zw7ZVvUqc= github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526/go.mod h1:UQkeMHVoNcyXYq9otUupF7/h/2tmHlhrS2zw7ZVvUqc=
github.com/jeandeaual/go-locale v0.0.0-20210323163322-5cf4ff553a8d h1:VPBM6qn7uSBJroH61nL9yqtfK0xDWcmI5JHl11a2CJ0= github.com/jeandeaual/go-locale v0.0.0-20211014152413-b809787f45c8 h1:t3zg0eJ2qUP6yqqcwicCBqqaQVKs3ul4n27CAcyh0aw=
github.com/jeandeaual/go-locale v0.0.0-20210323163322-5cf4ff553a8d/go.mod h1:S0Hh9Ro1RbEQKfJA5XcnmGjcSQF+ZdSVikXVNQJMTAo= github.com/jeandeaual/go-locale v0.0.0-20211014152413-b809787f45c8/go.mod h1:3/uOR/xyUPi69BwdDezaGEixFZOspXUmKujIOg2r8JM=
github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE= github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
@ -220,13 +224,15 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s=
github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac=
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/lucor/goinfo v0.0.0-20200401173949-526b5363a13a/go.mod h1:ORP3/rB5IsulLEBwQZCJyyV6niqmI7P4EWSmkug+1Ng= github.com/lucor/goinfo v0.0.0-20200401173949-526b5363a13a/go.mod h1:ORP3/rB5IsulLEBwQZCJyyV6niqmI7P4EWSmkug+1Ng=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
@ -253,6 +259,8 @@ github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/nicksnyder/go-i18n/v2 v2.1.1/go.mod h1:d++QJC9ZVf7pa48qrsRWhMJ5pSHIPmS3OLqK1niyLxs= github.com/nicksnyder/go-i18n/v2 v2.1.1/go.mod h1:d++QJC9ZVf7pa48qrsRWhMJ5pSHIPmS3OLqK1niyLxs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
@ -283,7 +291,10 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sanity-io/litter v1.2.0/go.mod h1:JF6pZUFgu2Q0sBZ+HSV35P8TVPI1TTzEwyu9FXAw2W4= github.com/sanity-io/litter v1.2.0/go.mod h1:JF6pZUFgu2Q0sBZ+HSV35P8TVPI1TTzEwyu9FXAw2W4=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
@ -338,8 +349,9 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI=
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -412,8 +424,10 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4 h1:DZshvxDdVoeKIbudAdFEKi+f70l51luSy/7b76ibTY0=
golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -473,7 +487,6 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201223074533-0d417f636930/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -482,14 +495,19 @@ golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 h1:kwrAHlwJ0DUBZwQ238v+Uod/3eZ8B2K5rYsUHBQvzmI=
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -497,6 +515,7 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -555,6 +574,7 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

@ -1,9 +1,7 @@
language: go language: go
go: go:
- 1.6.x - 1.15.x
- 1.7.x
- 1.8.x
script: script:
- go test - go test

@ -0,0 +1,21 @@
## v1.2.0
### Added
- Error enums which can be accessed using `Root.Error.(soup.Error).Type`. Refer to `examples/errors`.
## v1.1.0
### Added
- Cookies can be added to the HTTP request, either via the `Cookies` map or the `Cookie()` function
- Function `GetWithClient()` provides the ability to send the request with a custom HTTP client
- Function `FindStrict()` finds the first instance of the mentioned tag with the exact matching values of the provided attribute (previously `Find()`)
- Function `FindAllStrict()` finds all the instances of the mentioned tag with the exact matching values of the attributes (previously `FindAll()`)
## Changed
- Function `Find()` now finds the first instance of the mentioned tag with any matching values of the provided attribute.
- Function `FindAll()` now finds all the instances of the mentioned tag with any matching values of the provided attribute.
---

@ -1,32 +1,53 @@
# soup # soup
[![Build Status](https://travis-ci.org/anaskhan96/soup.svg?branch=master)](https://travis-ci.org/anaskhan96/soup) [![Build Status](https://travis-ci.org/anaskhan96/soup.svg?branch=master)](https://travis-ci.org/anaskhan96/soup)
[![GoDoc](https://godoc.org/github.com/anaskhan96/soup?status.svg)](https://godoc.org/github.com/anaskhan96/soup) [![GoDoc](https://godoc.org/github.com/anaskhan96/soup?status.svg)](https://pkg.go.dev/github.com/anaskhan96/soup)
[![Go Report Card](https://goreportcard.com/badge/github.com/anaskhan96/soup)](https://goreportcard.com/report/github.com/anaskhan96/soup) [![Go Report Card](https://goreportcard.com/badge/github.com/anaskhan96/soup)](https://goreportcard.com/report/github.com/anaskhan96/soup)
**Web Scraper in Go, similar to BeautifulSoup** **Web Scraper in Go, similar to BeautifulSoup**
*soup* is a small web scraper package for Go, with its interface highly similar to that of BeautifulSoup. *soup* is a small web scraper package for Go, with its interface highly similar to that of BeautifulSoup.
Functions implemented till now : Exported variables and functions implemented till now :
```go ```go
func Get(string) (string,error) // Takes the url as an argument, returns HTML string var Headers map[string]string // Set headers as a map of key-value pairs, an alternative to calling Header() individually
func Header(string, string) // Takes key,value pair to set as headers for the HTTP request made in Get(), refer to PR #11 for more usage var Cookies map[string]string // Set cookies as a map of key-value pairs, an alternative to calling Cookie() individually
func HTMLParse(string) struct{} // Takes the HTML string as an argument, returns a pointer to the DOM constructed func Get(string) (string,error) {} // Takes the url as an argument, returns HTML string
func Find([]string) struct{} // Element tag,(attribute key-value pair) as argument, pointer to first occurence returned func GetWithClient(string, *http.Client) {} // Takes the url and a custom HTTP client as arguments, returns HTML string
func FindAll([]string) []struct{} // Same as Find(), but pointers to all occurrences returned func Post(string, string, interface{}) (string, error) {} // Takes the url, bodyType, and payload as an argument, returns HTML string
func FindNextSibling() struct{} // Pointer to the next sibling of the Element in the DOM returned func PostForm(string, url.Values) {} // Takes the url and body. bodyType is set to "application/x-www-form-urlencoded"
func FindNextElementSibling() struct{} // Pointer to the next element sibling of the Element in the DOM returned func Header(string, string) {} // Takes key,value pair to set as headers for the HTTP request made in Get()
func FindPrevSibling() struct{} // Pointer to the previous sibling of the Element in the DOM returned func Cookie(string, string) {} // Takes key, value pair to set as cookies to be sent with the HTTP request in Get()
func FindPrevElementSibling() struct{} // Pointer to the previous element sibling of the Element in the DOM returned func HTMLParse(string) Root {} // Takes the HTML string as an argument, returns a pointer to the DOM constructed
func Attrs() map[string]string // Map returned with all the attributes of the Element as lookup to their respective values func Find([]string) Root {} // Element tag,(attribute key-value pair) as argument, pointer to first occurence returned
func Text() string // Full text inside a non-nested tag returned func FindAll([]string) []Root {} // Same as Find(), but pointers to all occurrences returned
func SetDebug(bool) // Sets the debug mode to true or false; false by default func FindStrict([]string) Root {} // Element tag,(attribute key-value pair) as argument, pointer to first occurence returned with exact matching values
func FindAllStrict([]string) []Root {} // Same as FindStrict(), but pointers to all occurrences returned
func FindNextSibling() Root {} // Pointer to the next sibling of the Element in the DOM returned
func FindNextElementSibling() Root {} // Pointer to the next element sibling of the Element in the DOM returned
func FindPrevSibling() Root {} // Pointer to the previous sibling of the Element in the DOM returned
func FindPrevElementSibling() Root {} // Pointer to the previous element sibling of the Element in the DOM returned
func Children() []Root {} // Find all direct children of this DOM element
func Attrs() map[string]string {} // Map returned with all the attributes of the Element as lookup to their respective values
func Text() string {} // Full text inside a non-nested tag returned, first half returned in a nested one
func FullText() string {} // Full text inside a nested/non-nested tag returned
func SetDebug(bool) {} // Sets the debug mode to true or false; false by default
func HTML() {} // HTML returns the HTML code for the specific element
``` ```
The struct returned by the functions has three fields : `Root` is a struct, containing three fields :
* `Pointer` containing the pointer to the current html node * `Pointer` containing the pointer to the current html node
* `NodeValue` containing the current html node's value, i.e. the tag name for an ElementNode, or the text in case of a TextNode * `NodeValue` containing the current html node's value, i.e. the tag name for an ElementNode, or the text in case of a TextNode
* `Error` containing an error if one occurrs, else `nil` is returned. * `Error` containing an error in a struct if one occurrs, else `nil` is returned.
A detailed text explaination of the error can be accessed using the `Error()` function. A field `Type` in this struct of type `ErrorType` will denote the kind of error that took place, which will consist of either of the following
* `ErrUnableToParse`
* `ErrElementNotFound`
* `ErrNoNextSibling`
* `ErrNoPreviousSibling`
* `ErrNoNextElementSibling`
* `ErrNoPreviousElementSibling`
* `ErrCreatingGetRequest`
* `ErrInGetRequest`
* `ErrReadingResponse`
## Installation ## Installation
Install the package using the command Install the package using the command
@ -61,4 +82,4 @@ func main() {
``` ```
## Contributions ## Contributions
This package was developed in my free time. However, contributions from everybody in the community are welcome, to make it a better web scraper. If you feel there should be a particular new feature or function in the package, feel free to open up a new issue or pull request. This package was developed in my free time. However, contributions from everybody in the community are welcome, to make it a better web scraper. If you think there should be a particular feature or function included in the package, feel free to open up a new issue or pull request.

@ -5,27 +5,87 @@ keeping it as similar as possible to BeautifulSoup
package soup package soup
import ( import (
"errors" "bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil" "io/ioutil"
"log"
"net/http" "net/http"
"net/http/httputil"
"net/url"
netURL "net/url"
"regexp" "regexp"
"strings" "strings"
"golang.org/x/net/html" "golang.org/x/net/html"
"golang.org/x/net/html/charset"
) )
// Root is a structure containing a pointer to an html node, the node value, and an error variable to return an error if occurred // ErrorType defines types of errors that are possible from soup
type ErrorType int
const (
// ErrUnableToParse will be returned when the HTML could not be parsed
ErrUnableToParse ErrorType = iota
// ErrElementNotFound will be returned when element was not found
ErrElementNotFound
// ErrNoNextSibling will be returned when no next sibling can be found
ErrNoNextSibling
// ErrNoPreviousSibling will be returned when no previous sibling can be found
ErrNoPreviousSibling
// ErrNoNextElementSibling will be returned when no next element sibling can be found
ErrNoNextElementSibling
// ErrNoPreviousElementSibling will be returned when no previous element sibling can be found
ErrNoPreviousElementSibling
// ErrCreatingGetRequest will be returned when the get request couldn't be created
ErrCreatingGetRequest
// ErrInGetRequest will be returned when there was an error during the get request
ErrInGetRequest
// ErrCreatingPostRequest will be returned when the post request couldn't be created
ErrCreatingPostRequest
// ErrMarshallingPostRequest will be returned when the body of a post request couldn't be serialized
ErrMarshallingPostRequest
// ErrReadingResponse will be returned if there was an error reading the response to our get request
ErrReadingResponse
)
// Error allows easier introspection on the type of error returned.
// If you know you have a Error, you can compare the Type to one of the exported types
// from this package to see what kind of error it is, then further inspect the Error() method
// to see if it has more specific details for you, like in the case of a ErrElementNotFound
// type of error.
type Error struct {
Type ErrorType
msg string
}
func (se Error) Error() string {
return se.msg
}
func newError(t ErrorType, msg string) Error {
return Error{Type: t, msg: msg}
}
// Root is a structure containing a pointer to an html node, the node value, and an error variable to return an error if one occurred
type Root struct { type Root struct {
Pointer *html.Node Pointer *html.Node
NodeValue string NodeValue string
Error error Error error
} }
var debug = false // Init a new HTTP client for use when the client doesn't want to use their own.
var (
defaultClient = &http.Client{}
// Headers contains all HTTP headers to send debug = false
var Headers = make(map[string]string)
// Headers contains all HTTP headers to send
Headers = make(map[string]string)
// Cookies contains all HTTP cookies to send
Cookies = make(map[string]string)
)
// SetDebug sets the debug status // SetDebug sets the debug status
// Setting this to true causes the panics to be thrown and logged onto the console. // Setting this to true causes the panics to be thrown and logged onto the console.
@ -39,29 +99,119 @@ func Header(n string, v string) {
Headers[n] = v Headers[n] = v
} }
// Get returns the HTML returned by the url in string // Cookie sets a cookie for http requests
func Get(url string) (string, error) { func Cookie(n string, v string) {
defer catchPanic("Get()") Cookies[n] = v
// Init a new HTTP client }
client := &http.Client{}
// GetWithClient returns the HTML returned by the url using a provided HTTP client
func GetWithClient(url string, client *http.Client) (string, error) {
req, err := http.NewRequest("GET", url, nil) req, err := http.NewRequest("GET", url, nil)
if err != nil {
if debug {
panic("Couldn't create GET request to " + url)
}
return "", newError(ErrCreatingGetRequest, "error creating get request to "+url)
}
setHeadersAndCookies(req)
// Perform request
resp, err := client.Do(req)
if err != nil { if err != nil {
if debug { if debug {
panic("Couldn't perform GET request to " + url) panic("Couldn't perform GET request to " + url)
} }
return "", errors.New("Couldn't perform GET request to " + url) return "", newError(ErrInGetRequest, "couldn't perform GET request to "+url)
} }
defer resp.Body.Close()
utf8Body, err := charset.NewReader(resp.Body, resp.Header.Get("Content-Type"))
if err != nil {
return "", err
}
bytes, err := ioutil.ReadAll(utf8Body)
if err != nil {
if debug {
panic("Unable to read the response body")
}
return "", newError(ErrReadingResponse, "unable to read the response body")
}
return string(bytes), nil
}
// setHeadersAndCookies helps build a request
func setHeadersAndCookies(req *http.Request) {
// Set headers // Set headers
for hName, hValue := range Headers { for hName, hValue := range Headers {
req.Header.Set(hName, hValue) req.Header.Set(hName, hValue)
} }
// Set cookies
for cName, cValue := range Cookies {
req.AddCookie(&http.Cookie{
Name: cName,
Value: cValue,
})
}
}
// getBodyReader serializes the body for a network request. See the test file for examples
func getBodyReader(rawBody interface{}) (io.Reader, error) {
var bodyReader io.Reader
if rawBody != nil {
switch body := rawBody.(type) {
case map[string]string:
jsonBody, err := json.Marshal(body)
if err != nil {
if debug {
panic("Unable to read the response body")
}
return nil, newError(ErrMarshallingPostRequest, "couldn't serialize map of strings to JSON.")
}
bodyReader = bytes.NewBuffer(jsonBody)
case netURL.Values:
bodyReader = strings.NewReader(body.Encode())
case []byte: //expects JSON format
bodyReader = bytes.NewBuffer(body)
case string: //expects JSON format
bodyReader = strings.NewReader(body)
default:
return nil, newError(ErrMarshallingPostRequest, fmt.Sprintf("Cannot handle body type %T", rawBody))
}
}
return bodyReader, nil
}
// PostWithClient returns the HTML returned by the url using a provided HTTP client
// The type of the body must conform to one of the types listed in func getBodyReader()
func PostWithClient(url string, bodyType string, body interface{}, client *http.Client) (string, error) {
bodyReader, err := getBodyReader(body)
if err != nil {
return "todo:", err
}
req, err := http.NewRequest("POST", url, bodyReader)
Header("Content-Type", bodyType)
setHeadersAndCookies(req)
if debug {
// Save a copy of this request for debugging.
requestDump, err := httputil.DumpRequest(req, true)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(requestDump))
}
// Perform request // Perform request
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
if debug { if debug {
panic("Couldn't perform GET request to " + url) panic("Couldn't perform POST request to " + url)
} }
return "", errors.New("Couldn't perform GET request to " + url) return "", newError(ErrCreatingPostRequest, "couldn't perform POST request to"+url)
} }
defer resp.Body.Close() defer resp.Body.Close()
bytes, err := ioutil.ReadAll(resp.Body) bytes, err := ioutil.ReadAll(resp.Body)
@ -69,20 +219,34 @@ func Get(url string) (string, error) {
if debug { if debug {
panic("Unable to read the response body") panic("Unable to read the response body")
} }
return "", errors.New("Unable to read the response body") return "", newError(ErrReadingResponse, "unable to read the response body")
} }
return string(bytes), nil return string(bytes), nil
} }
// Post returns the HTML returned by the url as a string using the default HTTP client
func Post(url string, bodyType string, body interface{}) (string, error) {
return PostWithClient(url, bodyType, body, defaultClient)
}
// PostForm is a convenience method for POST requests that
func PostForm(url string, data url.Values) (string, error) {
return PostWithClient(url, "application/x-www-form-urlencoded", data, defaultClient)
}
// Get returns the HTML returned by the url as a string using the default HTTP client
func Get(url string) (string, error) {
return GetWithClient(url, defaultClient)
}
// HTMLParse parses the HTML returning a start pointer to the DOM // HTMLParse parses the HTML returning a start pointer to the DOM
func HTMLParse(s string) Root { func HTMLParse(s string) Root {
defer catchPanic("HTMLParse()")
r, err := html.Parse(strings.NewReader(s)) r, err := html.Parse(strings.NewReader(s))
if err != nil { if err != nil {
if debug { if debug {
panic("Unable to parse the HTML") panic("Unable to parse the HTML")
} }
return Root{nil, "", errors.New("Unable to parse the HTML")} return Root{Error: newError(ErrUnableToParse, "unable to parse the HTML")}
} }
for r.Type != html.ElementNode { for r.Type != html.ElementNode {
switch r.Type { switch r.Type {
@ -94,22 +258,21 @@ func HTMLParse(s string) Root {
r = r.NextSibling r = r.NextSibling
} }
} }
return Root{r, r.Data, nil} return Root{Pointer: r, NodeValue: r.Data}
} }
// Find finds the first occurrence of the given tag name, // Find finds the first occurrence of the given tag name,
// with or without attribute key and value specified, // with or without attribute key and value specified,
// and returns a struct with a pointer to it // and returns a struct with a pointer to it
func (r Root) Find(args ...string) Root { func (r Root) Find(args ...string) Root {
defer catchPanic("Find()") temp, ok := findOnce(r.Pointer, args, false, false)
temp, ok := findOnce(r.Pointer, args, false)
if ok == false { if ok == false {
if debug { if debug {
panic("Element `" + args[0] + "` with attributes `" + strings.Join(args[1:], " ") + "` not found") panic("Element `" + args[0] + "` with attributes `" + strings.Join(args[1:], " ") + "` not found")
} }
return Root{nil, "", errors.New("Element `" + args[0] + "` with attributes `" + strings.Join(args[1:], " ") + "` not found")} return Root{Error: newError(ErrElementNotFound, fmt.Sprintf("element `%s` with attributes `%s` not found", args[0], strings.Join(args[1:], " ")))}
} }
return Root{temp, temp.Data, nil} return Root{Pointer: temp, NodeValue: temp.Data}
} }
// FindAll finds all occurrences of the given tag name, // FindAll finds all occurrences of the given tag name,
@ -117,17 +280,46 @@ func (r Root) Find(args ...string) Root {
// and returns an array of structs, each having // and returns an array of structs, each having
// the respective pointers // the respective pointers
func (r Root) FindAll(args ...string) []Root { func (r Root) FindAll(args ...string) []Root {
defer catchPanic("FindAll()") temp := findAllofem(r.Pointer, args, false)
temp := findAllofem(r.Pointer, args)
if len(temp) == 0 { if len(temp) == 0 {
if debug { if debug {
panic("Element `" + args[0] + "` with attributes `" + strings.Join(args[1:], " ") + "` not found") panic("Element `" + args[0] + "` with attributes `" + strings.Join(args[1:], " ") + "` not found")
} }
return []Root{} return []Root{}
} }
pointers := make([]Root, 0, 10) pointers := make([]Root, 0, len(temp))
for i := 0; i < len(temp); i++ { for i := 0; i < len(temp); i++ {
pointers = append(pointers, Root{temp[i], temp[i].Data, nil}) pointers = append(pointers, Root{Pointer: temp[i], NodeValue: temp[i].Data})
}
return pointers
}
// FindStrict finds the first occurrence of the given tag name
// only if all the values of the provided attribute are an exact match
func (r Root) FindStrict(args ...string) Root {
temp, ok := findOnce(r.Pointer, args, false, true)
if ok == false {
if debug {
panic("Element `" + args[0] + "` with attributes `" + strings.Join(args[1:], " ") + "` not found")
}
return Root{nil, "", newError(ErrElementNotFound, fmt.Sprintf("element `%s` with attributes `%s` not found", args[0], strings.Join(args[1:], " ")))}
}
return Root{Pointer: temp, NodeValue: temp.Data}
}
// FindAllStrict finds all occurrences of the given tag name
// only if all the values of the provided attribute are an exact match
func (r Root) FindAllStrict(args ...string) []Root {
temp := findAllofem(r.Pointer, args, true)
if len(temp) == 0 {
if debug {
panic("Element `" + args[0] + "` with attributes `" + strings.Join(args[1:], " ") + "` not found")
}
return []Root{}
}
pointers := make([]Root, 0, len(temp))
for i := 0; i < len(temp); i++ {
pointers = append(pointers, Root{Pointer: temp[i], NodeValue: temp[i].Data})
} }
return pointers return pointers
} }
@ -135,70 +327,77 @@ func (r Root) FindAll(args ...string) []Root {
// FindNextSibling finds the next sibling of the pointer in the DOM // FindNextSibling finds the next sibling of the pointer in the DOM
// returning a struct with a pointer to it // returning a struct with a pointer to it
func (r Root) FindNextSibling() Root { func (r Root) FindNextSibling() Root {
defer catchPanic("FindNextSibling()")
nextSibling := r.Pointer.NextSibling nextSibling := r.Pointer.NextSibling
if nextSibling == nil { if nextSibling == nil {
if debug { if debug {
panic("No next sibling found") panic("No next sibling found")
} }
return Root{nil, "", errors.New("No next sibling found")} return Root{Error: newError(ErrNoNextSibling, "no next sibling found")}
} }
return Root{nextSibling, nextSibling.Data, nil} return Root{Pointer: nextSibling, NodeValue: nextSibling.Data}
} }
// FindPrevSibling finds the previous sibling of the pointer in the DOM // FindPrevSibling finds the previous sibling of the pointer in the DOM
// returning a struct with a pointer to it // returning a struct with a pointer to it
func (r Root) FindPrevSibling() Root { func (r Root) FindPrevSibling() Root {
defer catchPanic("FindPrevSibling()")
prevSibling := r.Pointer.PrevSibling prevSibling := r.Pointer.PrevSibling
if prevSibling == nil { if prevSibling == nil {
if debug { if debug {
panic("No previous sibling found") panic("No previous sibling found")
} }
return Root{nil, "", errors.New("No previous sibling found")}
return Root{Error: newError(ErrNoPreviousSibling, "no previous sibling found")}
} }
return Root{prevSibling, prevSibling.Data, nil} return Root{Pointer: prevSibling, NodeValue: prevSibling.Data}
} }
// FindNextElementSibling finds the next element sibling of the pointer in the DOM // FindNextElementSibling finds the next element sibling of the pointer in the DOM
// returning a struct with a pointer to it // returning a struct with a pointer to it
func (r Root) FindNextElementSibling() Root { func (r Root) FindNextElementSibling() Root {
defer catchPanic("FindNextElementSibling()")
nextSibling := r.Pointer.NextSibling nextSibling := r.Pointer.NextSibling
if nextSibling == nil { if nextSibling == nil {
if debug { if debug {
panic("No next element sibling found") panic("No next element sibling found")
} }
return Root{nil, "", errors.New("No next element sibling found")} return Root{Error: newError(ErrNoNextElementSibling, "no next element sibling found")}
} }
if nextSibling.Type == html.ElementNode { if nextSibling.Type == html.ElementNode {
return Root{nextSibling, nextSibling.Data, nil} return Root{Pointer: nextSibling, NodeValue: nextSibling.Data}
} }
p := Root{nextSibling, nextSibling.Data, nil} p := Root{Pointer: nextSibling, NodeValue: nextSibling.Data}
return p.FindNextElementSibling() return p.FindNextElementSibling()
} }
// FindPrevElementSibling finds the previous element sibling of the pointer in the DOM // FindPrevElementSibling finds the previous element sibling of the pointer in the DOM
// returning a struct with a pointer to it // returning a struct with a pointer to it
func (r Root) FindPrevElementSibling() Root { func (r Root) FindPrevElementSibling() Root {
defer catchPanic("FindPrevElementSibling()")
prevSibling := r.Pointer.PrevSibling prevSibling := r.Pointer.PrevSibling
if prevSibling == nil { if prevSibling == nil {
if debug { if debug {
panic("No previous element sibling found") panic("No previous element sibling found")
} }
return Root{nil, "", errors.New("No previous element sibling found")} return Root{Error: newError(ErrNoPreviousElementSibling, "no previous element sibling found")}
} }
if prevSibling.Type == html.ElementNode { if prevSibling.Type == html.ElementNode {
return Root{prevSibling, prevSibling.Data, nil} return Root{Pointer: prevSibling, NodeValue: prevSibling.Data}
} }
p := Root{prevSibling, prevSibling.Data, nil} p := Root{Pointer: prevSibling, NodeValue: prevSibling.Data}
return p.FindPrevElementSibling() return p.FindPrevElementSibling()
} }
// Children retuns all direct children of this DOME element.
func (r Root) Children() []Root {
child := r.Pointer.FirstChild
var children []Root
for child != nil {
children = append(children, Root{Pointer: child, NodeValue: child.Data})
child = child.NextSibling
}
return children
}
// Attrs returns a map containing all attributes // Attrs returns a map containing all attributes
func (r Root) Attrs() map[string]string { func (r Root) Attrs() map[string]string {
defer catchPanic("Attrs()")
if r.Pointer.Type != html.ElementNode { if r.Pointer.Type != html.ElementNode {
if debug { if debug {
panic("Not an ElementNode") panic("Not an ElementNode")
@ -213,10 +412,9 @@ func (r Root) Attrs() map[string]string {
// Text returns the string inside a non-nested element // Text returns the string inside a non-nested element
func (r Root) Text() string { func (r Root) Text() string {
defer catchPanic("Text()")
k := r.Pointer.FirstChild k := r.Pointer.FirstChild
checkNode: checkNode:
if k.Type != html.TextNode { if k != nil && k.Type != html.TextNode {
k = k.NextSibling k = k.NextSibling
if k == nil { if k == nil {
if debug { if debug {
@ -243,13 +441,55 @@ checkNode:
return "" return ""
} }
// HTML returns the HTML code for the specific element
func (r Root) HTML() string {
var buf bytes.Buffer
if err := html.Render(&buf, r.Pointer); err != nil {
return ""
}
return buf.String()
}
// FullText returns the string inside even a nested element
func (r Root) FullText() string {
var buf bytes.Buffer
var f func(*html.Node)
f = func(n *html.Node) {
if n == nil {
return
}
if n.Type == html.TextNode {
buf.WriteString(n.Data)
}
if n.Type == html.ElementNode {
f(n.FirstChild)
}
if n.NextSibling != nil {
f(n.NextSibling)
}
}
f(r.Pointer.FirstChild)
return buf.String()
}
func matchElementName(n *html.Node, name string) bool {
return name == "" || name == n.Data
}
// Using depth first search to find the first occurrence and return // Using depth first search to find the first occurrence and return
func findOnce(n *html.Node, args []string, uni bool) (*html.Node, bool) { func findOnce(n *html.Node, args []string, uni bool, strict bool) (*html.Node, bool) {
if uni == true { if uni == true {
if n.Type == html.ElementNode && n.Data == args[0] { if n.Type == html.ElementNode && matchElementName(n, args[0]) {
if len(args) > 1 && len(args) < 4 { if len(args) > 1 && len(args) < 4 {
for i := 0; i < len(n.Attr); i++ { for i := 0; i < len(n.Attr); i++ {
if n.Attr[i].Key == args[1] && n.Attr[i].Val == args[2] { attr := n.Attr[i]
searchAttrName := args[1]
searchAttrVal := args[2]
if (strict && attributeAndValueEquals(attr, searchAttrName, searchAttrVal)) ||
(!strict && attributeContainsValue(attr, searchAttrName, searchAttrVal)) {
return n, true return n, true
} }
} }
@ -260,7 +500,7 @@ func findOnce(n *html.Node, args []string, uni bool) (*html.Node, bool) {
} }
uni = true uni = true
for c := n.FirstChild; c != nil; c = c.NextSibling { for c := n.FirstChild; c != nil; c = c.NextSibling {
p, q := findOnce(c, args, true) p, q := findOnce(c, args, true, strict)
if q != false { if q != false {
return p, q return p, q
} }
@ -269,15 +509,19 @@ func findOnce(n *html.Node, args []string, uni bool) (*html.Node, bool) {
} }
// Using depth first search to find all occurrences and return // Using depth first search to find all occurrences and return
func findAllofem(n *html.Node, args []string) []*html.Node { func findAllofem(n *html.Node, args []string, strict bool) []*html.Node {
var nodeLinks = make([]*html.Node, 0, 10) var nodeLinks = make([]*html.Node, 0, 10)
var f func(*html.Node, []string, bool) var f func(*html.Node, []string, bool)
f = func(n *html.Node, args []string, uni bool) { f = func(n *html.Node, args []string, uni bool) {
if uni == true { if uni == true {
if n.Data == args[0] { if n.Type == html.ElementNode && matchElementName(n, args[0]) {
if len(args) > 1 && len(args) < 4 { if len(args) > 1 && len(args) < 4 {
for i := 0; i < len(n.Attr); i++ { for i := 0; i < len(n.Attr); i++ {
if n.Attr[i].Key == args[1] && n.Attr[i].Val == args[2] { attr := n.Attr[i]
searchAttrName := args[1]
searchAttrVal := args[2]
if (strict && attributeAndValueEquals(attr, searchAttrName, searchAttrVal)) ||
(!strict && attributeContainsValue(attr, searchAttrName, searchAttrVal)) {
nodeLinks = append(nodeLinks, n) nodeLinks = append(nodeLinks, n)
} }
} }
@ -295,6 +539,25 @@ func findAllofem(n *html.Node, args []string) []*html.Node {
return nodeLinks return nodeLinks
} }
// attributeAndValueEquals reports when the html.Attribute attr has the same attribute name and value as from
// provided arguments
func attributeAndValueEquals(attr html.Attribute, attribute, value string) bool {
return attr.Key == attribute && attr.Val == value
}
// attributeContainsValue reports when the html.Attribute attr has the same attribute name as from provided
// attribute argument and compares if it has the same value in its values parameter
func attributeContainsValue(attr html.Attribute, attribute, value string) bool {
if attr.Key == attribute {
for _, attrVal := range strings.Fields(attr.Val) {
if attrVal == value {
return true
}
}
}
return false
}
// Returns a key pair value (like a dictionary) for each attribute // Returns a key pair value (like a dictionary) for each attribute
func getKeyValue(attributes []html.Attribute) map[string]string { func getKeyValue(attributes []html.Attribute) map[string]string {
var keyvalues = make(map[string]string) var keyvalues = make(map[string]string)
@ -306,10 +569,3 @@ func getKeyValue(attributes []html.Attribute) map[string]string {
} }
return keyvalues return keyvalues
} }
// Catch panics when they occur
func catchPanic(fnName string) {
if r := recover(); r != nil {
log.Println("Error occurred in", fnName, ":", r)
}
}

@ -1,6 +1,5 @@
//go:build (loongarch32 || loongarch64) && linux //go:build loong64
//+build linux // +build loong64
//+build loongarch32 loongarch64
// Created by cgo -godefs - DO NOT EDIT // Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types.go // cgo -godefs types.go

@ -14,14 +14,12 @@ D-Bus message bus system.
### Installation ### Installation
This packages requires Go 1.7. If you installed it and set up your GOPATH, just run: This packages requires Go 1.12 or later. It can be installed by running the command below:
``` ```
go get github.com/godbus/dbus go get github.com/godbus/dbus/v5
``` ```
If you want to use the subpackages, you can install them the same way.
### Usage ### Usage
The complete package documentation and some simple examples are available at The complete package documentation and some simple examples are available at
@ -30,10 +28,12 @@ The complete package documentation and some simple examples are available at
gives a short overview over the basic usage. gives a short overview over the basic usage.
#### Projects using godbus #### Projects using godbus
- [notify](https://github.com/esiqveland/notify) provides desktop notifications over dbus into a library. - [fyne](https://github.com/fyne-io/fyne) a cross platform GUI in Go inspired by Material Design.
- [fynedesk](https://github.com/fyne-io/fynedesk) a full desktop environment for Linux/Unix using Fyne.
- [go-bluetooth](https://github.com/muka/go-bluetooth) provides a bluetooth client over bluez dbus API. - [go-bluetooth](https://github.com/muka/go-bluetooth) provides a bluetooth client over bluez dbus API.
- [playerbm](https://github.com/altdesktop/playerbm) a bookmark utility for media players.
- [iwd](https://github.com/shibumi/iwd) go bindings for the internet wireless daemon "iwd". - [iwd](https://github.com/shibumi/iwd) go bindings for the internet wireless daemon "iwd".
- [notify](https://github.com/esiqveland/notify) provides desktop notifications over dbus into a library.
- [playerbm](https://github.com/altdesktop/playerbm) a bookmark utility for media players.
Please note that the API is considered unstable for now and may change without Please note that the API is considered unstable for now and may change without
further notice. further notice.

@ -53,7 +53,7 @@ type Auth interface {
// bus. Auth must not be called on shared connections. // bus. Auth must not be called on shared connections.
func (conn *Conn) Auth(methods []Auth) error { func (conn *Conn) Auth(methods []Auth) error {
if methods == nil { if methods == nil {
uid := strconv.Itoa(os.Getuid()) uid := strconv.Itoa(os.Geteuid())
methods = []Auth{AuthExternal(uid), AuthCookieSha1(uid, getHomeDir())} methods = []Auth{AuthExternal(uid), AuthCookieSha1(uid, getHomeDir())}
} }
in := bufio.NewReader(conn.transport) in := bufio.NewReader(conn.transport)
@ -75,9 +75,9 @@ func (conn *Conn) Auth(methods []Auth) error {
s = s[1:] s = s[1:]
for _, v := range s { for _, v := range s {
for _, m := range methods { for _, m := range methods {
if name, data, status := m.FirstData(); bytes.Equal(v, name) { if name, _, status := m.FirstData(); bytes.Equal(v, name) {
var ok bool var ok bool
err = authWriteLine(conn.transport, []byte("AUTH"), v, data) err = authWriteLine(conn.transport, []byte("AUTH"), v)
if err != nil { if err != nil {
return err return err
} }
@ -194,11 +194,14 @@ func (conn *Conn) tryAuth(m Auth, state authState, in *bufio.Reader) (error, boo
} }
conn.uuid = string(s[1]) conn.uuid = string(s[1])
return nil, true return nil, true
case state == waitingForOk && string(s[0]) == "DATA":
err = authWriteLine(conn.transport, []byte("DATA"))
if err != nil {
return err, false
}
case state == waitingForOk && string(s[0]) == "REJECTED": case state == waitingForOk && string(s[0]) == "REJECTED":
return nil, false return nil, false
case state == waitingForOk && (string(s[0]) == "DATA" || case state == waitingForOk && string(s[0]) == "ERROR":
string(s[0]) == "ERROR"):
err = authWriteLine(conn.transport, []byte("CANCEL")) err = authWriteLine(conn.transport, []byte("CANCEL"))
if err != nil { if err != nil {
return err, false return err, false

@ -73,7 +73,7 @@ func SessionBus() (conn *Conn, err error) {
return return
} }
func getSessionBusAddress() (string, error) { func getSessionBusAddress(autolaunch bool) (string, error) {
if address := os.Getenv("DBUS_SESSION_BUS_ADDRESS"); address != "" && address != "autolaunch:" { if address := os.Getenv("DBUS_SESSION_BUS_ADDRESS"); address != "" && address != "autolaunch:" {
return address, nil return address, nil
@ -81,12 +81,26 @@ func getSessionBusAddress() (string, error) {
os.Setenv("DBUS_SESSION_BUS_ADDRESS", address) os.Setenv("DBUS_SESSION_BUS_ADDRESS", address)
return address, nil return address, nil
} }
if !autolaunch {
return "", errors.New("dbus: couldn't determine address of session bus")
}
return getSessionBusPlatformAddress() return getSessionBusPlatformAddress()
} }
// SessionBusPrivate returns a new private connection to the session bus. // SessionBusPrivate returns a new private connection to the session bus.
func SessionBusPrivate(opts ...ConnOption) (*Conn, error) { func SessionBusPrivate(opts ...ConnOption) (*Conn, error) {
address, err := getSessionBusAddress() address, err := getSessionBusAddress(true)
if err != nil {
return nil, err
}
return Dial(address, opts...)
}
// SessionBusPrivate returns a new private connection to the session bus. If
// the session bus is not already open, do not attempt to launch it.
func SessionBusPrivateNoAutoStartup(opts ...ConnOption) (*Conn, error) {
address, err := getSessionBusAddress(false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -121,7 +135,7 @@ func SystemBus() (conn *Conn, err error) {
// ConnectSessionBus connects to the session bus. // ConnectSessionBus connects to the session bus.
func ConnectSessionBus(opts ...ConnOption) (*Conn, error) { func ConnectSessionBus(opts ...ConnOption) (*Conn, error) {
address, err := getSessionBusAddress() address, err := getSessionBusAddress(true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -180,7 +194,7 @@ func Dial(address string, opts ...ConnOption) (*Conn, error) {
// //
// Deprecated: use Dial with options instead. // Deprecated: use Dial with options instead.
func DialHandler(address string, handler Handler, signalHandler SignalHandler) (*Conn, error) { func DialHandler(address string, handler Handler, signalHandler SignalHandler) (*Conn, error) {
return Dial(address, WithSignalHandler(signalHandler)) return Dial(address, WithHandler(handler), WithSignalHandler(signalHandler))
} }
// ConnOption is a connection option. // ConnOption is a connection option.
@ -478,14 +492,24 @@ func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) {
conn.outInt(msg) conn.outInt(msg)
} }
err := conn.outHandler.sendAndIfClosed(msg, ifClosed) err := conn.outHandler.sendAndIfClosed(msg, ifClosed)
conn.calls.handleSendError(msg, err)
if err != nil { if err != nil {
conn.serialGen.RetireSerial(msg.serial) conn.handleSendError(msg, err)
} else if msg.Type != TypeMethodCall { } else if msg.Type != TypeMethodCall {
conn.serialGen.RetireSerial(msg.serial) conn.serialGen.RetireSerial(msg.serial)
} }
} }
func (conn *Conn) handleSendError(msg *Message, err error) {
if msg.Type == TypeMethodCall {
conn.calls.handleSendError(msg, err)
} else if msg.Type == TypeMethodReply {
if _, ok := err.(FormatError); ok {
conn.sendError(err, msg.Headers[FieldDestination].value.(string), msg.Headers[FieldReplySerial].value.(uint32))
}
}
conn.serialGen.RetireSerial(msg.serial)
}
// Send sends the given message to the message bus. You usually don't need to // Send sends the given message to the message bus. You usually don't need to
// use this; use the higher-level equivalents (Call / Go, Emit and Export) // use this; use the higher-level equivalents (Call / Go, Emit and Export)
// instead. If msg is a method call and NoReplyExpected is not set, a non-nil // instead. If msg is a method call and NoReplyExpected is not set, a non-nil

@ -10,14 +10,16 @@ type decoder struct {
in io.Reader in io.Reader
order binary.ByteOrder order binary.ByteOrder
pos int pos int
fds []int
} }
// newDecoder returns a new decoder that reads values from in. The input is // newDecoder returns a new decoder that reads values from in. The input is
// expected to be in the given byte order. // expected to be in the given byte order.
func newDecoder(in io.Reader, order binary.ByteOrder) *decoder { func newDecoder(in io.Reader, order binary.ByteOrder, fds []int) *decoder {
dec := new(decoder) dec := new(decoder)
dec.in = in dec.in = in
dec.order = order dec.order = order
dec.fds = fds
return dec return dec
} }
@ -53,7 +55,7 @@ func (dec *decoder) Decode(sig Signature) (vs []interface{}, err error) {
vs = make([]interface{}, 0) vs = make([]interface{}, 0)
s := sig.str s := sig.str
for s != "" { for s != "" {
err, rem := validSingle(s, 0) err, rem := validSingle(s, &depthCounter{})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -150,7 +152,7 @@ func (dec *decoder) decode(s string, depth int) interface{} {
if len(sig.str) == 0 { if len(sig.str) == 0 {
panic(FormatError("variant signature is empty")) panic(FormatError("variant signature is empty"))
} }
err, rem := validSingle(sig.str, 0) err, rem := validSingle(sig.str, &depthCounter{})
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -161,7 +163,11 @@ func (dec *decoder) decode(s string, depth int) interface{} {
variant.value = dec.decode(sig.str, depth+1) variant.value = dec.decode(sig.str, depth+1)
return variant return variant
case 'h': case 'h':
return UnixFDIndex(dec.decode("u", depth).(uint32)) idx := dec.decode("u", depth).(uint32)
if int(idx) < len(dec.fds) {
return UnixFD(dec.fds[idx])
}
return UnixFDIndex(idx)
case 'a': case 'a':
if len(s) > 1 && s[1] == '{' { if len(s) > 1 && s[1] == '{' {
ksig := s[2:3] ksig := s[2:3]
@ -219,7 +225,7 @@ func (dec *decoder) decode(s string, depth int) interface{} {
v := make([]interface{}, 0) v := make([]interface{}, 0)
s = s[1 : len(s)-1] s = s[1 : len(s)-1]
for s != "" { for s != "" {
err, rem := validSingle(s, 0) err, rem := validSingle(s, &depthCounter{})
if err != nil { if err != nil {
panic(err) panic(err)
} }

@ -5,28 +5,33 @@ import (
"encoding/binary" "encoding/binary"
"io" "io"
"reflect" "reflect"
"strings"
"unicode/utf8"
) )
// An encoder encodes values to the D-Bus wire format. // An encoder encodes values to the D-Bus wire format.
type encoder struct { type encoder struct {
out io.Writer out io.Writer
fds []int
order binary.ByteOrder order binary.ByteOrder
pos int pos int
} }
// NewEncoder returns a new encoder that writes to out in the given byte order. // NewEncoder returns a new encoder that writes to out in the given byte order.
func newEncoder(out io.Writer, order binary.ByteOrder) *encoder { func newEncoder(out io.Writer, order binary.ByteOrder, fds []int) *encoder {
return newEncoderAtOffset(out, 0, order) enc := newEncoderAtOffset(out, 0, order, fds)
return enc
} }
// newEncoderAtOffset returns a new encoder that writes to out in the given // newEncoderAtOffset returns a new encoder that writes to out in the given
// byte order. Specify the offset to initialize pos for proper alignment // byte order. Specify the offset to initialize pos for proper alignment
// computation. // computation.
func newEncoderAtOffset(out io.Writer, offset int, order binary.ByteOrder) *encoder { func newEncoderAtOffset(out io.Writer, offset int, order binary.ByteOrder, fds []int) *encoder {
enc := new(encoder) enc := new(encoder)
enc.out = out enc.out = out
enc.order = order enc.order = order
enc.pos = offset enc.pos = offset
enc.fds = fds
return enc return enc
} }
@ -75,6 +80,9 @@ func (enc *encoder) Encode(vs ...interface{}) (err error) {
// encode encodes the given value to the writer and panics on error. depth holds // encode encodes the given value to the writer and panics on error. depth holds
// the depth of the container nesting. // the depth of the container nesting.
func (enc *encoder) encode(v reflect.Value, depth int) { func (enc *encoder) encode(v reflect.Value, depth int) {
if depth > 64 {
panic(FormatError("input exceeds depth limitation"))
}
enc.align(alignment(v.Type())) enc.align(alignment(v.Type()))
switch v.Kind() { switch v.Kind() {
case reflect.Uint8: case reflect.Uint8:
@ -97,7 +105,14 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
enc.binwrite(uint16(v.Uint())) enc.binwrite(uint16(v.Uint()))
enc.pos += 2 enc.pos += 2
case reflect.Int, reflect.Int32: case reflect.Int, reflect.Int32:
enc.binwrite(int32(v.Int())) if v.Type() == unixFDType {
fd := v.Int()
idx := len(enc.fds)
enc.fds = append(enc.fds, int(fd))
enc.binwrite(uint32(idx))
} else {
enc.binwrite(int32(v.Int()))
}
enc.pos += 4 enc.pos += 4
case reflect.Uint, reflect.Uint32: case reflect.Uint, reflect.Uint32:
enc.binwrite(uint32(v.Uint())) enc.binwrite(uint32(v.Uint()))
@ -112,9 +127,21 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
enc.binwrite(v.Float()) enc.binwrite(v.Float())
enc.pos += 8 enc.pos += 8
case reflect.String: case reflect.String:
enc.encode(reflect.ValueOf(uint32(len(v.String()))), depth) str := v.String()
if !utf8.ValidString(str) {
panic(FormatError("input has a not-utf8 char in string"))
}
if strings.IndexByte(str, byte(0)) != -1 {
panic(FormatError("input has a null char('\\000') in string"))
}
if v.Type() == objectPathType {
if !ObjectPath(str).IsValid() {
panic(FormatError("invalid object path"))
}
}
enc.encode(reflect.ValueOf(uint32(len(str))), depth)
b := make([]byte, v.Len()+1) b := make([]byte, v.Len()+1)
copy(b, v.String()) copy(b, str)
b[len(b)-1] = 0 b[len(b)-1] = 0
n, err := enc.out.Write(b) n, err := enc.out.Write(b)
if err != nil { if err != nil {
@ -124,20 +151,23 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
case reflect.Ptr: case reflect.Ptr:
enc.encode(v.Elem(), depth) enc.encode(v.Elem(), depth)
case reflect.Slice, reflect.Array: case reflect.Slice, reflect.Array:
if depth >= 64 {
panic(FormatError("input exceeds container depth limit"))
}
// Lookahead offset: 4 bytes for uint32 length (with alignment), // Lookahead offset: 4 bytes for uint32 length (with alignment),
// plus alignment for elements. // plus alignment for elements.
n := enc.padding(0, 4) + 4 n := enc.padding(0, 4) + 4
offset := enc.pos + n + enc.padding(n, alignment(v.Type().Elem())) offset := enc.pos + n + enc.padding(n, alignment(v.Type().Elem()))
var buf bytes.Buffer var buf bytes.Buffer
bufenc := newEncoderAtOffset(&buf, offset, enc.order) bufenc := newEncoderAtOffset(&buf, offset, enc.order, enc.fds)
for i := 0; i < v.Len(); i++ { for i := 0; i < v.Len(); i++ {
bufenc.encode(v.Index(i), depth+1) bufenc.encode(v.Index(i), depth+1)
} }
if buf.Len() > 1<<26 {
panic(FormatError("input exceeds array size limitation"))
}
enc.fds = bufenc.fds
enc.encode(reflect.ValueOf(uint32(buf.Len())), depth) enc.encode(reflect.ValueOf(uint32(buf.Len())), depth)
length := buf.Len() length := buf.Len()
enc.align(alignment(v.Type().Elem())) enc.align(alignment(v.Type().Elem()))
@ -146,13 +176,10 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
} }
enc.pos += length enc.pos += length
case reflect.Struct: case reflect.Struct:
if depth >= 64 && v.Type() != signatureType {
panic(FormatError("input exceeds container depth limit"))
}
switch t := v.Type(); t { switch t := v.Type(); t {
case signatureType: case signatureType:
str := v.Field(0) str := v.Field(0)
enc.encode(reflect.ValueOf(byte(str.Len())), depth+1) enc.encode(reflect.ValueOf(byte(str.Len())), depth)
b := make([]byte, str.Len()+1) b := make([]byte, str.Len()+1)
copy(b, str.String()) copy(b, str.String())
b[len(b)-1] = 0 b[len(b)-1] = 0
@ -176,9 +203,6 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
case reflect.Map: case reflect.Map:
// Maps are arrays of structures, so they actually increase the depth by // Maps are arrays of structures, so they actually increase the depth by
// 2. // 2.
if depth >= 63 {
panic(FormatError("input exceeds container depth limit"))
}
if !isKeyType(v.Type().Key()) { if !isKeyType(v.Type().Key()) {
panic(InvalidTypeError{v.Type()}) panic(InvalidTypeError{v.Type()})
} }
@ -189,12 +213,13 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
offset := enc.pos + n + enc.padding(n, 8) offset := enc.pos + n + enc.padding(n, 8)
var buf bytes.Buffer var buf bytes.Buffer
bufenc := newEncoderAtOffset(&buf, offset, enc.order) bufenc := newEncoderAtOffset(&buf, offset, enc.order, enc.fds)
for _, k := range keys { for _, k := range keys {
bufenc.align(8) bufenc.align(8)
bufenc.encode(k, depth+2) bufenc.encode(k, depth+2)
bufenc.encode(v.MapIndex(k), depth+2) bufenc.encode(v.MapIndex(k), depth+2)
} }
enc.fds = bufenc.fds
enc.encode(reflect.ValueOf(uint32(buf.Len())), depth) enc.encode(reflect.ValueOf(uint32(buf.Len())), depth)
length := buf.Len() length := buf.Len()
enc.align(8) enc.align(8)

@ -26,6 +26,27 @@ var (
} }
) )
func MakeNoObjectError(path ObjectPath) Error {
return Error{
"org.freedesktop.DBus.Error.NoSuchObject",
[]interface{}{fmt.Sprintf("No such object '%s'", string(path))},
}
}
func MakeUnknownMethodError(methodName string) Error {
return Error{
"org.freedesktop.DBus.Error.UnknownMethod",
[]interface{}{fmt.Sprintf("Unknown / invalid method '%s'", methodName)},
}
}
func MakeUnknownInterfaceError(ifaceName string) Error {
return Error{
"org.freedesktop.DBus.Error.UnknownInterface",
[]interface{}{fmt.Sprintf("Object does not implement the interface '%s'", ifaceName)},
}
}
func MakeFailedError(err error) *Error { func MakeFailedError(err error) *Error {
return &Error{ return &Error{
"org.freedesktop.DBus.Error.Failed", "org.freedesktop.DBus.Error.Failed",
@ -128,6 +149,11 @@ func (conn *Conn) handleCall(msg *Message) {
ifaceName, _ := msg.Headers[FieldInterface].value.(string) ifaceName, _ := msg.Headers[FieldInterface].value.(string)
sender, hasSender := msg.Headers[FieldSender].value.(string) sender, hasSender := msg.Headers[FieldSender].value.(string)
serial := msg.serial serial := msg.serial
if len(name) == 0 {
conn.sendError(ErrMsgUnknownMethod, sender, serial)
}
if ifaceName == "org.freedesktop.DBus.Peer" { if ifaceName == "org.freedesktop.DBus.Peer" {
switch name { switch name {
case "Ping": case "Ping":
@ -135,29 +161,26 @@ func (conn *Conn) handleCall(msg *Message) {
case "GetMachineId": case "GetMachineId":
conn.sendReply(sender, serial, conn.uuid) conn.sendReply(sender, serial, conn.uuid)
default: default:
conn.sendError(ErrMsgUnknownMethod, sender, serial) conn.sendError(MakeUnknownMethodError(name), sender, serial)
} }
return return
} }
if len(name) == 0 {
conn.sendError(ErrMsgUnknownMethod, sender, serial)
}
object, ok := conn.handler.LookupObject(path) object, ok := conn.handler.LookupObject(path)
if !ok { if !ok {
conn.sendError(ErrMsgNoObject, sender, serial) conn.sendError(MakeNoObjectError(path), sender, serial)
return return
} }
iface, exists := object.LookupInterface(ifaceName) iface, exists := object.LookupInterface(ifaceName)
if !exists { if !exists {
conn.sendError(ErrMsgUnknownInterface, sender, serial) conn.sendError(MakeUnknownInterfaceError(ifaceName), sender, serial)
return return
} }
m, exists := iface.LookupMethod(name) m, exists := iface.LookupMethod(name)
if !exists { if !exists {
conn.sendError(ErrMsgUnknownMethod, sender, serial) conn.sendError(MakeUnknownMethodError(name), sender, serial)
return return
} }
args, err := conn.decodeArguments(m, sender, msg) args, err := conn.decodeArguments(m, sender, msg)

@ -118,11 +118,7 @@ type header struct {
Variant Variant
} }
// DecodeMessage tries to decode a single message in the D-Bus wire format func DecodeMessageWithFDs(rd io.Reader, fds []int) (msg *Message, err error) {
// from the given reader. The byte order is figured out from the first byte.
// The possibly returned error can be an error of the underlying reader, an
// InvalidMessageError or a FormatError.
func DecodeMessage(rd io.Reader) (msg *Message, err error) {
var order binary.ByteOrder var order binary.ByteOrder
var hlength, length uint32 var hlength, length uint32
var typ, flags, proto byte var typ, flags, proto byte
@ -142,7 +138,7 @@ func DecodeMessage(rd io.Reader) (msg *Message, err error) {
return nil, InvalidMessageError("invalid byte order") return nil, InvalidMessageError("invalid byte order")
} }
dec := newDecoder(rd, order) dec := newDecoder(rd, order, fds)
dec.pos = 1 dec.pos = 1
msg = new(Message) msg = new(Message)
@ -166,7 +162,7 @@ func DecodeMessage(rd io.Reader) (msg *Message, err error) {
if hlength+length+16 > 1<<27 { if hlength+length+16 > 1<<27 {
return nil, InvalidMessageError("message is too long") return nil, InvalidMessageError("message is too long")
} }
dec = newDecoder(io.MultiReader(bytes.NewBuffer(b), rd), order) dec = newDecoder(io.MultiReader(bytes.NewBuffer(b), rd), order, fds)
dec.pos = 12 dec.pos = 12
vs, err = dec.Decode(Signature{"a(yv)"}) vs, err = dec.Decode(Signature{"a(yv)"})
if err != nil { if err != nil {
@ -196,7 +192,7 @@ func DecodeMessage(rd io.Reader) (msg *Message, err error) {
sig, _ := msg.Headers[FieldSignature].value.(Signature) sig, _ := msg.Headers[FieldSignature].value.(Signature)
if sig.str != "" { if sig.str != "" {
buf := bytes.NewBuffer(body) buf := bytes.NewBuffer(body)
dec = newDecoder(buf, order) dec = newDecoder(buf, order, fds)
vs, err := dec.Decode(sig) vs, err := dec.Decode(sig)
if err != nil { if err != nil {
return nil, err return nil, err
@ -207,12 +203,32 @@ func DecodeMessage(rd io.Reader) (msg *Message, err error) {
return return
} }
// EncodeTo encodes and sends a message to the given writer. The byte order must // DecodeMessage tries to decode a single message in the D-Bus wire format
// be either binary.LittleEndian or binary.BigEndian. If the message is not // from the given reader. The byte order is figured out from the first byte.
// valid or an error occurs when writing, an error is returned. // The possibly returned error can be an error of the underlying reader, an
func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) error { // InvalidMessageError or a FormatError.
func DecodeMessage(rd io.Reader) (msg *Message, err error) {
return DecodeMessageWithFDs(rd, make([]int, 0));
}
type nullwriter struct{}
func (nullwriter) Write(p []byte) (cnt int, err error) {
return len(p), nil
}
func (msg *Message) CountFds() (int, error) {
if len(msg.Body) == 0 {
return 0, nil
}
enc := newEncoder(nullwriter{}, nativeEndian, make([]int, 0))
err := enc.Encode(msg.Body...)
return len(enc.fds), err
}
func (msg *Message) EncodeToWithFDs(out io.Writer, order binary.ByteOrder) (fds []int, err error) {
if err := msg.IsValid(); err != nil { if err := msg.IsValid(); err != nil {
return err return make([]int, 0), err
} }
var vs [7]interface{} var vs [7]interface{}
switch order { switch order {
@ -221,12 +237,16 @@ func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) error {
case binary.BigEndian: case binary.BigEndian:
vs[0] = byte('B') vs[0] = byte('B')
default: default:
return errors.New("dbus: invalid byte order") return make([]int, 0), errors.New("dbus: invalid byte order")
} }
body := new(bytes.Buffer) body := new(bytes.Buffer)
enc := newEncoder(body, order) fds = make([]int, 0)
enc := newEncoder(body, order, fds)
if len(msg.Body) != 0 { if len(msg.Body) != 0 {
enc.Encode(msg.Body...) err = enc.Encode(msg.Body...)
if err != nil {
return
}
} }
vs[1] = msg.Type vs[1] = msg.Type
vs[2] = msg.Flags vs[2] = msg.Flags
@ -239,17 +259,28 @@ func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) error {
} }
vs[6] = headers vs[6] = headers
var buf bytes.Buffer var buf bytes.Buffer
enc = newEncoder(&buf, order) enc = newEncoder(&buf, order, enc.fds)
enc.Encode(vs[:]...) err = enc.Encode(vs[:]...)
if err != nil {
return
}
enc.align(8) enc.align(8)
body.WriteTo(&buf) body.WriteTo(&buf)
if buf.Len() > 1<<27 { if buf.Len() > 1<<27 {
return InvalidMessageError("message is too long") return make([]int, 0), InvalidMessageError("message is too long")
} }
if _, err := buf.WriteTo(out); err != nil { if _, err := buf.WriteTo(out); err != nil {
return err return make([]int, 0), err
} }
return nil return enc.fds, nil
}
// EncodeTo encodes and sends a message to the given writer. The byte order must
// be either binary.LittleEndian or binary.BigEndian. If the message is not
// valid or an error occurs when writing, an error is returned.
func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) (err error) {
_, err = msg.EncodeToWithFDs(out, order)
return err
} }
// IsValid checks whether msg is a valid message and returns an // IsValid checks whether msg is a valid message and returns an

@ -34,7 +34,7 @@ type Signature struct {
func SignatureOf(vs ...interface{}) Signature { func SignatureOf(vs ...interface{}) Signature {
var s string var s string
for _, v := range vs { for _, v := range vs {
s += getSignature(reflect.TypeOf(v)) s += getSignature(reflect.TypeOf(v), &depthCounter{})
} }
return Signature{s} return Signature{s}
} }
@ -42,11 +42,19 @@ func SignatureOf(vs ...interface{}) Signature {
// SignatureOfType returns the signature of the given type. It panics if the // SignatureOfType returns the signature of the given type. It panics if the
// type is not representable in D-Bus. // type is not representable in D-Bus.
func SignatureOfType(t reflect.Type) Signature { func SignatureOfType(t reflect.Type) Signature {
return Signature{getSignature(t)} return Signature{getSignature(t, &depthCounter{})}
} }
// getSignature returns the signature of the given type and panics on unknown types. // getSignature returns the signature of the given type and panics on unknown types.
func getSignature(t reflect.Type) string { func getSignature(t reflect.Type, depth *depthCounter) (sig string) {
if !depth.Valid() {
panic("container nesting too deep")
}
defer func() {
if len(sig) > 255 {
panic("signature exceeds the length limitation")
}
}()
// handle simple types first // handle simple types first
switch t.Kind() { switch t.Kind() {
case reflect.Uint8: case reflect.Uint8:
@ -74,7 +82,7 @@ func getSignature(t reflect.Type) string {
case reflect.Float64: case reflect.Float64:
return "d" return "d"
case reflect.Ptr: case reflect.Ptr:
return getSignature(t.Elem()) return getSignature(t.Elem(), depth)
case reflect.String: case reflect.String:
if t == objectPathType { if t == objectPathType {
return "o" return "o"
@ -90,17 +98,20 @@ func getSignature(t reflect.Type) string {
for i := 0; i < t.NumField(); i++ { for i := 0; i < t.NumField(); i++ {
field := t.Field(i) field := t.Field(i)
if field.PkgPath == "" && field.Tag.Get("dbus") != "-" { if field.PkgPath == "" && field.Tag.Get("dbus") != "-" {
s += getSignature(t.Field(i).Type) s += getSignature(t.Field(i).Type, depth.EnterStruct())
} }
} }
if len(s) == 0 {
panic("empty struct")
}
return "(" + s + ")" return "(" + s + ")"
case reflect.Array, reflect.Slice: case reflect.Array, reflect.Slice:
return "a" + getSignature(t.Elem()) return "a" + getSignature(t.Elem(), depth.EnterArray())
case reflect.Map: case reflect.Map:
if !isKeyType(t.Key()) { if !isKeyType(t.Key()) {
panic(InvalidTypeError{t}) panic(InvalidTypeError{t})
} }
return "a{" + getSignature(t.Key()) + getSignature(t.Elem()) + "}" return "a{" + getSignature(t.Key(), depth.EnterArray().EnterDictEntry()) + getSignature(t.Elem(), depth.EnterArray().EnterDictEntry()) + "}"
case reflect.Interface: case reflect.Interface:
return "v" return "v"
} }
@ -118,7 +129,7 @@ func ParseSignature(s string) (sig Signature, err error) {
} }
sig.str = s sig.str = s
for err == nil && len(s) != 0 { for err == nil && len(s) != 0 {
err, s = validSingle(s, 0) err, s = validSingle(s, &depthCounter{})
} }
if err != nil { if err != nil {
sig = Signature{""} sig = Signature{""}
@ -144,7 +155,7 @@ func (s Signature) Empty() bool {
// Single returns whether the signature represents a single, complete type. // Single returns whether the signature represents a single, complete type.
func (s Signature) Single() bool { func (s Signature) Single() bool {
err, r := validSingle(s.str, 0) err, r := validSingle(s.str, &depthCounter{})
return err != nil && r == "" return err != nil && r == ""
} }
@ -164,15 +175,38 @@ func (e SignatureError) Error() string {
return fmt.Sprintf("dbus: invalid signature: %q (%s)", e.Sig, e.Reason) return fmt.Sprintf("dbus: invalid signature: %q (%s)", e.Sig, e.Reason)
} }
type depthCounter struct {
arrayDepth, structDepth, dictEntryDepth int
}
func (cnt *depthCounter) Valid() bool {
return cnt.arrayDepth <= 32 && cnt.structDepth <= 32 && cnt.dictEntryDepth <= 32
}
func (cnt depthCounter) EnterArray() *depthCounter {
cnt.arrayDepth++
return &cnt
}
func (cnt depthCounter) EnterStruct() *depthCounter {
cnt.structDepth++
return &cnt
}
func (cnt depthCounter) EnterDictEntry() *depthCounter {
cnt.dictEntryDepth++
return &cnt
}
// Try to read a single type from this string. If it was successful, err is nil // Try to read a single type from this string. If it was successful, err is nil
// and rem is the remaining unparsed part. Otherwise, err is a non-nil // and rem is the remaining unparsed part. Otherwise, err is a non-nil
// SignatureError and rem is "". depth is the current recursion depth which may // SignatureError and rem is "". depth is the current recursion depth which may
// not be greater than 64 and should be given as 0 on the first call. // not be greater than 64 and should be given as 0 on the first call.
func validSingle(s string, depth int) (err error, rem string) { func validSingle(s string, depth *depthCounter) (err error, rem string) {
if s == "" { if s == "" {
return SignatureError{Sig: s, Reason: "empty signature"}, "" return SignatureError{Sig: s, Reason: "empty signature"}, ""
} }
if depth > 64 { if !depth.Valid() {
return SignatureError{Sig: s, Reason: "container nesting too deep"}, "" return SignatureError{Sig: s, Reason: "container nesting too deep"}, ""
} }
switch s[0] { switch s[0] {
@ -187,10 +221,10 @@ func validSingle(s string, depth int) (err error, rem string) {
i++ i++
rem = s[i+1:] rem = s[i+1:]
s = s[2:i] s = s[2:i]
if err, _ = validSingle(s[:1], depth+1); err != nil { if err, _ = validSingle(s[:1], depth.EnterArray().EnterDictEntry()); err != nil {
return err, "" return err, ""
} }
err, nr := validSingle(s[1:], depth+1) err, nr := validSingle(s[1:], depth.EnterArray().EnterDictEntry())
if err != nil { if err != nil {
return err, "" return err, ""
} }
@ -199,7 +233,7 @@ func validSingle(s string, depth int) (err error, rem string) {
} }
return nil, rem return nil, rem
} }
return validSingle(s[1:], depth+1) return validSingle(s[1:], depth.EnterArray())
case '(': case '(':
i := findMatching(s, '(', ')') i := findMatching(s, '(', ')')
if i == -1 { if i == -1 {
@ -208,7 +242,7 @@ func validSingle(s string, depth int) (err error, rem string) {
rem = s[i+1:] rem = s[i+1:]
s = s[1:i] s = s[1:i]
for err == nil && s != "" { for err == nil && s != "" {
err, s = validSingle(s, depth+1) err, s = validSingle(s, depth.EnterStruct())
} }
if err != nil { if err != nil {
rem = "" rem = ""
@ -236,7 +270,7 @@ func findMatching(s string, left, right rune) int {
// typeFor returns the type of the given signature. It ignores any left over // typeFor returns the type of the given signature. It ignores any left over
// characters and panics if s doesn't start with a valid type signature. // characters and panics if s doesn't start with a valid type signature.
func typeFor(s string) (t reflect.Type) { func typeFor(s string) (t reflect.Type) {
err, _ := validSingle(s, 0) err, _ := validSingle(s, &depthCounter{})
if err != nil { if err != nil {
panic(err) panic(err)
} }

@ -41,10 +41,12 @@ func (t genericTransport) ReadMessage() (*Message, error) {
} }
func (t genericTransport) SendMessage(msg *Message) error { func (t genericTransport) SendMessage(msg *Message) error {
for _, v := range msg.Body { fds, err := msg.CountFds()
if _, ok := v.(UnixFD); ok { if err != nil {
return errors.New("dbus: unix fd passing not enabled") return err
} }
if fds != 0 {
return errors.New("dbus: unix fd passing not enabled")
} }
return msg.EncodeTo(t, nativeEndian) return msg.EncodeTo(t, nativeEndian)
} }

@ -113,7 +113,7 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
if _, err := io.ReadFull(t.rdr, headerdata[4:]); err != nil { if _, err := io.ReadFull(t.rdr, headerdata[4:]); err != nil {
return nil, err return nil, err
} }
dec := newDecoder(bytes.NewBuffer(headerdata), order) dec := newDecoder(bytes.NewBuffer(headerdata), order, make([]int, 0))
dec.pos = 12 dec.pos = 12
vs, err := dec.Decode(Signature{"a(yv)"}) vs, err := dec.Decode(Signature{"a(yv)"})
if err != nil { if err != nil {
@ -147,7 +147,7 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
msg, err := DecodeMessage(bytes.NewBuffer(all)) msg, err := DecodeMessageWithFDs(bytes.NewBuffer(all), fds)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -179,21 +179,21 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
} }
func (t *unixTransport) SendMessage(msg *Message) error { func (t *unixTransport) SendMessage(msg *Message) error {
fds := make([]int, 0) fdcnt, err := msg.CountFds()
for i, v := range msg.Body { if err != nil {
if fd, ok := v.(UnixFD); ok { return err
msg.Body[i] = UnixFDIndex(len(fds))
fds = append(fds, int(fd))
}
} }
if len(fds) != 0 { if fdcnt != 0 {
if !t.hasUnixFDs { if !t.hasUnixFDs {
return errors.New("dbus: unix fd passing not enabled") return errors.New("dbus: unix fd passing not enabled")
} }
msg.Headers[FieldUnixFDs] = MakeVariant(uint32(len(fds))) msg.Headers[FieldUnixFDs] = MakeVariant(uint32(fdcnt))
oob := syscall.UnixRights(fds...)
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
msg.EncodeTo(buf, nativeEndian) fds, err := msg.EncodeToWithFDs(buf, nativeEndian)
if err != nil {
return err
}
oob := syscall.UnixRights(fds...)
n, oobn, err := t.UnixConn.WriteMsgUnix(buf.Bytes(), oob, nil) n, oobn, err := t.UnixConn.WriteMsgUnix(buf.Bytes(), oob, nil)
if err != nil { if err != nil {
return err return err

@ -0,0 +1,14 @@
package dbus
import "io"
func (t *unixTransport) SendNullByte() error {
n, _, err := t.UnixConn.WriteMsgUnix([]byte{0}, nil, nil)
if err != nil {
return err
}
if n != 1 {
return io.ErrShortWrite
}
return nil
}

@ -1,3 +1,8 @@
examples/getlocale/getlocale
examples/getlocale/getlocale.exe
examples/getlocale-gui/getlocale-gui
examples/getlocale-gui/getlocale-gui.exe
### Go ### ### Go ###
# Binaries for programs and plugins # Binaries for programs and plugins
*.exe *.exe

@ -18,7 +18,7 @@ linters:
- dupl - dupl
- gocyclo - gocyclo
- gofmt - gofmt
- golint - revive
- goprintffuncname - goprintffuncname
- lll - lll
- misspell - misspell

@ -1,3 +1,4 @@
//go:build android
// +build android // +build android
package locale package locale

@ -1,3 +1,4 @@
//go:build darwin && !ios
// +build darwin,!ios // +build darwin,!ios
package locale package locale
@ -10,12 +11,14 @@ import (
"syscall" "syscall"
) )
func execCommand(cmd string, args ...string) (status int, out []byte, err error) { func execCommand(cmd string, args ...string) (status int, out string, err error) {
var bytesOut []byte
status = -1 status = -1
command := exec.Command(cmd, args...) command := exec.Command(cmd, args...)
// Execute the command and get the standard and error outputs // Execute the command and get the standard and error outputs
out, err = command.CombinedOutput() bytesOut, err = command.CombinedOutput()
out = string(bytesOut)
if err != nil { if err != nil {
return return
} }
@ -35,17 +38,23 @@ func GetLocale() (string, error) {
return "", fmt.Errorf("cannot determine locale: %v (output: %s)", err, output) return "", fmt.Errorf("cannot determine locale: %v (output: %s)", err, output)
} }
return strings.TrimRight(strings.Replace(string(output), "_", "-", 1), "\n"), nil // defaults read -g AppleLocale can return a string containing additional
// information after the locale, e.g. "en_US@currency=USD"
if idx := strings.Index(output, "@"); idx != -1 {
output = output[:idx]
}
return strings.TrimRight(strings.Replace(output, "_", "-", 1), "\n"), nil
} }
// appleLanguagesRegex is used to parse the output of "defaults read -g AppleLanguages" // appleLanguagesRegex is used to parse the output of "defaults read -g AppleLanguages"
// e.g.: // e.g.:
// ( // (
// "en-US", // en,
// "fr-FR", // "fr-FR",
// "ja-JP" // "ja-JP"
// ) // )
var appleLanguagesRegex = regexp.MustCompile(`"([a-z]{2}-[A-Z]{2})"`) var appleLanguagesRegex = regexp.MustCompile(`([a-z]{2}(?:-[A-Z]{2})?)`)
// GetLocales retrieves the IETF BCP 47 language tags set on the system. // GetLocales retrieves the IETF BCP 47 language tags set on the system.
func GetLocales() ([]string, error) { func GetLocales() ([]string, error) {
@ -54,7 +63,7 @@ func GetLocales() ([]string, error) {
return nil, fmt.Errorf("cannot determine locale: %v (output: %s)", err, output) return nil, fmt.Errorf("cannot determine locale: %v (output: %s)", err, output)
} }
matches := appleLanguagesRegex.FindAllStringSubmatch(string(output), -1) matches := appleLanguagesRegex.FindAllStringSubmatch(output, -1)
if len(matches) == 0 { if len(matches) == 0 {
return nil, fmt.Errorf("invalid output from \"defaults read -g AppleLanguages\": %s", output) return nil, fmt.Errorf("invalid output from \"defaults read -g AppleLanguages\": %s", output)
} }

@ -1,3 +1,4 @@
//go:build ios
// +build ios // +build ios
package locale package locale

@ -1,3 +1,4 @@
//go:build js && wasm
// +build js,wasm // +build js,wasm
package locale package locale

@ -1,3 +1,4 @@
//go:build !windows && !darwin && !js && !android
// +build !windows,!darwin,!js,!android // +build !windows,!darwin,!js,!android
package locale package locale

@ -1,3 +1,4 @@
//go:build windows
// +build windows // +build windows
package locale package locale

@ -1,3 +1,4 @@
//go:build !android
// +build !android // +build !android
package locale package locale

@ -1,28 +1,101 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects) # Created by https://www.toptal.com/developers/gitignore/api/code,go,linux,macos,windows
*.o # Edit at https://www.toptal.com/developers/gitignore?templates=code,go,linux,macos,windows
*.a
### Code ###
.vscode/*
!.vscode/tasks.json
!.vscode/launch.json
*.code-workspace
### Go ###
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so *.so
*.dylib
# Folders # Test binary, built with `go test -c`
_obj *.test
_test
# Vim swap files # Output of the go coverage tool, specifically when used with LiteIDE
.*.sw? *.out
# Architecture specific extensions/prefixes # Dependency directories (remove the comment below to include it)
*.[568vq] # vendor/
[568vq].out
*.cgo1.go ### Go Patch ###
*.cgo2.c /vendor/
_cgo_defun.c /Godeps/
_cgo_gotypes.go
_cgo_export.*
_testmain.go ### Linux ###
*~
*.exe # temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# Code coverage stuff # End of https://www.toptal.com/developers/gitignore/api/code,go,linux,macos,windows
coverage.out

@ -1,7 +0,0 @@
language: go
install:
- go get golang.org/x/tools/cmd/cover
- go get github.com/mattn/goveralls
script:
- go test -v -covermode=count -coverprofile=coverage.out
- if [[ "$TRAVIS_PULL_REQUEST" = "false" ]]; then $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci -repotoken $COVERALLS_TOKEN; fi

@ -0,0 +1,42 @@
# Changelog
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
The format of this file is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
but only releases after v1.0.3 properly adhere to it.
## [1.2.0] - 2021-01-27
### Added
- HSLuv and HPLuv color spaces (#41, #51)
- CIE LCh(uv) color space, called `LuvLCh` in code (#51)
- JSON and envconfig serialization support for `HexColor` (#42)
- `DistanceLinearRGB` (#53)
### Fixed
- RGB to/from XYZ conversion is more accurate (#51)
- A bug in `XYZToLuvWhiteRef` that only applied to very small values was fixed (#51)
- `BlendHCL` output is clamped so that it's not invalid (#46)
- Properly documented `DistanceCIE76` (#40)
- Some small godoc fixes
## [1.0.3] - 2019-11-11
- Remove SQLMock dependency
## [1.0.2] - 2019-04-07
- Fixes SQLMock dependency
## [1.0.1] - 2019-03-24
- Adds support for Go Modules
## [1.0.0] - 2018-05-26
- API Breaking change in `MakeColor`: instead of `panic`ing when alpha is zero, it now returns a secondary, boolean return value indicating success. See [the color.Color interface](#the-colorcolor-interface) section and [this FAQ entry](#q-why-would-makecolor-ever-fail) for details.
## [0.9.0] - 2018-05-26
- Initial version number after having ignored versioning for a long time :)

@ -1,9 +1,9 @@
go-colorful go-colorful
=========== ===========
A library for playing with colors in go (golang).
[![Build Status](https://travis-ci.org/lucasb-eyer/go-colorful.svg?branch=master)](https://travis-ci.org/lucasb-eyer/go-colorful) [![go reportcard](https://goreportcard.com/badge/github.com/lucasb-eyer/go-colorful)](https://goreportcard.com/report/github.com/lucasb-eyer/go-colorful)
[![Coverage Status](https://coveralls.io/repos/github/lucasb-eyer/go-colorful/badge.svg?branch=master)](https://coveralls.io/github/lucasb-eyer/go-colorful?branch=master)
A library for playing with colors in Go. Supports Go 1.13 onwards.
Why? Why?
==== ====
@ -30,6 +30,9 @@ Go-Colorful stores colors in RGB and provides methods from converting these to v
- **CIE-L\*a\*b\*:** A *perceptually uniform* color space, i.e. distances are meaningful. L\* in [0..1] and a\*, b\* almost in [-1..1]. - **CIE-L\*a\*b\*:** A *perceptually uniform* color space, i.e. distances are meaningful. L\* in [0..1] and a\*, b\* almost in [-1..1].
- **CIE-L\*u\*v\*:** Very similar to CIE-L\*a\*b\*, there is [no consensus](http://en.wikipedia.org/wiki/CIELUV#Historical_background) on which one is "better". - **CIE-L\*u\*v\*:** Very similar to CIE-L\*a\*b\*, there is [no consensus](http://en.wikipedia.org/wiki/CIELUV#Historical_background) on which one is "better".
- **CIE-L\*C\*h° (HCL):** This is generally the [most useful](http://vis4.net/blog/posts/avoid-equidistant-hsv-colors/) one; CIE-L\*a\*b\* space in polar coordinates, i.e. a *better* HSV. H° is in [0..360], C\* almost in [-1..1] and L\* as in CIE-L\*a\*b\*. - **CIE-L\*C\*h° (HCL):** This is generally the [most useful](http://vis4.net/blog/posts/avoid-equidistant-hsv-colors/) one; CIE-L\*a\*b\* space in polar coordinates, i.e. a *better* HSV. H° is in [0..360], C\* almost in [-1..1] and L\* as in CIE-L\*a\*b\*.
- **CIE LCh(uv):** Called `LuvLCh` in code, this is a cylindrical transformation of the CIE-L\*u\*v\* color space. Like HCL above: H° is in [0..360], C\* almost in [-1..1] and L\* as in CIE-L\*u\*v\*.
- **HSLuv:** The better alternative to HSL, see [here](https://www.hsluv.org/) and [here](https://www.kuon.ch/post/2020-03-08-hsluv/). Hue in [0..360], Saturation and Luminance in [0..1].
- **HPLuv:** A variant of HSLuv. The color space is smoother, but only pastel colors can be included. Because the valid colors are limited, it's easy to get invalid Saturation values way above 1.0, indicating the color can't be represented in HPLuv beccause it's not pastel.
For the colorspaces where it makes sense (XYZ, Lab, Luv, HCl), the For the colorspaces where it makes sense (XYZ, Lab, Luv, HCl), the
[D65](http://en.wikipedia.org/wiki/Illuminant_D65) is used as reference white [D65](http://en.wikipedia.org/wiki/Illuminant_D65) is used as reference white
@ -248,14 +251,14 @@ func main() {
//c2, _ := colorful.Hex("#1E3140") //c2, _ := colorful.Hex("#1E3140")
for i := 0 ; i < blocks ; i++ { for i := 0 ; i < blocks ; i++ {
draw.Draw(img, image.Rect(i*blockw, 0,(i+1)*blockw, 40), &image.Uniform{c1.BlendHsv(c2, float64(i)/float64(blocks-1))}, image.ZP, draw.Src) draw.Draw(img, image.Rect(i*blockw, 0,(i+1)*blockw, 40), &image.Uniform{c1.BlendHsv(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
draw.Draw(img, image.Rect(i*blockw, 40,(i+1)*blockw, 80), &image.Uniform{c1.BlendLuv(c2, float64(i)/float64(blocks-1))}, image.ZP, draw.Src) draw.Draw(img, image.Rect(i*blockw, 40,(i+1)*blockw, 80), &image.Uniform{c1.BlendLuv(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
draw.Draw(img, image.Rect(i*blockw, 80,(i+1)*blockw,120), &image.Uniform{c1.BlendRgb(c2, float64(i)/float64(blocks-1))}, image.ZP, draw.Src) draw.Draw(img, image.Rect(i*blockw, 80,(i+1)*blockw,120), &image.Uniform{c1.BlendRgb(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
draw.Draw(img, image.Rect(i*blockw,120,(i+1)*blockw,160), &image.Uniform{c1.BlendLab(c2, float64(i)/float64(blocks-1))}, image.ZP, draw.Src) draw.Draw(img, image.Rect(i*blockw,120,(i+1)*blockw,160), &image.Uniform{c1.BlendLab(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
draw.Draw(img, image.Rect(i*blockw,160,(i+1)*blockw,200), &image.Uniform{c1.BlendHcl(c2, float64(i)/float64(blocks-1))}, image.ZP, draw.Src) draw.Draw(img, image.Rect(i*blockw,160,(i+1)*blockw,200), &image.Uniform{c1.BlendHcl(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src)
// This can be used to "fix" invalid colors in the gradient. // This can be used to "fix" invalid colors in the gradient.
//draw.Draw(img, image.Rect(i*blockw,160,(i+1)*blockw,200), &image.Uniform{c1.BlendHcl(c2, float64(i)/float64(blocks-1)).Clamped()}, image.ZP, draw.Src) //draw.Draw(img, image.Rect(i*blockw,160,(i+1)*blockw,200), &image.Uniform{c1.BlendHcl(c2, float64(i)/float64(blocks-1)).Clamped()}, image.Point{}, draw.Src)
} }
toimg, err := os.Create("colorblend.png") toimg, err := os.Create("colorblend.png")
@ -468,25 +471,12 @@ section above.
Who? Who?
==== ====
This library has been developed by Lucas Beyer with contributions from This library was developed by Lucas Beyer with contributions from
Bastien Dejean (@baskerville), Phil Kulak (@pkulak) and Christian Muehlhaeuser (@muesli). Bastien Dejean (@baskerville), Phil Kulak (@pkulak) and Christian Muehlhaeuser (@muesli).
Release Notes It is now maintained by makeworld (@makeworld-the-better-one).
=============
### Version 1.0
- API Breaking change in `MakeColor`: instead of `panic`ing when alpha is zero, it now returns a secondary, boolean return value indicating success. See [the color.Color interface](https://github.com/lucasb-eyer/go-colorful#the-colorcolor-interface) section and [this FAQ entry](https://github.com/lucasb-eyer/go-colorful#q-why-would-makecolor-ever-fail) for details.
### Version 0.9
- Initial version number after having ignored versioning for a long time :)
License: MIT
============
Copyright (c) 2013 Lucas Beyer
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ## License
This repo is under the MIT license, see [LICENSE](LICENSE) for details.

@ -48,6 +48,11 @@ func (col Color) RGB255() (r, g, b uint8) {
return return
} }
// Used to simplify HSLuv testing.
func (col Color) values() (float64, float64, float64) {
return col.R, col.G, col.B
}
// This is the tolerance used when comparing colors using AlmostEqualRgb. // This is the tolerance used when comparing colors using AlmostEqualRgb.
const Delta = 1.0 / 255.0 const Delta = 1.0 / 255.0
@ -64,6 +69,7 @@ func (c Color) IsValid() bool {
0.0 <= c.B && c.B <= 1.0 0.0 <= c.B && c.B <= 1.0
} }
// clamp01 clamps from 0 to 1.
func clamp01(v float64) float64 { func clamp01(v float64) float64 {
return math.Max(0.0, math.Min(v, 1.0)) return math.Max(0.0, math.Min(v, 1.0))
} }
@ -88,6 +94,15 @@ func (c1 Color) DistanceRgb(c2 Color) float64 {
return math.Sqrt(sq(c1.R-c2.R) + sq(c1.G-c2.G) + sq(c1.B-c2.B)) return math.Sqrt(sq(c1.R-c2.R) + sq(c1.G-c2.G) + sq(c1.B-c2.B))
} }
// DistanceLinearRGB computes the distance between two colors in linear RGB
// space. This is not useful for measuring how humans perceive color, but
// might be useful for other things, like dithering.
func (c1 Color) DistanceLinearRGB(c2 Color) float64 {
r1, g1, b1 := c1.LinearRgb()
r2, g2, b2 := c2.LinearRgb()
return math.Sqrt(sq(r1-r2) + sq(g1-g2) + sq(b1-b2))
}
// Check for equality between colors within the tolerance Delta (1/255). // Check for equality between colors within the tolerance Delta (1/255).
func (c1 Color) AlmostEqualRgb(c2 Color) bool { func (c1 Color) AlmostEqualRgb(c2 Color) bool {
return math.Abs(c1.R-c2.R)+ return math.Abs(c1.R-c2.R)+
@ -422,16 +437,16 @@ func FastLinearRgb(r, g, b float64) Color {
// XyzToLinearRgb converts from CIE XYZ-space to Linear RGB space. // XyzToLinearRgb converts from CIE XYZ-space to Linear RGB space.
func XyzToLinearRgb(x, y, z float64) (r, g, b float64) { func XyzToLinearRgb(x, y, z float64) (r, g, b float64) {
r = 3.2404542*x - 1.5371385*y - 0.4985314*z r = 3.2409699419045214*x - 1.5373831775700935*y - 0.49861076029300328*z
g = -0.9692660*x + 1.8760108*y + 0.0415560*z g = -0.96924363628087983*x + 1.8759675015077207*y + 0.041555057407175613*z
b = 0.0556434*x - 0.2040259*y + 1.0572252*z b = 0.055630079696993609*x - 0.20397695888897657*y + 1.0569715142428786*z
return return
} }
func LinearRgbToXyz(r, g, b float64) (x, y, z float64) { func LinearRgbToXyz(r, g, b float64) (x, y, z float64) {
x = 0.4124564*r + 0.3575761*g + 0.1804375*b x = 0.41239079926595948*r + 0.35758433938387796*g + 0.18048078840183429*b
y = 0.2126729*r + 0.7151522*g + 0.0721750*b y = 0.21263900587151036*r + 0.71516867876775593*g + 0.072192315360733715*b
z = 0.0193339*r + 0.1191920*g + 0.9503041*b z = 0.019330818715591851*r + 0.11919477979462599*g + 0.95053215224966058*b
return return
} }
@ -569,7 +584,7 @@ func (col Color) LabWhiteRef(wref [3]float64) (l, a, b float64) {
// Generates a color by using data given in CIE L*a*b* space using D65 as reference white. // Generates a color by using data given in CIE L*a*b* space using D65 as reference white.
// WARNING: many combinations of `l`, `a`, and `b` values do not have corresponding // WARNING: many combinations of `l`, `a`, and `b` values do not have corresponding
// valid RGB values, check the FAQ in the README if you're unsure. // valid RGB values, check the FAQ in the README if you're unsure.
func Lab(l, a, b float64) Color { func Lab(l, a, b float64) Color {
return Xyz(LabToXyz(l, a, b)) return Xyz(LabToXyz(l, a, b))
} }
@ -589,7 +604,7 @@ func (c1 Color) DistanceLab(c2 Color) float64 {
return math.Sqrt(sq(l1-l2) + sq(a1-a2) + sq(b1-b2)) return math.Sqrt(sq(l1-l2) + sq(a1-a2) + sq(b1-b2))
} }
// That's actually the same, but I don't want to break code. // DistanceCIE76 is the same as DistanceLab.
func (c1 Color) DistanceCIE76(c2 Color) float64 { func (c1 Color) DistanceCIE76(c2 Color) float64 {
return c1.DistanceLab(c2) return c1.DistanceLab(c2)
} }
@ -739,7 +754,7 @@ func XyzToLuv(x, y, z float64) (l, a, b float64) {
func XyzToLuvWhiteRef(x, y, z float64, wref [3]float64) (l, u, v float64) { func XyzToLuvWhiteRef(x, y, z float64, wref [3]float64) (l, u, v float64) {
if y/wref[1] <= 6.0/29.0*6.0/29.0*6.0/29.0 { if y/wref[1] <= 6.0/29.0*6.0/29.0*6.0/29.0 {
l = y / wref[1] * 29.0 / 3.0 * 29.0 / 3.0 * 29.0 / 3.0 l = y / wref[1] * (29.0 / 3.0 * 29.0 / 3.0 * 29.0 / 3.0) / 100.0
} else { } else {
l = 1.16*math.Cbrt(y/wref[1]) - 0.16 l = 1.16*math.Cbrt(y/wref[1]) - 0.16
} }
@ -803,8 +818,8 @@ func (col Color) LuvWhiteRef(wref [3]float64) (l, u, v float64) {
// Generates a color by using data given in CIE L*u*v* space using D65 as reference white. // Generates a color by using data given in CIE L*u*v* space using D65 as reference white.
// L* is in [0..1] and both u* and v* are in about [-1..1] // L* is in [0..1] and both u* and v* are in about [-1..1]
// WARNING: many combinations of `l`, `a`, and `b` values do not have corresponding // WARNING: many combinations of `l`, `u`, and `v` values do not have corresponding
// valid RGB values, check the FAQ in the README if you're unsure. // valid RGB values, check the FAQ in the README if you're unsure.
func Luv(l, u, v float64) Color { func Luv(l, u, v float64) Color {
return Xyz(LuvToXyz(l, u, v)) return Xyz(LuvToXyz(l, u, v))
} }
@ -870,8 +885,8 @@ func (col Color) HclWhiteRef(wref [3]float64) (h, c, l float64) {
// Generates a color by using data given in HCL space using D65 as reference white. // Generates a color by using data given in HCL space using D65 as reference white.
// H values are in [0..360], C and L values are in [0..1] // H values are in [0..360], C and L values are in [0..1]
// WARNING: many combinations of `l`, `a`, and `b` values do not have corresponding // WARNING: many combinations of `h`, `c`, and `l` values do not have corresponding
// valid RGB values, check the FAQ in the README if you're unsure. // valid RGB values, check the FAQ in the README if you're unsure.
func Hcl(h, c, l float64) Color { func Hcl(h, c, l float64) Color {
return HclWhiteRef(h, c, l, D65) return HclWhiteRef(h, c, l, D65)
} }
@ -899,5 +914,66 @@ func (col1 Color) BlendHcl(col2 Color, t float64) Color {
h2, c2, l2 := col2.Hcl() h2, c2, l2 := col2.Hcl()
// We know that h are both in [0..360] // We know that h are both in [0..360]
return Hcl(interp_angle(h1, h2, t), c1+t*(c2-c1), l1+t*(l2-l1)) return Hcl(interp_angle(h1, h2, t), c1+t*(c2-c1), l1+t*(l2-l1)).Clamped()
}
// LuvLch
// Converts the given color to LuvLCh space using D65 as reference white.
// h values are in [0..360], C and L values are in [0..1] although C can overshoot 1.0
func (col Color) LuvLCh() (l, c, h float64) {
return col.LuvLChWhiteRef(D65)
}
func LuvToLuvLCh(L, u, v float64) (l, c, h float64) {
// Oops, floating point workaround necessary if u ~= v and both are very small (i.e. almost zero).
if math.Abs(v-u) > 1e-4 && math.Abs(u) > 1e-4 {
h = math.Mod(57.29577951308232087721*math.Atan2(v, u)+360.0, 360.0) // Rad2Deg
} else {
h = 0.0
}
l = L
c = math.Sqrt(sq(u) + sq(v))
return
}
// Converts the given color to LuvLCh space, taking into account
// a given reference white. (i.e. the monitor's white)
// h values are in [0..360], c and l values are in [0..1]
func (col Color) LuvLChWhiteRef(wref [3]float64) (l, c, h float64) {
return LuvToLuvLCh(col.LuvWhiteRef(wref))
}
// Generates a color by using data given in LuvLCh space using D65 as reference white.
// h values are in [0..360], C and L values are in [0..1]
// WARNING: many combinations of `l`, `c`, and `h` values do not have corresponding
// valid RGB values, check the FAQ in the README if you're unsure.
func LuvLCh(l, c, h float64) Color {
return LuvLChWhiteRef(l, c, h, D65)
}
func LuvLChToLuv(l, c, h float64) (L, u, v float64) {
H := 0.01745329251994329576 * h // Deg2Rad
u = c * math.Cos(H)
v = c * math.Sin(H)
L = l
return
}
// Generates a color by using data given in LuvLCh space, taking
// into account a given reference white. (i.e. the monitor's white)
// h values are in [0..360], C and L values are in [0..1]
func LuvLChWhiteRef(l, c, h float64, wref [3]float64) Color {
L, u, v := LuvLChToLuv(l, c, h)
return LuvWhiteRef(L, u, v, wref)
}
// BlendLuvLCh blends two colors in the cylindrical CIELUV color space.
// t == 0 results in c1, t == 1 results in c2
func (col1 Color) BlendLuvLCh(col2 Color, t float64) Color {
l1, c1, h1 := col1.LuvLCh()
l2, c2, h2 := col2.LuvLCh()
// We know that h are both in [0..360]
return LuvLCh(l1+t*(l2-l1), c1+t*(c2-c1), interp_angle(h1, h2, t))
} }

@ -2,12 +2,14 @@ package colorful
import ( import (
"database/sql/driver" "database/sql/driver"
"encoding/json"
"fmt" "fmt"
"reflect" "reflect"
) )
// A HexColor is a Color stored as a hex string "#rrggbb". It implements the // A HexColor is a Color stored as a hex string "#rrggbb". It implements the
// database/sql.Scanner and database/sql/driver.Value interfaces. // database/sql.Scanner, database/sql/driver.Value,
// encoding/json.Unmarshaler and encoding/json.Marshaler interfaces.
type HexColor Color type HexColor Color
type errUnsupportedType struct { type errUnsupportedType struct {
@ -35,3 +37,31 @@ func (hc *HexColor) Value() (driver.Value, error) {
func (e errUnsupportedType) Error() string { func (e errUnsupportedType) Error() string {
return fmt.Sprintf("unsupported type: got %v, want a %s", e.got, e.want) return fmt.Sprintf("unsupported type: got %v, want a %s", e.got, e.want)
} }
func (hc *HexColor) UnmarshalJSON(data []byte) error {
var hexCode string
if err := json.Unmarshal(data, &hexCode); err != nil {
return err
}
var col, err = Hex(hexCode)
if err != nil {
return err
}
*hc = HexColor(col)
return nil
}
func (hc HexColor) MarshalJSON() ([]byte, error) {
return json.Marshal(Color(hc).Hex())
}
// Decode - deserialize function for https://github.com/kelseyhightower/envconfig
func (hc *HexColor) Decode(hexCode string) error {
var col, err = Hex(hexCode)
if err != nil {
return err
}
*hc = HexColor(col)
return nil
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,207 @@
package colorful
import "math"
// Source: https://github.com/hsluv/hsluv-go
// Under MIT License
// Modified so that Saturation and Luminance are in [0..1] instead of [0..100].
// HSLuv uses a rounded version of the D65. This has no impact on the final RGB
// values, but to keep high levels of accuracy for internal operations and when
// comparing to the test values, this modified white reference is used internally.
//
// See this GitHub thread for details on these values:
// https://github.com/hsluv/hsluv/issues/79
var hSLuvD65 = [3]float64{0.95045592705167, 1.0, 1.089057750759878}
func LuvLChToHSLuv(l, c, h float64) (float64, float64, float64) {
// [-1..1] but the code expects it to be [-100..100]
c *= 100.0
l *= 100.0
var s, max float64
if l > 99.9999999 || l < 0.00000001 {
s = 0.0
} else {
max = maxChromaForLH(l, h)
s = c / max * 100.0
}
return h, clamp01(s / 100.0), clamp01(l / 100.0)
}
func HSLuvToLuvLCh(h, s, l float64) (float64, float64, float64) {
l *= 100.0
s *= 100.0
var c, max float64
if l > 99.9999999 || l < 0.00000001 {
c = 0.0
} else {
max = maxChromaForLH(l, h)
c = max / 100.0 * s
}
// c is [-100..100], but for LCh it's supposed to be almost [-1..1]
return clamp01(l / 100.0), c / 100.0, h
}
func LuvLChToHPLuv(l, c, h float64) (float64, float64, float64) {
// [-1..1] but the code expects it to be [-100..100]
c *= 100.0
l *= 100.0
var s, max float64
if l > 99.9999999 || l < 0.00000001 {
s = 0.0
} else {
max = maxSafeChromaForL(l)
s = c / max * 100.0
}
return h, s / 100.0, l / 100.0
}
func HPLuvToLuvLCh(h, s, l float64) (float64, float64, float64) {
// [-1..1] but the code expects it to be [-100..100]
l *= 100.0
s *= 100.0
var c, max float64
if l > 99.9999999 || l < 0.00000001 {
c = 0.0
} else {
max = maxSafeChromaForL(l)
c = max / 100.0 * s
}
return l / 100.0, c / 100.0, h
}
// HSLuv creates a new Color from values in the HSLuv color space.
// Hue in [0..360], a Saturation [0..1], and a Luminance (lightness) in [0..1].
//
// The returned color values are clamped (using .Clamped), so this will never output
// an invalid color.
func HSLuv(h, s, l float64) Color {
// HSLuv -> LuvLCh -> CIELUV -> CIEXYZ -> Linear RGB -> sRGB
l, u, v := LuvLChToLuv(HSLuvToLuvLCh(h, s, l))
return LinearRgb(XyzToLinearRgb(LuvToXyzWhiteRef(l, u, v, hSLuvD65))).Clamped()
}
// HPLuv creates a new Color from values in the HPLuv color space.
// Hue in [0..360], a Saturation [0..1], and a Luminance (lightness) in [0..1].
//
// The returned color values are clamped (using .Clamped), so this will never output
// an invalid color.
func HPLuv(h, s, l float64) Color {
// HPLuv -> LuvLCh -> CIELUV -> CIEXYZ -> Linear RGB -> sRGB
l, u, v := LuvLChToLuv(HPLuvToLuvLCh(h, s, l))
return LinearRgb(XyzToLinearRgb(LuvToXyzWhiteRef(l, u, v, hSLuvD65))).Clamped()
}
// HSLuv returns the Hue, Saturation and Luminance of the color in the HSLuv
// color space. Hue in [0..360], a Saturation [0..1], and a Luminance
// (lightness) in [0..1].
func (col Color) HSLuv() (h, s, l float64) {
// sRGB -> Linear RGB -> CIEXYZ -> CIELUV -> LuvLCh -> HSLuv
return LuvLChToHSLuv(col.LuvLChWhiteRef(hSLuvD65))
}
// HPLuv returns the Hue, Saturation and Luminance of the color in the HSLuv
// color space. Hue in [0..360], a Saturation [0..1], and a Luminance
// (lightness) in [0..1].
//
// Note that HPLuv can only represent pastel colors, and so the Saturation
// value could be much larger than 1 for colors it can't represent.
func (col Color) HPLuv() (h, s, l float64) {
return LuvLChToHPLuv(col.LuvLChWhiteRef(hSLuvD65))
}
// DistanceHSLuv calculates Euclidan distance in the HSLuv colorspace. No idea
// how useful this is.
//
// The Hue value is divided by 100 before the calculation, so that H, S, and L
// have the same relative ranges.
func (c1 Color) DistanceHSLuv(c2 Color) float64 {
h1, s1, l1 := c1.HSLuv()
h2, s2, l2 := c2.HSLuv()
return math.Sqrt(sq((h1-h2)/100.0) + sq(s1-s2) + sq(l1-l2))
}
// DistanceHPLuv calculates Euclidean distance in the HPLuv colorspace. No idea
// how useful this is.
//
// The Hue value is divided by 100 before the calculation, so that H, S, and L
// have the same relative ranges.
func (c1 Color) DistanceHPLuv(c2 Color) float64 {
h1, s1, l1 := c1.HPLuv()
h2, s2, l2 := c2.HPLuv()
return math.Sqrt(sq((h1-h2)/100.0) + sq(s1-s2) + sq(l1-l2))
}
var m = [3][3]float64{
{3.2409699419045214, -1.5373831775700935, -0.49861076029300328},
{-0.96924363628087983, 1.8759675015077207, 0.041555057407175613},
{0.055630079696993609, -0.20397695888897657, 1.0569715142428786},
}
const kappa = 903.2962962962963
const epsilon = 0.0088564516790356308
func maxChromaForLH(l, h float64) float64 {
hRad := h / 360.0 * math.Pi * 2.0
minLength := math.MaxFloat64
for _, line := range getBounds(l) {
length := lengthOfRayUntilIntersect(hRad, line[0], line[1])
if length > 0.0 && length < minLength {
minLength = length
}
}
return minLength
}
func getBounds(l float64) [6][2]float64 {
var sub2 float64
var ret [6][2]float64
sub1 := math.Pow(l+16.0, 3.0) / 1560896.0
if sub1 > epsilon {
sub2 = sub1
} else {
sub2 = l / kappa
}
for i := range m {
for k := 0; k < 2; k++ {
top1 := (284517.0*m[i][0] - 94839.0*m[i][2]) * sub2
top2 := (838422.0*m[i][2]+769860.0*m[i][1]+731718.0*m[i][0])*l*sub2 - 769860.0*float64(k)*l
bottom := (632260.0*m[i][2]-126452.0*m[i][1])*sub2 + 126452.0*float64(k)
ret[i*2+k][0] = top1 / bottom
ret[i*2+k][1] = top2 / bottom
}
}
return ret
}
func lengthOfRayUntilIntersect(theta, x, y float64) (length float64) {
length = y / (math.Sin(theta) - x*math.Cos(theta))
return
}
func maxSafeChromaForL(l float64) float64 {
minLength := math.MaxFloat64
for _, line := range getBounds(l) {
m1 := line[0]
b1 := line[1]
x := intersectLineLine(m1, b1, -1.0/m1, 0.0)
dist := distanceFromPole(x, b1+x*m1)
if dist < minLength {
minLength = dist
}
}
return minLength
}
func intersectLineLine(x1, y1, x2, y2 float64) float64 {
return (y1 - y2) / (x2 - x1)
}
func distanceFromPole(x, y float64) float64 {
return math.Sqrt(math.Pow(x, 2.0) + math.Pow(y, 2.0))
}

@ -61,7 +61,7 @@ func SoftPaletteEx(colorsCount int, settings SoftPaletteSettings) ([]Color, erro
// That would cause some infinite loops down there... // That would cause some infinite loops down there...
if len(samples) < colorsCount { if len(samples) < colorsCount {
return nil, fmt.Errorf("palettegen: more colors requested (%v) than samples available (%v). Your requested color count may be wrong, you might want to use many samples or your constraint function makes the valid color space too small.", colorsCount, len(samples)) return nil, fmt.Errorf("palettegen: more colors requested (%v) than samples available (%v). Your requested color count may be wrong, you might want to use many samples or your constraint function makes the valid color space too small", colorsCount, len(samples))
} else if len(samples) == colorsCount { } else if len(samples) == colorsCount {
return labs2cols(samples), nil // Oops? return labs2cols(samples), nil // Oops?
} }

@ -1,15 +0,0 @@
language: go
sudo: false
go:
- 1.13.x
- tip
before_install:
- go get -t -v ./...
script:
- ./go.test.sh
after_success:
- bash <(curl -s https://codecov.io/bash)

@ -1,6 +1,6 @@
# go-colorable # go-colorable
[![Build Status](https://travis-ci.org/mattn/go-colorable.svg?branch=master)](https://travis-ci.org/mattn/go-colorable) [![Build Status](https://github.com/mattn/go-colorable/workflows/test/badge.svg)](https://github.com/mattn/go-colorable/actions?query=workflow%3Atest)
[![Codecov](https://codecov.io/gh/mattn/go-colorable/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-colorable) [![Codecov](https://codecov.io/gh/mattn/go-colorable/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-colorable)
[![GoDoc](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable) [![GoDoc](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable)
[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable) [![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable)

@ -1,3 +1,4 @@
//go:build appengine
// +build appengine // +build appengine
package colorable package colorable

@ -1,5 +1,5 @@
// +build !windows //go:build !windows && !appengine
// +build !appengine // +build !windows,!appengine
package colorable package colorable

@ -1,5 +1,5 @@
// +build windows //go:build windows && !appengine
// +build !appengine // +build windows,!appengine
package colorable package colorable
@ -452,18 +452,22 @@ func (w *Writer) Write(data []byte) (n int, err error) {
} else { } else {
er = bytes.NewReader(data) er = bytes.NewReader(data)
} }
var bw [1]byte var plaintext bytes.Buffer
loop: loop:
for { for {
c1, err := er.ReadByte() c1, err := er.ReadByte()
if err != nil { if err != nil {
plaintext.WriteTo(w.out)
break loop break loop
} }
if c1 != 0x1b { if c1 != 0x1b {
bw[0] = c1 plaintext.WriteByte(c1)
w.out.Write(bw[:])
continue continue
} }
_, err = plaintext.WriteTo(w.out)
if err != nil {
break loop
}
c2, err := er.ReadByte() c2, err := er.ReadByte()
if err != nil { if err != nil {
break loop break loop

@ -18,21 +18,22 @@ func NewNonColorable(w io.Writer) io.Writer {
// Write writes data on console // Write writes data on console
func (w *NonColorable) Write(data []byte) (n int, err error) { func (w *NonColorable) Write(data []byte) (n int, err error) {
er := bytes.NewReader(data) er := bytes.NewReader(data)
var bw [1]byte var plaintext bytes.Buffer
loop: loop:
for { for {
c1, err := er.ReadByte() c1, err := er.ReadByte()
if err != nil { if err != nil {
plaintext.WriteTo(w.out)
break loop break loop
} }
if c1 != 0x1b { if c1 != 0x1b {
bw[0] = c1 plaintext.WriteByte(c1)
_, err = w.out.Write(bw[:])
if err != nil {
break loop
}
continue continue
} }
_, err = plaintext.WriteTo(w.out)
if err != nil {
break loop
}
c2, err := er.ReadByte() c2, err := er.ReadByte()
if err != nil { if err != nil {
break loop break loop

@ -14,7 +14,7 @@ import (
"time" "time"
) )
// These constants from [PROTOCOL.certkeys] represent the algorithm names // These constants from [PROTOCOL.certkeys] represent the key algorithm names
// for certificate types supported by this package. // for certificate types supported by this package.
const ( const (
CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com" CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
@ -27,6 +27,14 @@ const (
CertAlgoSKED25519v01 = "sk-ssh-ed25519-cert-v01@openssh.com" CertAlgoSKED25519v01 = "sk-ssh-ed25519-cert-v01@openssh.com"
) )
// These constants from [PROTOCOL.certkeys] represent additional signature
// algorithm names for certificate types supported by this package.
const (
CertSigAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
CertSigAlgoRSASHA2256v01 = "rsa-sha2-256-cert-v01@openssh.com"
CertSigAlgoRSASHA2512v01 = "rsa-sha2-512-cert-v01@openssh.com"
)
// Certificate types distinguish between host and user // Certificate types distinguish between host and user
// certificates. The values can be set in the CertType field of // certificates. The values can be set in the CertType field of
// Certificate. // Certificate.
@ -423,6 +431,12 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
} }
c.SignatureKey = authority.PublicKey() c.SignatureKey = authority.PublicKey()
if v, ok := authority.(AlgorithmSigner); ok {
if v.PublicKey().Type() == KeyAlgoRSA {
authority = &rsaSigner{v, SigAlgoRSASHA2512}
}
}
sig, err := authority.Sign(rand, c.bytesForSigning()) sig, err := authority.Sign(rand, c.bytesForSigning())
if err != nil { if err != nil {
return err return err
@ -431,8 +445,14 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
return nil return nil
} }
// certAlgoNames includes a mapping from signature algorithms to the
// corresponding certificate signature algorithm. When a key type (such
// as ED25516) is associated with only one algorithm, the KeyAlgo
// constant is used instead of the SigAlgo.
var certAlgoNames = map[string]string{ var certAlgoNames = map[string]string{
KeyAlgoRSA: CertAlgoRSAv01, SigAlgoRSA: CertSigAlgoRSAv01,
SigAlgoRSASHA2256: CertSigAlgoRSASHA2256v01,
SigAlgoRSASHA2512: CertSigAlgoRSASHA2512v01,
KeyAlgoDSA: CertAlgoDSAv01, KeyAlgoDSA: CertAlgoDSAv01,
KeyAlgoECDSA256: CertAlgoECDSA256v01, KeyAlgoECDSA256: CertAlgoECDSA256v01,
KeyAlgoECDSA384: CertAlgoECDSA384v01, KeyAlgoECDSA384: CertAlgoECDSA384v01,

@ -115,12 +115,25 @@ func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) e
// verifyHostKeySignature verifies the host key obtained in the key // verifyHostKeySignature verifies the host key obtained in the key
// exchange. // exchange.
func verifyHostKeySignature(hostKey PublicKey, result *kexResult) error { func verifyHostKeySignature(hostKey PublicKey, algo string, result *kexResult) error {
sig, rest, ok := parseSignatureBody(result.Signature) sig, rest, ok := parseSignatureBody(result.Signature)
if len(rest) > 0 || !ok { if len(rest) > 0 || !ok {
return errors.New("ssh: signature parse error") return errors.New("ssh: signature parse error")
} }
// For keys, underlyingAlgo is exactly algo. For certificates,
// we have to look up the underlying key algorithm that SSH
// uses to evaluate signatures.
underlyingAlgo := algo
for sigAlgo, certAlgo := range certAlgoNames {
if certAlgo == algo {
underlyingAlgo = sigAlgo
}
}
if sig.Format != underlyingAlgo {
return fmt.Errorf("ssh: invalid signature algorithm %q, expected %q", sig.Format, underlyingAlgo)
}
return hostKey.Verify(result.H, sig) return hostKey.Verify(result.H, sig)
} }

@ -69,11 +69,13 @@ var preferredKexAlgos = []string{
// supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods // supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods
// of authenticating servers) in preference order. // of authenticating servers) in preference order.
var supportedHostKeyAlgos = []string{ var supportedHostKeyAlgos = []string{
CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertSigAlgoRSASHA2512v01, CertSigAlgoRSASHA2256v01,
CertSigAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01,
CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01,
KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,
KeyAlgoRSA, KeyAlgoDSA, SigAlgoRSASHA2512, SigAlgoRSASHA2256,
SigAlgoRSA, KeyAlgoDSA,
KeyAlgoED25519, KeyAlgoED25519,
} }
@ -90,16 +92,20 @@ var supportedCompressions = []string{compressionNone}
// hashFuncs keeps the mapping of supported algorithms to their respective // hashFuncs keeps the mapping of supported algorithms to their respective
// hashes needed for signature verification. // hashes needed for signature verification.
var hashFuncs = map[string]crypto.Hash{ var hashFuncs = map[string]crypto.Hash{
KeyAlgoRSA: crypto.SHA1, SigAlgoRSA: crypto.SHA1,
KeyAlgoDSA: crypto.SHA1, SigAlgoRSASHA2256: crypto.SHA256,
KeyAlgoECDSA256: crypto.SHA256, SigAlgoRSASHA2512: crypto.SHA512,
KeyAlgoECDSA384: crypto.SHA384, KeyAlgoDSA: crypto.SHA1,
KeyAlgoECDSA521: crypto.SHA512, KeyAlgoECDSA256: crypto.SHA256,
CertAlgoRSAv01: crypto.SHA1, KeyAlgoECDSA384: crypto.SHA384,
CertAlgoDSAv01: crypto.SHA1, KeyAlgoECDSA521: crypto.SHA512,
CertAlgoECDSA256v01: crypto.SHA256, CertSigAlgoRSAv01: crypto.SHA1,
CertAlgoECDSA384v01: crypto.SHA384, CertSigAlgoRSASHA2256v01: crypto.SHA256,
CertAlgoECDSA521v01: crypto.SHA512, CertSigAlgoRSASHA2512v01: crypto.SHA512,
CertAlgoDSAv01: crypto.SHA1,
CertAlgoECDSA256v01: crypto.SHA256,
CertAlgoECDSA384v01: crypto.SHA384,
CertAlgoECDSA521v01: crypto.SHA512,
} }
// unexpectedMessageError results when the SSH message that we received didn't // unexpectedMessageError results when the SSH message that we received didn't

@ -457,8 +457,15 @@ func (t *handshakeTransport) sendKexInit() error {
if len(t.hostKeys) > 0 { if len(t.hostKeys) > 0 {
for _, k := range t.hostKeys { for _, k := range t.hostKeys {
msg.ServerHostKeyAlgos = append( algo := k.PublicKey().Type()
msg.ServerHostKeyAlgos, k.PublicKey().Type()) switch algo {
case KeyAlgoRSA:
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, []string{SigAlgoRSASHA2512, SigAlgoRSASHA2256, SigAlgoRSA}...)
case CertAlgoRSAv01:
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, []string{CertSigAlgoRSASHA2512v01, CertSigAlgoRSASHA2256v01, CertSigAlgoRSAv01}...)
default:
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algo)
}
} }
} else { } else {
msg.ServerHostKeyAlgos = t.hostKeyAlgorithms msg.ServerHostKeyAlgos = t.hostKeyAlgorithms
@ -614,8 +621,22 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
func (t *handshakeTransport) server(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) { func (t *handshakeTransport) server(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) {
var hostKey Signer var hostKey Signer
for _, k := range t.hostKeys { for _, k := range t.hostKeys {
if algs.hostKey == k.PublicKey().Type() { kt := k.PublicKey().Type()
if kt == algs.hostKey {
hostKey = k hostKey = k
} else if signer, ok := k.(AlgorithmSigner); ok {
// Some signature algorithms don't show up as key types
// so we have to manually check for a compatible host key.
switch kt {
case KeyAlgoRSA:
if algs.hostKey == SigAlgoRSASHA2256 || algs.hostKey == SigAlgoRSASHA2512 {
hostKey = &rsaSigner{signer, algs.hostKey}
}
case CertAlgoRSAv01:
if algs.hostKey == CertSigAlgoRSASHA2256v01 || algs.hostKey == CertSigAlgoRSASHA2512v01 {
hostKey = &rsaSigner{signer, certToPrivAlgo(algs.hostKey)}
}
}
} }
} }
@ -634,7 +655,7 @@ func (t *handshakeTransport) client(kex kexAlgorithm, algs *algorithms, magics *
return nil, err return nil, err
} }
if err := verifyHostKeySignature(hostKey, result); err != nil { if err := verifyHostKeySignature(hostKey, algs.hostKey, result); err != nil {
return nil, err return nil, err
} }

@ -939,6 +939,15 @@ func newDSAPrivateKey(key *dsa.PrivateKey) (Signer, error) {
return &dsaPrivateKey{key}, nil return &dsaPrivateKey{key}, nil
} }
type rsaSigner struct {
AlgorithmSigner
defaultAlgorithm string
}
func (s *rsaSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
return s.AlgorithmSigner.SignWithAlgorithm(rand, data, s.defaultAlgorithm)
}
type wrappedSigner struct { type wrappedSigner struct {
signer crypto.Signer signer crypto.Signer
pubKey PublicKey pubKey PublicKey

@ -284,7 +284,7 @@ func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error)
func isAcceptableAlgo(algo string) bool { func isAcceptableAlgo(algo string) bool {
switch algo { switch algo {
case KeyAlgoRSA, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoSKECDSA256, KeyAlgoED25519, KeyAlgoSKED25519, case SigAlgoRSA, SigAlgoRSASHA2256, SigAlgoRSASHA2512, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoSKECDSA256, KeyAlgoED25519, KeyAlgoSKED25519,
CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01: CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:
return true return true
} }

@ -0,0 +1,257 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package charset provides common text encodings for HTML documents.
//
// The mapping from encoding labels to encodings is defined at
// https://encoding.spec.whatwg.org/.
package charset // import "golang.org/x/net/html/charset"
import (
"bytes"
"fmt"
"io"
"mime"
"strings"
"unicode/utf8"
"golang.org/x/net/html"
"golang.org/x/text/encoding"
"golang.org/x/text/encoding/charmap"
"golang.org/x/text/encoding/htmlindex"
"golang.org/x/text/transform"
)
// Lookup returns the encoding with the specified label, and its canonical
// name. It returns nil and the empty string if label is not one of the
// standard encodings for HTML. Matching is case-insensitive and ignores
// leading and trailing whitespace. Encoders will use HTML escape sequences for
// runes that are not supported by the character set.
func Lookup(label string) (e encoding.Encoding, name string) {
e, err := htmlindex.Get(label)
if err != nil {
return nil, ""
}
name, _ = htmlindex.Name(e)
return &htmlEncoding{e}, name
}
type htmlEncoding struct{ encoding.Encoding }
func (h *htmlEncoding) NewEncoder() *encoding.Encoder {
// HTML requires a non-terminating legacy encoder. We use HTML escapes to
// substitute unsupported code points.
return encoding.HTMLEscapeUnsupported(h.Encoding.NewEncoder())
}
// DetermineEncoding determines the encoding of an HTML document by examining
// up to the first 1024 bytes of content and the declared Content-Type.
//
// See http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#determining-the-character-encoding
func DetermineEncoding(content []byte, contentType string) (e encoding.Encoding, name string, certain bool) {
if len(content) > 1024 {
content = content[:1024]
}
for _, b := range boms {
if bytes.HasPrefix(content, b.bom) {
e, name = Lookup(b.enc)
return e, name, true
}
}
if _, params, err := mime.ParseMediaType(contentType); err == nil {
if cs, ok := params["charset"]; ok {
if e, name = Lookup(cs); e != nil {
return e, name, true
}
}
}
if len(content) > 0 {
e, name = prescan(content)
if e != nil {
return e, name, false
}
}
// Try to detect UTF-8.
// First eliminate any partial rune at the end.
for i := len(content) - 1; i >= 0 && i > len(content)-4; i-- {
b := content[i]
if b < 0x80 {
break
}
if utf8.RuneStart(b) {
content = content[:i]
break
}
}
hasHighBit := false
for _, c := range content {
if c >= 0x80 {
hasHighBit = true
break
}
}
if hasHighBit && utf8.Valid(content) {
return encoding.Nop, "utf-8", false
}
// TODO: change default depending on user's locale?
return charmap.Windows1252, "windows-1252", false
}
// NewReader returns an io.Reader that converts the content of r to UTF-8.
// It calls DetermineEncoding to find out what r's encoding is.
func NewReader(r io.Reader, contentType string) (io.Reader, error) {
preview := make([]byte, 1024)
n, err := io.ReadFull(r, preview)
switch {
case err == io.ErrUnexpectedEOF:
preview = preview[:n]
r = bytes.NewReader(preview)
case err != nil:
return nil, err
default:
r = io.MultiReader(bytes.NewReader(preview), r)
}
if e, _, _ := DetermineEncoding(preview, contentType); e != encoding.Nop {
r = transform.NewReader(r, e.NewDecoder())
}
return r, nil
}
// NewReaderLabel returns a reader that converts from the specified charset to
// UTF-8. It uses Lookup to find the encoding that corresponds to label, and
// returns an error if Lookup returns nil. It is suitable for use as
// encoding/xml.Decoder's CharsetReader function.
func NewReaderLabel(label string, input io.Reader) (io.Reader, error) {
e, _ := Lookup(label)
if e == nil {
return nil, fmt.Errorf("unsupported charset: %q", label)
}
return transform.NewReader(input, e.NewDecoder()), nil
}
func prescan(content []byte) (e encoding.Encoding, name string) {
z := html.NewTokenizer(bytes.NewReader(content))
for {
switch z.Next() {
case html.ErrorToken:
return nil, ""
case html.StartTagToken, html.SelfClosingTagToken:
tagName, hasAttr := z.TagName()
if !bytes.Equal(tagName, []byte("meta")) {
continue
}
attrList := make(map[string]bool)
gotPragma := false
const (
dontKnow = iota
doNeedPragma
doNotNeedPragma
)
needPragma := dontKnow
name = ""
e = nil
for hasAttr {
var key, val []byte
key, val, hasAttr = z.TagAttr()
ks := string(key)
if attrList[ks] {
continue
}
attrList[ks] = true
for i, c := range val {
if 'A' <= c && c <= 'Z' {
val[i] = c + 0x20
}
}
switch ks {
case "http-equiv":
if bytes.Equal(val, []byte("content-type")) {
gotPragma = true
}
case "content":
if e == nil {
name = fromMetaElement(string(val))
if name != "" {
e, name = Lookup(name)
if e != nil {
needPragma = doNeedPragma
}
}
}
case "charset":
e, name = Lookup(string(val))
needPragma = doNotNeedPragma
}
}
if needPragma == dontKnow || needPragma == doNeedPragma && !gotPragma {
continue
}
if strings.HasPrefix(name, "utf-16") {
name = "utf-8"
e = encoding.Nop
}
if e != nil {
return e, name
}
}
}
}
func fromMetaElement(s string) string {
for s != "" {
csLoc := strings.Index(s, "charset")
if csLoc == -1 {
return ""
}
s = s[csLoc+len("charset"):]
s = strings.TrimLeft(s, " \t\n\f\r")
if !strings.HasPrefix(s, "=") {
continue
}
s = s[1:]
s = strings.TrimLeft(s, " \t\n\f\r")
if s == "" {
return ""
}
if q := s[0]; q == '"' || q == '\'' {
s = s[1:]
closeQuote := strings.IndexRune(s, rune(q))
if closeQuote == -1 {
return ""
}
return s[:closeQuote]
}
end := strings.IndexAny(s, "; \t\n\f\r")
if end == -1 {
end = len(s)
}
return s[:end]
}
return ""
}
var boms = []struct {
bom []byte
enc string
}{
{[]byte{0xfe, 0xff}, "utf-16be"},
{[]byte{0xff, 0xfe}, "utf-16le"},
{[]byte{0xef, 0xbb, 0xbf}, "utf-8"},
}

@ -663,6 +663,24 @@ func inHeadIM(p *parser) bool {
// Ignore the token. // Ignore the token.
return true return true
case a.Template: case a.Template:
// TODO: remove this divergence from the HTML5 spec.
//
// We don't handle all of the corner cases when mixing foreign
// content (i.e. <math> or <svg>) with <template>. Without this
// early return, we can get into an infinite loop, possibly because
// of the "TODO... further divergence" a little below.
//
// As a workaround, if we are mixing foreign content and templates,
// just ignore the rest of the HTML. Foreign content is rare and a
// relatively old HTML feature. Templates are also rare and a
// relatively new HTML feature. Their combination is very rare.
for _, e := range p.oe {
if e.Namespace != "" {
p.im = ignoreTheRemainingTokens
return true
}
}
p.addElement() p.addElement()
p.afe = append(p.afe, &scopeMarker) p.afe = append(p.afe, &scopeMarker)
p.framesetOK = false p.framesetOK = false
@ -683,7 +701,7 @@ func inHeadIM(p *parser) bool {
if !p.oe.contains(a.Template) { if !p.oe.contains(a.Template) {
return true return true
} }
// TODO: remove this divergence from the HTML5 spec. // TODO: remove this further divergence from the HTML5 spec.
// //
// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668 // See https://bugs.chromium.org/p/chromium/issues/detail?id=829668
p.generateImpliedEndTags() p.generateImpliedEndTags()
@ -2127,6 +2145,10 @@ func afterAfterFramesetIM(p *parser) bool {
return true return true
} }
func ignoreTheRemainingTokens(p *parser) bool {
return true
}
const whitespaceOrNUL = whitespace + "\x00" const whitespaceOrNUL = whitespace + "\x00"
// Section 12.2.6.5 // Section 12.2.6.5

@ -56,6 +56,7 @@ var X86 struct {
HasAVX512BF16 bool // Advanced vector extension 512 BFloat16 Instructions HasAVX512BF16 bool // Advanced vector extension 512 BFloat16 Instructions
HasBMI1 bool // Bit manipulation instruction set 1 HasBMI1 bool // Bit manipulation instruction set 1
HasBMI2 bool // Bit manipulation instruction set 2 HasBMI2 bool // Bit manipulation instruction set 2
HasCX16 bool // Compare and exchange 16 Bytes
HasERMS bool // Enhanced REP for MOVSB and STOSB HasERMS bool // Enhanced REP for MOVSB and STOSB
HasFMA bool // Fused-multiply-add instructions HasFMA bool // Fused-multiply-add instructions
HasOSXSAVE bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers. HasOSXSAVE bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers.

@ -39,6 +39,7 @@ func initOptions() {
{Name: "avx512bf16", Feature: &X86.HasAVX512BF16}, {Name: "avx512bf16", Feature: &X86.HasAVX512BF16},
{Name: "bmi1", Feature: &X86.HasBMI1}, {Name: "bmi1", Feature: &X86.HasBMI1},
{Name: "bmi2", Feature: &X86.HasBMI2}, {Name: "bmi2", Feature: &X86.HasBMI2},
{Name: "cx16", Feature: &X86.HasCX16},
{Name: "erms", Feature: &X86.HasERMS}, {Name: "erms", Feature: &X86.HasERMS},
{Name: "fma", Feature: &X86.HasFMA}, {Name: "fma", Feature: &X86.HasFMA},
{Name: "osxsave", Feature: &X86.HasOSXSAVE}, {Name: "osxsave", Feature: &X86.HasOSXSAVE},
@ -73,6 +74,7 @@ func archInit() {
X86.HasPCLMULQDQ = isSet(1, ecx1) X86.HasPCLMULQDQ = isSet(1, ecx1)
X86.HasSSSE3 = isSet(9, ecx1) X86.HasSSSE3 = isSet(9, ecx1)
X86.HasFMA = isSet(12, ecx1) X86.HasFMA = isSet(12, ecx1)
X86.HasCX16 = isSet(13, ecx1)
X86.HasSSE41 = isSet(19, ecx1) X86.HasSSE41 = isSet(19, ecx1)
X86.HasSSE42 = isSet(20, ecx1) X86.HasSSE42 = isSet(20, ecx1)
X86.HasPOPCNT = isSet(23, ecx1) X86.HasPOPCNT = isSet(23, ecx1)
@ -88,9 +90,10 @@ func archInit() {
osSupportsAVX = isSet(1, eax) && isSet(2, eax) osSupportsAVX = isSet(1, eax) && isSet(2, eax)
if runtime.GOOS == "darwin" { if runtime.GOOS == "darwin" {
// Check darwin commpage for AVX512 support. Necessary because: // Darwin doesn't save/restore AVX-512 mask registers correctly across signal handlers.
// https://github.com/apple/darwin-xnu/blob/0a798f6738bc1db01281fc08ae024145e84df927/osfmk/i386/fpu.c#L175-L201 // Since users can't rely on mask register contents, let's not advertise AVX-512 support.
osSupportsAVX512 = osSupportsAVX && darwinSupportsAVX512() // See issue 49233.
osSupportsAVX512 = false
} else { } else {
// Check if OPMASK and ZMM registers have OS support. // Check if OPMASK and ZMM registers have OS support.
osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && isSet(6, eax) && isSet(7, eax) osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && isSet(6, eax) && isSet(7, eax)

@ -26,27 +26,3 @@ TEXT ·xgetbv(SB),NOSPLIT,$0-8
MOVL AX, eax+0(FP) MOVL AX, eax+0(FP)
MOVL DX, edx+4(FP) MOVL DX, edx+4(FP)
RET RET
// func darwinSupportsAVX512() bool
TEXT ·darwinSupportsAVX512(SB), NOSPLIT, $0-1
MOVB $0, ret+0(FP) // default to false
#ifdef GOOS_darwin // return if not darwin
#ifdef GOARCH_amd64 // return if not amd64
// These values from:
// https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/osfmk/i386/cpu_capabilities.h
#define commpage64_base_address 0x00007fffffe00000
#define commpage64_cpu_capabilities64 (commpage64_base_address+0x010)
#define commpage64_version (commpage64_base_address+0x01E)
#define hasAVX512F 0x0000004000000000
MOVQ $commpage64_version, BX
CMPW (BX), $13 // cpu_capabilities64 undefined in versions < 13
JL no_avx512
MOVQ $commpage64_cpu_capabilities64, BX
MOVQ $hasAVX512F, CX
TESTQ (BX), CX
JZ no_avx512
MOVB $1, ret+0(FP)
no_avx512:
#endif
#endif
RET

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build go1.5
// +build go1.5 // +build go1.5
package plan9 package plan9

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !go1.5
// +build !go1.5 // +build !go1.5
package plan9 package plan9

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build plan9 && race
// +build plan9,race // +build plan9,race
package plan9 package plan9

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build plan9 && !race
// +build plan9,!race // +build plan9,!race
package plan9 package plan9

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build plan9
// +build plan9 // +build plan9
package plan9 package plan9

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build plan9
// +build plan9 // +build plan9
// Package plan9 contains an interface to the low-level operating system // Package plan9 contains an interface to the low-level operating system

@ -1,6 +1,7 @@
// go run mksyscall.go -l32 -plan9 -tags plan9,386 syscall_plan9.go // go run mksyscall.go -l32 -plan9 -tags plan9,386 syscall_plan9.go
// Code generated by the command above; see README.md. DO NOT EDIT. // Code generated by the command above; see README.md. DO NOT EDIT.
//go:build plan9 && 386
// +build plan9,386 // +build plan9,386
package plan9 package plan9

@ -1,6 +1,7 @@
// go run mksyscall.go -l32 -plan9 -tags plan9,amd64 syscall_plan9.go // go run mksyscall.go -l32 -plan9 -tags plan9,amd64 syscall_plan9.go
// Code generated by the command above; see README.md. DO NOT EDIT. // Code generated by the command above; see README.md. DO NOT EDIT.
//go:build plan9 && amd64
// +build plan9,amd64 // +build plan9,amd64
package plan9 package plan9

@ -1,6 +1,7 @@
// go run mksyscall.go -l32 -plan9 -tags plan9,arm syscall_plan9.go // go run mksyscall.go -l32 -plan9 -tags plan9,arm syscall_plan9.go
// Code generated by the command above; see README.md. DO NOT EDIT. // Code generated by the command above; see README.md. DO NOT EDIT.
//go:build plan9 && arm
// +build plan9,arm // +build plan9,arm
package plan9 package plan9

@ -149,7 +149,7 @@ To add a constant, add the header that includes it to the appropriate variable.
Then, edit the regex (if necessary) to match the desired constant. Avoid making Then, edit the regex (if necessary) to match the desired constant. Avoid making
the regex too broad to avoid matching unintended constants. the regex too broad to avoid matching unintended constants.
### mkmerge.go ### internal/mkmerge
This program is used to extract duplicate const, func, and type declarations This program is used to extract duplicate const, func, and type declarations
from the generated architecture-specific files listed below, and merge these from the generated architecture-specific files listed below, and merge these

@ -0,0 +1,149 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build linux
// +build linux
package unix
import (
"bytes"
"unsafe"
)
// Helpers for dealing with ifreq since it contains a union and thus requires a
// lot of unsafe.Pointer casts to use properly.
// An Ifreq is a type-safe wrapper around the raw ifreq struct. An Ifreq
// contains an interface name and a union of arbitrary data which can be
// accessed using the Ifreq's methods. To create an Ifreq, use the NewIfreq
// function.
//
// Use the Name method to access the stored interface name. The union data
// fields can be get and set using the following methods:
// - Uint16/SetUint16: flags
// - Uint32/SetUint32: ifindex, metric, mtu
type Ifreq struct{ raw ifreq }
// NewIfreq creates an Ifreq with the input network interface name after
// validating the name does not exceed IFNAMSIZ-1 (trailing NULL required)
// bytes.
func NewIfreq(name string) (*Ifreq, error) {
// Leave room for terminating NULL byte.
if len(name) >= IFNAMSIZ {
return nil, EINVAL
}
var ifr ifreq
copy(ifr.Ifrn[:], name)
return &Ifreq{raw: ifr}, nil
}
// TODO(mdlayher): get/set methods for hardware address sockaddr, char array, etc.
// Name returns the interface name associated with the Ifreq.
func (ifr *Ifreq) Name() string {
// BytePtrToString requires a NULL terminator or the program may crash. If
// one is not present, just return the empty string.
if !bytes.Contains(ifr.raw.Ifrn[:], []byte{0x00}) {
return ""
}
return BytePtrToString(&ifr.raw.Ifrn[0])
}
// According to netdevice(7), only AF_INET addresses are returned for numerous
// sockaddr ioctls. For convenience, we expose these as Inet4Addr since the Port
// field and other data is always empty.
// Inet4Addr returns the Ifreq union data from an embedded sockaddr as a C
// in_addr/Go []byte (4-byte IPv4 address) value. If the sockaddr family is not
// AF_INET, an error is returned.
func (ifr *Ifreq) Inet4Addr() ([]byte, error) {
raw := *(*RawSockaddrInet4)(unsafe.Pointer(&ifr.raw.Ifru[:SizeofSockaddrInet4][0]))
if raw.Family != AF_INET {
// Cannot safely interpret raw.Addr bytes as an IPv4 address.
return nil, EINVAL
}
return raw.Addr[:], nil
}
// SetInet4Addr sets a C in_addr/Go []byte (4-byte IPv4 address) value in an
// embedded sockaddr within the Ifreq's union data. v must be 4 bytes in length
// or an error will be returned.
func (ifr *Ifreq) SetInet4Addr(v []byte) error {
if len(v) != 4 {
return EINVAL
}
var addr [4]byte
copy(addr[:], v)
ifr.clear()
*(*RawSockaddrInet4)(
unsafe.Pointer(&ifr.raw.Ifru[:SizeofSockaddrInet4][0]),
) = RawSockaddrInet4{
// Always set IP family as ioctls would require it anyway.
Family: AF_INET,
Addr: addr,
}
return nil
}
// Uint16 returns the Ifreq union data as a C short/Go uint16 value.
func (ifr *Ifreq) Uint16() uint16 {
return *(*uint16)(unsafe.Pointer(&ifr.raw.Ifru[:2][0]))
}
// SetUint16 sets a C short/Go uint16 value as the Ifreq's union data.
func (ifr *Ifreq) SetUint16(v uint16) {
ifr.clear()
*(*uint16)(unsafe.Pointer(&ifr.raw.Ifru[:2][0])) = v
}
// Uint32 returns the Ifreq union data as a C int/Go uint32 value.
func (ifr *Ifreq) Uint32() uint32 {
return *(*uint32)(unsafe.Pointer(&ifr.raw.Ifru[:4][0]))
}
// SetUint32 sets a C int/Go uint32 value as the Ifreq's union data.
func (ifr *Ifreq) SetUint32(v uint32) {
ifr.clear()
*(*uint32)(unsafe.Pointer(&ifr.raw.Ifru[:4][0])) = v
}
// clear zeroes the ifreq's union field to prevent trailing garbage data from
// being sent to the kernel if an ifreq is reused.
func (ifr *Ifreq) clear() {
for i := range ifr.raw.Ifru {
ifr.raw.Ifru[i] = 0
}
}
// TODO(mdlayher): export as IfreqData? For now we can provide helpers such as
// IoctlGetEthtoolDrvinfo which use these APIs under the hood.
// An ifreqData is an Ifreq which carries pointer data. To produce an ifreqData,
// use the Ifreq.withData method.
type ifreqData struct {
name [IFNAMSIZ]byte
// A type separate from ifreq is required in order to comply with the
// unsafe.Pointer rules since the "pointer-ness" of data would not be
// preserved if it were cast into the byte array of a raw ifreq.
data unsafe.Pointer
// Pad to the same size as ifreq.
_ [len(ifreq{}.Ifru) - SizeofPtr]byte
}
// withData produces an ifreqData with the pointer p set for ioctls which require
// arbitrary pointer data.
func (ifr Ifreq) withData(p unsafe.Pointer) ifreqData {
return ifreqData{
name: ifr.raw.Ifrn,
data: p,
}
}

@ -5,7 +5,6 @@
package unix package unix
import ( import (
"runtime"
"unsafe" "unsafe"
) )
@ -22,56 +21,42 @@ func IoctlRetInt(fd int, req uint) (int, error) {
func IoctlGetUint32(fd int, req uint) (uint32, error) { func IoctlGetUint32(fd int, req uint) (uint32, error) {
var value uint32 var value uint32
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) err := ioctlPtr(fd, req, unsafe.Pointer(&value))
return value, err return value, err
} }
func IoctlGetRTCTime(fd int) (*RTCTime, error) { func IoctlGetRTCTime(fd int) (*RTCTime, error) {
var value RTCTime var value RTCTime
err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value))) err := ioctlPtr(fd, RTC_RD_TIME, unsafe.Pointer(&value))
return &value, err return &value, err
} }
func IoctlSetRTCTime(fd int, value *RTCTime) error { func IoctlSetRTCTime(fd int, value *RTCTime) error {
err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value))) return ioctlPtr(fd, RTC_SET_TIME, unsafe.Pointer(value))
runtime.KeepAlive(value)
return err
} }
func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) { func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) {
var value RTCWkAlrm var value RTCWkAlrm
err := ioctl(fd, RTC_WKALM_RD, uintptr(unsafe.Pointer(&value))) err := ioctlPtr(fd, RTC_WKALM_RD, unsafe.Pointer(&value))
return &value, err return &value, err
} }
func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error { func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error {
err := ioctl(fd, RTC_WKALM_SET, uintptr(unsafe.Pointer(value))) return ioctlPtr(fd, RTC_WKALM_SET, unsafe.Pointer(value))
runtime.KeepAlive(value)
return err
}
type ifreqEthtool struct {
name [IFNAMSIZ]byte
data unsafe.Pointer
} }
// IoctlGetEthtoolDrvinfo fetches ethtool driver information for the network // IoctlGetEthtoolDrvinfo fetches ethtool driver information for the network
// device specified by ifname. // device specified by ifname.
func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) { func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) {
// Leave room for terminating NULL byte. ifr, err := NewIfreq(ifname)
if len(ifname) >= IFNAMSIZ { if err != nil {
return nil, EINVAL return nil, err
} }
value := EthtoolDrvinfo{ value := EthtoolDrvinfo{Cmd: ETHTOOL_GDRVINFO}
Cmd: ETHTOOL_GDRVINFO, ifrd := ifr.withData(unsafe.Pointer(&value))
}
ifreq := ifreqEthtool{ err = ioctlIfreqData(fd, SIOCETHTOOL, &ifrd)
data: unsafe.Pointer(&value),
}
copy(ifreq.name[:], ifname)
err := ioctl(fd, SIOCETHTOOL, uintptr(unsafe.Pointer(&ifreq)))
runtime.KeepAlive(ifreq)
return &value, err return &value, err
} }
@ -80,7 +65,7 @@ func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) {
// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html. // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) { func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) {
var value WatchdogInfo var value WatchdogInfo
err := ioctl(fd, WDIOC_GETSUPPORT, uintptr(unsafe.Pointer(&value))) err := ioctlPtr(fd, WDIOC_GETSUPPORT, unsafe.Pointer(&value))
return &value, err return &value, err
} }
@ -88,6 +73,7 @@ func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) {
// more information, see: // more information, see:
// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html. // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
func IoctlWatchdogKeepalive(fd int) error { func IoctlWatchdogKeepalive(fd int) error {
// arg is ignored and not a pointer, so ioctl is fine instead of ioctlPtr.
return ioctl(fd, WDIOC_KEEPALIVE, 0) return ioctl(fd, WDIOC_KEEPALIVE, 0)
} }
@ -95,9 +81,7 @@ func IoctlWatchdogKeepalive(fd int) error {
// range of data conveyed in value to the file associated with the file // range of data conveyed in value to the file associated with the file
// descriptor destFd. See the ioctl_ficlonerange(2) man page for details. // descriptor destFd. See the ioctl_ficlonerange(2) man page for details.
func IoctlFileCloneRange(destFd int, value *FileCloneRange) error { func IoctlFileCloneRange(destFd int, value *FileCloneRange) error {
err := ioctl(destFd, FICLONERANGE, uintptr(unsafe.Pointer(value))) return ioctlPtr(destFd, FICLONERANGE, unsafe.Pointer(value))
runtime.KeepAlive(value)
return err
} }
// IoctlFileClone performs an FICLONE ioctl operation to clone the entire file // IoctlFileClone performs an FICLONE ioctl operation to clone the entire file
@ -148,7 +132,7 @@ func IoctlFileDedupeRange(srcFd int, value *FileDedupeRange) error {
rawinfo.Reserved = value.Info[i].Reserved rawinfo.Reserved = value.Info[i].Reserved
} }
err := ioctl(srcFd, FIDEDUPERANGE, uintptr(unsafe.Pointer(&buf[0]))) err := ioctlPtr(srcFd, FIDEDUPERANGE, unsafe.Pointer(&buf[0]))
// Output // Output
for i := range value.Info { for i := range value.Info {
@ -166,31 +150,47 @@ func IoctlFileDedupeRange(srcFd int, value *FileDedupeRange) error {
} }
func IoctlHIDGetDesc(fd int, value *HIDRawReportDescriptor) error { func IoctlHIDGetDesc(fd int, value *HIDRawReportDescriptor) error {
err := ioctl(fd, HIDIOCGRDESC, uintptr(unsafe.Pointer(value))) return ioctlPtr(fd, HIDIOCGRDESC, unsafe.Pointer(value))
runtime.KeepAlive(value)
return err
} }
func IoctlHIDGetRawInfo(fd int) (*HIDRawDevInfo, error) { func IoctlHIDGetRawInfo(fd int) (*HIDRawDevInfo, error) {
var value HIDRawDevInfo var value HIDRawDevInfo
err := ioctl(fd, HIDIOCGRAWINFO, uintptr(unsafe.Pointer(&value))) err := ioctlPtr(fd, HIDIOCGRAWINFO, unsafe.Pointer(&value))
return &value, err return &value, err
} }
func IoctlHIDGetRawName(fd int) (string, error) { func IoctlHIDGetRawName(fd int) (string, error) {
var value [_HIDIOCGRAWNAME_LEN]byte var value [_HIDIOCGRAWNAME_LEN]byte
err := ioctl(fd, _HIDIOCGRAWNAME, uintptr(unsafe.Pointer(&value[0]))) err := ioctlPtr(fd, _HIDIOCGRAWNAME, unsafe.Pointer(&value[0]))
return ByteSliceToString(value[:]), err return ByteSliceToString(value[:]), err
} }
func IoctlHIDGetRawPhys(fd int) (string, error) { func IoctlHIDGetRawPhys(fd int) (string, error) {
var value [_HIDIOCGRAWPHYS_LEN]byte var value [_HIDIOCGRAWPHYS_LEN]byte
err := ioctl(fd, _HIDIOCGRAWPHYS, uintptr(unsafe.Pointer(&value[0]))) err := ioctlPtr(fd, _HIDIOCGRAWPHYS, unsafe.Pointer(&value[0]))
return ByteSliceToString(value[:]), err return ByteSliceToString(value[:]), err
} }
func IoctlHIDGetRawUniq(fd int) (string, error) { func IoctlHIDGetRawUniq(fd int) (string, error) {
var value [_HIDIOCGRAWUNIQ_LEN]byte var value [_HIDIOCGRAWUNIQ_LEN]byte
err := ioctl(fd, _HIDIOCGRAWUNIQ, uintptr(unsafe.Pointer(&value[0]))) err := ioctlPtr(fd, _HIDIOCGRAWUNIQ, unsafe.Pointer(&value[0]))
return ByteSliceToString(value[:]), err return ByteSliceToString(value[:]), err
} }
// IoctlIfreq performs an ioctl using an Ifreq structure for input and/or
// output. See the netdevice(7) man page for details.
func IoctlIfreq(fd int, req uint, value *Ifreq) error {
// It is possible we will add more fields to *Ifreq itself later to prevent
// misuse, so pass the raw *ifreq directly.
return ioctlPtr(fd, req, unsafe.Pointer(&value.raw))
}
// TODO(mdlayher): export if and when IfreqData is exported.
// ioctlIfreqData performs an ioctl using an ifreqData structure for input
// and/or output. See the netdevice(7) man page for details.
func ioctlIfreqData(fd int, req uint, value *ifreqData) error {
// The memory layout of IfreqData (type-safe) and ifreq (not type-safe) are
// identical so pass *IfreqData directly.
return ioctlPtr(fd, req, unsafe.Pointer(value))
}

@ -50,7 +50,7 @@ if [[ "$GOOS" = "linux" ]]; then
# Use the Docker-based build system # Use the Docker-based build system
# Files generated through docker (use $cmd so you can Ctl-C the build or run) # Files generated through docker (use $cmd so you can Ctl-C the build or run)
$cmd docker build --tag generate:$GOOS $GOOS $cmd docker build --tag generate:$GOOS $GOOS
$cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")" && /bin/pwd):/build generate:$GOOS $cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")/.." && /bin/pwd):/build generate:$GOOS
exit exit
fi fi

@ -54,7 +54,7 @@ includes_AIX='
includes_Darwin=' includes_Darwin='
#define _DARWIN_C_SOURCE #define _DARWIN_C_SOURCE
#define KERNEL #define KERNEL 1
#define _DARWIN_USE_64_BIT_INODE #define _DARWIN_USE_64_BIT_INODE
#define __APPLE_USE_RFC_3542 #define __APPLE_USE_RFC_3542
#include <stdint.h> #include <stdint.h>
@ -75,6 +75,7 @@ includes_Darwin='
#include <sys/utsname.h> #include <sys/utsname.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/xattr.h> #include <sys/xattr.h>
#include <sys/vsock.h>
#include <net/bpf.h> #include <net/bpf.h>
#include <net/if.h> #include <net/if.h>
#include <net/if_types.h> #include <net/if_types.h>
@ -82,6 +83,9 @@ includes_Darwin='
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <termios.h> #include <termios.h>
// for backwards compatibility because moved TIOCREMOTE to Kernel.framework after MacOSX12.0.sdk.
#define TIOCREMOTE 0x80047469
' '
includes_DragonFly=' includes_DragonFly='
@ -217,8 +221,6 @@ struct ltchars {
#include <linux/genetlink.h> #include <linux/genetlink.h>
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/hidraw.h> #include <linux/hidraw.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
#include <linux/if.h> #include <linux/if.h>
#include <linux/if_addr.h> #include <linux/if_addr.h>
#include <linux/if_alg.h> #include <linux/if_alg.h>
@ -231,11 +233,13 @@ struct ltchars {
#include <linux/input.h> #include <linux/input.h>
#include <linux/kexec.h> #include <linux/kexec.h>
#include <linux/keyctl.h> #include <linux/keyctl.h>
#include <linux/landlock.h>
#include <linux/loop.h> #include <linux/loop.h>
#include <linux/lwtunnel.h> #include <linux/lwtunnel.h>
#include <linux/magic.h> #include <linux/magic.h>
#include <linux/memfd.h> #include <linux/memfd.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mount.h>
#include <linux/netfilter/nfnetlink.h> #include <linux/netfilter/nfnetlink.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/net_namespace.h> #include <linux/net_namespace.h>
@ -467,7 +471,6 @@ ccflags="$@"
$2 !~ /^EQUIV_/ && $2 !~ /^EQUIV_/ &&
$2 !~ /^EXPR_/ && $2 !~ /^EXPR_/ &&
$2 !~ /^EVIOC/ && $2 !~ /^EVIOC/ &&
$2 !~ /^EV_/ &&
$2 ~ /^E[A-Z0-9_]+$/ || $2 ~ /^E[A-Z0-9_]+$/ ||
$2 ~ /^B[0-9_]+$/ || $2 ~ /^B[0-9_]+$/ ||
$2 ~ /^(OLD|NEW)DEV$/ || $2 ~ /^(OLD|NEW)DEV$/ ||
@ -499,10 +502,11 @@ ccflags="$@"
$2 ~ /^O?XTABS$/ || $2 ~ /^O?XTABS$/ ||
$2 ~ /^TC[IO](ON|OFF)$/ || $2 ~ /^TC[IO](ON|OFF)$/ ||
$2 ~ /^IN_/ || $2 ~ /^IN_/ ||
$2 ~ /^LANDLOCK_/ ||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ || $2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ || $2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ || $2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL)_/ || $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT)_/ ||
$2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ || $2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ ||
$2 ~ /^NFC_.*_(MAX)?SIZE$/ || $2 ~ /^NFC_.*_(MAX)?SIZE$/ ||
$2 ~ /^RAW_PAYLOAD_/ || $2 ~ /^RAW_PAYLOAD_/ ||
@ -517,7 +521,7 @@ ccflags="$@"
$2 ~ /^HW_MACHINE$/ || $2 ~ /^HW_MACHINE$/ ||
$2 ~ /^SYSCTL_VERS/ || $2 ~ /^SYSCTL_VERS/ ||
$2 !~ "MNT_BITS" && $2 !~ "MNT_BITS" &&
$2 ~ /^(MS|MNT|UMOUNT)_/ || $2 ~ /^(MS|MNT|MOUNT|UMOUNT)_/ ||
$2 ~ /^NS_GET_/ || $2 ~ /^NS_GET_/ ||
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ || $2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|TFD)_/ || $2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|TFD)_/ ||

@ -34,3 +34,52 @@ func ParseUnixCredentials(m *SocketControlMessage) (*Ucred, error) {
ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0])) ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
return &ucred, nil return &ucred, nil
} }
// PktInfo4 encodes Inet4Pktinfo into a socket control message of type IP_PKTINFO.
func PktInfo4(info *Inet4Pktinfo) []byte {
b := make([]byte, CmsgSpace(SizeofInet4Pktinfo))
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
h.Level = SOL_IP
h.Type = IP_PKTINFO
h.SetLen(CmsgLen(SizeofInet4Pktinfo))
*(*Inet4Pktinfo)(h.data(0)) = *info
return b
}
// PktInfo6 encodes Inet6Pktinfo into a socket control message of type IPV6_PKTINFO.
func PktInfo6(info *Inet6Pktinfo) []byte {
b := make([]byte, CmsgSpace(SizeofInet6Pktinfo))
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
h.Level = SOL_IPV6
h.Type = IPV6_PKTINFO
h.SetLen(CmsgLen(SizeofInet6Pktinfo))
*(*Inet6Pktinfo)(h.data(0)) = *info
return b
}
// ParseOrigDstAddr decodes a socket control message containing the original
// destination address. To receive such a message the IP_RECVORIGDSTADDR or
// IPV6_RECVORIGDSTADDR option must be enabled on the socket.
func ParseOrigDstAddr(m *SocketControlMessage) (Sockaddr, error) {
switch {
case m.Header.Level == SOL_IP && m.Header.Type == IP_ORIGDSTADDR:
pp := (*RawSockaddrInet4)(unsafe.Pointer(&m.Data[0]))
sa := new(SockaddrInet4)
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1])
sa.Addr = pp.Addr
return sa, nil
case m.Header.Level == SOL_IPV6 && m.Header.Type == IPV6_ORIGDSTADDR:
pp := (*RawSockaddrInet6)(unsafe.Pointer(&m.Data[0]))
sa := new(SockaddrInet6)
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1])
sa.ZoneId = pp.Scope_id
sa.Addr = pp.Addr
return sa, nil
default:
return nil, EINVAL
}
}

@ -70,9 +70,7 @@ func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
p[0] = byte(sa.Port >> 8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
} }
@ -85,9 +83,7 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
p[0] = byte(sa.Port >> 8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
sa.raw.Scope_id = sa.ZoneId sa.raw.Scope_id = sa.ZoneId
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
} }
@ -261,9 +257,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
sa := new(SockaddrInet4) sa := new(SockaddrInet4)
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1]) sa.Port = int(p[0])<<8 + int(p[1])
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
case AF_INET6: case AF_INET6:
@ -272,9 +266,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1]) sa.Port = int(p[0])<<8 + int(p[1])
sa.ZoneId = pp.Scope_id sa.ZoneId = pp.Scope_id
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
} }
return nil, EAFNOSUPPORT return nil, EAFNOSUPPORT
@ -385,6 +377,11 @@ func (w WaitStatus) TrapCause() int { return -1 }
//sys fcntl(fd int, cmd int, arg int) (val int, err error) //sys fcntl(fd int, cmd int, arg int) (val int, err error)
//sys fsyncRange(fd int, how int, start int64, length int64) (err error) = fsync_range
func Fsync(fd int) error {
return fsyncRange(fd, O_SYNC, 0, 0)
}
/* /*
* Direct access * Direct access
*/ */
@ -401,7 +398,6 @@ func (w WaitStatus) TrapCause() int { return -1 }
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//sys Fdatasync(fd int) (err error) //sys Fdatasync(fd int) (err error)
//sys Fsync(fd int) (err error)
// readdir_r // readdir_r
//sysnb Getpgid(pid int) (pgid int, err error) //sysnb Getpgid(pid int) (pgid int, err error)

@ -163,9 +163,7 @@ func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
p[0] = byte(sa.Port >> 8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
} }
@ -179,9 +177,7 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
p[0] = byte(sa.Port >> 8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
sa.raw.Scope_id = sa.ZoneId sa.raw.Scope_id = sa.ZoneId
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
} }
@ -210,9 +206,7 @@ func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Nlen = sa.Nlen sa.raw.Nlen = sa.Nlen
sa.raw.Alen = sa.Alen sa.raw.Alen = sa.Alen
sa.raw.Slen = sa.Slen sa.raw.Slen = sa.Slen
for i := 0; i < len(sa.raw.Data); i++ { sa.raw.Data = sa.Data
sa.raw.Data[i] = sa.Data[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
} }
@ -228,9 +222,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
sa.Nlen = pp.Nlen sa.Nlen = pp.Nlen
sa.Alen = pp.Alen sa.Alen = pp.Alen
sa.Slen = pp.Slen sa.Slen = pp.Slen
for i := 0; i < len(sa.Data); i++ { sa.Data = pp.Data
sa.Data[i] = pp.Data[i]
}
return sa, nil return sa, nil
case AF_UNIX: case AF_UNIX:
@ -262,9 +254,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
sa := new(SockaddrInet4) sa := new(SockaddrInet4)
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1]) sa.Port = int(p[0])<<8 + int(p[1])
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
case AF_INET6: case AF_INET6:
@ -273,9 +263,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1]) sa.Port = int(p[0])<<8 + int(p[1])
sa.ZoneId = pp.Scope_id sa.ZoneId = pp.Scope_id
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
} }
return anyToSockaddrGOOS(fd, rsa) return anyToSockaddrGOOS(fd, rsa)

@ -48,6 +48,30 @@ func (sa *SockaddrCtl) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrCtl, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrCtl, nil
} }
// SockaddrVM implements the Sockaddr interface for AF_VSOCK type sockets.
// SockaddrVM provides access to Darwin VM sockets: a mechanism that enables
// bidirectional communication between a hypervisor and its guest virtual
// machines.
type SockaddrVM struct {
// CID and Port specify a context ID and port address for a VM socket.
// Guests have a unique CID, and hosts may have a well-known CID of:
// - VMADDR_CID_HYPERVISOR: refers to the hypervisor process.
// - VMADDR_CID_LOCAL: refers to local communication (loopback).
// - VMADDR_CID_HOST: refers to other processes on the host.
CID uint32
Port uint32
raw RawSockaddrVM
}
func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Len = SizeofSockaddrVM
sa.raw.Family = AF_VSOCK
sa.raw.Port = sa.Port
sa.raw.Cid = sa.CID
return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
}
func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family { switch rsa.Addr.Family {
case AF_SYSTEM: case AF_SYSTEM:
@ -58,6 +82,13 @@ func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
sa.Unit = pp.Sc_unit sa.Unit = pp.Sc_unit
return sa, nil return sa, nil
} }
case AF_VSOCK:
pp := (*RawSockaddrVM)(unsafe.Pointer(rsa))
sa := &SockaddrVM{
CID: pp.Cid,
Port: pp.Port,
}
return sa, nil
} }
return nil, EAFNOSUPPORT return nil, EAFNOSUPPORT
} }
@ -399,8 +430,25 @@ func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
return x, err return x, err
} }
func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) { func SysctlKinfoProc(name string, args ...int) (*KinfoProc, error) {
mib, err := sysctlmib(name) mib, err := sysctlmib(name, args...)
if err != nil {
return nil, err
}
var kinfo KinfoProc
n := uintptr(SizeofKinfoProc)
if err := sysctl(mib, (*byte)(unsafe.Pointer(&kinfo)), &n, nil, 0); err != nil {
return nil, err
}
if n != SizeofKinfoProc {
return nil, EIO
}
return &kinfo, nil
}
func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
mib, err := sysctlmib(name, args...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -433,6 +481,11 @@ func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) //sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
//sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error)
//sys shmdt(addr uintptr) (err error)
//sys shmget(key int, size int, flag int) (id int, err error)
/* /*
* Exposed directly * Exposed directly
*/ */
@ -590,10 +643,6 @@ func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
// Msgget // Msgget
// Msgsnd // Msgsnd
// Msgrcv // Msgrcv
// Shmat
// Shmctl
// Shmdt
// Shmget
// Shm_open // Shm_open
// Shm_unlink // Shm_unlink
// Sem_open // Sem_open

@ -162,6 +162,14 @@ func (l *Lifreq) GetLifruInt() int {
return *(*int)(unsafe.Pointer(&l.Lifru[0])) return *(*int)(unsafe.Pointer(&l.Lifru[0]))
} }
func (l *Lifreq) SetLifruUint(d uint) {
*(*uint)(unsafe.Pointer(&l.Lifru[0])) = d
}
func (l *Lifreq) GetLifruUint() uint {
return *(*uint)(unsafe.Pointer(&l.Lifru[0]))
}
func IoctlLifreq(fd int, req uint, l *Lifreq) error { func IoctlLifreq(fd int, req uint, l *Lifreq) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(l))) return ioctl(fd, req, uintptr(unsafe.Pointer(l)))
} }

@ -13,7 +13,6 @@ package unix
import ( import (
"encoding/binary" "encoding/binary"
"runtime"
"syscall" "syscall"
"unsafe" "unsafe"
) )
@ -38,6 +37,13 @@ func Creat(path string, mode uint32) (fd int, err error) {
return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
} }
func EpollCreate(size int) (fd int, err error) {
if size <= 0 {
return -1, EINVAL
}
return EpollCreate1(0)
}
//sys FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) //sys FanotifyInit(flags uint, event_f_flags uint) (fd int, err error)
//sys fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) //sys fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error)
@ -66,11 +72,22 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
return fchmodat(dirfd, path, mode) return fchmodat(dirfd, path, mode)
} }
//sys ioctl(fd int, req uint, arg uintptr) (err error) func InotifyInit() (fd int, err error) {
return InotifyInit1(0)
}
//sys ioctl(fd int, req uint, arg uintptr) (err error) = SYS_IOCTL
//sys ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL
// ioctl itself should not be exposed directly, but additional get/set // ioctl itself should not be exposed directly, but additional get/set functions
// functions for specific types are permissible. // for specific types are permissible. These are defined in ioctl.go and
// These are defined in ioctl.go and ioctl_linux.go. // ioctl_linux.go.
//
// The third argument to ioctl is often a pointer but sometimes an integer.
// Callers should use ioctlPtr when the third argument is a pointer and ioctl
// when the third argument is an integer.
//
// TODO: some existing code incorrectly uses ioctl when it should use ioctlPtr.
//sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
@ -102,6 +119,23 @@ func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) {
return openat2(dirfd, path, how, SizeofOpenHow) return openat2(dirfd, path, how, SizeofOpenHow)
} }
func Pipe(p []int) error {
return Pipe2(p, 0)
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) error {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err := pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return err
}
//sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) //sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
@ -111,6 +145,15 @@ func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error
return ppoll(&fds[0], len(fds), timeout, sigmask) return ppoll(&fds[0], len(fds), timeout, sigmask)
} }
func Poll(fds []PollFd, timeout int) (n int, err error) {
var ts *Timespec
if timeout >= 0 {
ts = new(Timespec)
*ts = NsecToTimespec(int64(timeout) * 1e6)
}
return Ppoll(fds, ts, nil)
}
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error) //sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
func Readlink(path string, buf []byte) (n int, err error) { func Readlink(path string, buf []byte) (n int, err error) {
@ -161,27 +204,7 @@ func Utimes(path string, tv []Timeval) error {
//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
func UtimesNano(path string, ts []Timespec) error { func UtimesNano(path string, ts []Timespec) error {
if ts == nil { return UtimesNanoAt(AT_FDCWD, path, ts, 0)
err := utimensat(AT_FDCWD, path, nil, 0)
if err != ENOSYS {
return err
}
return utimes(path, nil)
}
if len(ts) != 2 {
return EINVAL
}
err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
if err != ENOSYS {
return err
}
// If the utimensat syscall isn't available (utimensat was added to Linux
// in 2.6.22, Released, 8 July 2007) then fall back to utimes
var tv [2]Timeval
for i := 0; i < 2; i++ {
tv[i] = NsecToTimeval(TimespecToNsec(ts[i]))
}
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
} }
func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
@ -349,9 +372,7 @@ func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
p[0] = byte(sa.Port >> 8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
} }
@ -364,9 +385,7 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
p[0] = byte(sa.Port >> 8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
sa.raw.Scope_id = sa.ZoneId sa.raw.Scope_id = sa.ZoneId
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
} }
@ -415,9 +434,7 @@ func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Hatype = sa.Hatype sa.raw.Hatype = sa.Hatype
sa.raw.Pkttype = sa.Pkttype sa.raw.Pkttype = sa.Pkttype
sa.raw.Halen = sa.Halen sa.raw.Halen = sa.Halen
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
} }
@ -832,12 +849,10 @@ func (sa *SockaddrTIPC) sockaddr() (unsafe.Pointer, _Socklen, error) {
if sa.Addr == nil { if sa.Addr == nil {
return nil, 0, EINVAL return nil, 0, EINVAL
} }
sa.raw.Family = AF_TIPC sa.raw.Family = AF_TIPC
sa.raw.Scope = int8(sa.Scope) sa.raw.Scope = int8(sa.Scope)
sa.raw.Addrtype = sa.Addr.tipcAddrtype() sa.raw.Addrtype = sa.Addr.tipcAddrtype()
sa.raw.Addr = sa.Addr.tipcAddr() sa.raw.Addr = sa.Addr.tipcAddr()
return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil
} }
@ -851,9 +866,7 @@ type SockaddrL2TPIP struct {
func (sa *SockaddrL2TPIP) sockaddr() (unsafe.Pointer, _Socklen, error) { func (sa *SockaddrL2TPIP) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Family = AF_INET sa.raw.Family = AF_INET
sa.raw.Conn_id = sa.ConnId sa.raw.Conn_id = sa.ConnId
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP, nil
} }
@ -869,9 +882,7 @@ func (sa *SockaddrL2TPIP6) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Family = AF_INET6 sa.raw.Family = AF_INET6
sa.raw.Conn_id = sa.ConnId sa.raw.Conn_id = sa.ConnId
sa.raw.Scope_id = sa.ZoneId sa.raw.Scope_id = sa.ZoneId
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil
} }
@ -967,9 +978,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
sa.Hatype = pp.Hatype sa.Hatype = pp.Hatype
sa.Pkttype = pp.Pkttype sa.Pkttype = pp.Pkttype
sa.Halen = pp.Halen sa.Halen = pp.Halen
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
case AF_UNIX: case AF_UNIX:
@ -1008,18 +1017,14 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
pp := (*RawSockaddrL2TPIP)(unsafe.Pointer(rsa)) pp := (*RawSockaddrL2TPIP)(unsafe.Pointer(rsa))
sa := new(SockaddrL2TPIP) sa := new(SockaddrL2TPIP)
sa.ConnId = pp.Conn_id sa.ConnId = pp.Conn_id
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
default: default:
pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
sa := new(SockaddrInet4) sa := new(SockaddrInet4)
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1]) sa.Port = int(p[0])<<8 + int(p[1])
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
} }
@ -1035,9 +1040,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
sa := new(SockaddrL2TPIP6) sa := new(SockaddrL2TPIP6)
sa.ConnId = pp.Conn_id sa.ConnId = pp.Conn_id
sa.ZoneId = pp.Scope_id sa.ZoneId = pp.Scope_id
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
default: default:
pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
@ -1045,9 +1048,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1]) sa.Port = int(p[0])<<8 + int(p[1])
sa.ZoneId = pp.Scope_id sa.ZoneId = pp.Scope_id
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
} }
@ -1222,11 +1223,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
func Accept(fd int) (nfd int, sa Sockaddr, err error) { func Accept(fd int) (nfd int, sa Sockaddr, err error) {
var rsa RawSockaddrAny var rsa RawSockaddrAny
var len _Socklen = SizeofSockaddrAny var len _Socklen = SizeofSockaddrAny
// Try accept4 first for Android, then try accept for kernel older than 2.6.28
nfd, err = accept4(fd, &rsa, &len, 0) nfd, err = accept4(fd, &rsa, &len, 0)
if err == ENOSYS {
nfd, err = accept(fd, &rsa, &len)
}
if err != nil { if err != nil {
return return
} }
@ -1348,6 +1345,13 @@ func SetsockoptTpacketReq3(fd, level, opt int, tp *TpacketReq3) error {
return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp)) return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp))
} }
func SetsockoptTCPRepairOpt(fd, level, opt int, o []TCPRepairOpt) (err error) {
if len(o) == 0 {
return EINVAL
}
return setsockopt(fd, level, opt, unsafe.Pointer(&o[0]), uintptr(SizeofTCPRepairOpt*len(o)))
}
// Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html) // Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html)
// KeyctlInt calls keyctl commands in which each argument is an int. // KeyctlInt calls keyctl commands in which each argument is an int.
@ -1771,6 +1775,16 @@ func Mount(source string, target string, fstype string, flags uintptr, data stri
return mount(source, target, fstype, flags, datap) return mount(source, target, fstype, flags, datap)
} }
//sys mountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr, size uintptr) (err error) = SYS_MOUNT_SETATTR
// MountSetattr is a wrapper for mount_setattr(2).
// https://man7.org/linux/man-pages/man2/mount_setattr.2.html
//
// Requires kernel >= 5.12.
func MountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr) error {
return mountSetattr(dirfd, pathname, flags, attr, unsafe.Sizeof(*attr))
}
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
if raceenabled { if raceenabled {
raceReleaseMerge(unsafe.Pointer(&ioSync)) raceReleaseMerge(unsafe.Pointer(&ioSync))
@ -1802,11 +1816,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sys Dup(oldfd int) (fd int, err error) //sys Dup(oldfd int) (fd int, err error)
func Dup2(oldfd, newfd int) error { func Dup2(oldfd, newfd int) error {
// Android O and newer blocks dup2; riscv and arm64 don't implement dup2. return Dup3(oldfd, newfd, 0)
if runtime.GOOS == "android" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "arm64" {
return Dup3(oldfd, newfd, 0)
}
return dup2(oldfd, newfd)
} }
//sys Dup3(oldfd int, newfd int, flags int) (err error) //sys Dup3(oldfd int, newfd int, flags int) (err error)
@ -1859,7 +1869,7 @@ func Getpgrp() (pid int) {
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) //sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error)
//sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
//sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 //sysnb Prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
//sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error)
//sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6 //sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6
//sys read(fd int, p []byte) (n int, err error) //sys read(fd int, p []byte) (n int, err error)
@ -2294,6 +2304,14 @@ type RemoteIovec struct {
//sys ProcessVMReadv(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_READV //sys ProcessVMReadv(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_READV
//sys ProcessVMWritev(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_WRITEV //sys ProcessVMWritev(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_WRITEV
//sys PidfdOpen(pid int, flags int) (fd int, err error) = SYS_PIDFD_OPEN
//sys PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) = SYS_PIDFD_GETFD
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
//sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error)
//sys shmdt(addr uintptr) (err error)
//sys shmget(key int, size int, flag int) (id int, err error)
/* /*
* Unimplemented * Unimplemented
*/ */
@ -2375,10 +2393,6 @@ type RemoteIovec struct {
// SetRobustList // SetRobustList
// SetThreadArea // SetThreadArea
// SetTidAddress // SetTidAddress
// Shmat
// Shmctl
// Shmdt
// Shmget
// Sigaltstack // Sigaltstack
// Swapoff // Swapoff
// Swapon // Swapon

@ -19,36 +19,8 @@ func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: int32(sec), Usec: int32(usec)} return Timeval{Sec: int32(sec), Usec: int32(usec)}
} }
//sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe(&pp)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
// 64-bit file system and 32-bit uid calls // 64-bit file system and 32-bit uid calls
// (386 default is 32-bit file system and 16-bit uid). // (386 default is 32-bit file system and 16-bit uid).
//sys dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32 //sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
@ -59,7 +31,6 @@ func Pipe2(p []int, flags int) (err error) {
//sysnb Geteuid() (euid int) = SYS_GETEUID32 //sysnb Geteuid() (euid int) = SYS_GETEUID32
//sysnb Getgid() (gid int) = SYS_GETGID32 //sysnb Getgid() (gid int) = SYS_GETGID32
//sysnb Getuid() (uid int) = SYS_GETUID32 //sysnb Getuid() (uid int) = SYS_GETUID32
//sysnb InotifyInit() (fd int, err error)
//sys Ioperm(from int, num int, on int) (err error) //sys Ioperm(from int, num int, on int) (err error)
//sys Iopl(level int) (err error) //sys Iopl(level int) (err error)
//sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32 //sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
@ -105,7 +76,7 @@ const rlimInf32 = ^uint32(0)
const rlimInf64 = ^uint64(0) const rlimInf64 = ^uint64(0)
func Getrlimit(resource int, rlim *Rlimit) (err error) { func Getrlimit(resource int, rlim *Rlimit) (err error) {
err = prlimit(0, resource, nil, rlim) err = Prlimit(0, resource, nil, rlim)
if err != ENOSYS { if err != ENOSYS {
return err return err
} }
@ -133,7 +104,7 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) {
//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT //sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
func Setrlimit(resource int, rlim *Rlimit) (err error) { func Setrlimit(resource int, rlim *Rlimit) (err error) {
err = prlimit(0, resource, rlim, nil) err = Prlimit(0, resource, rlim, nil)
if err != ENOSYS { if err != ENOSYS {
return err return err
} }
@ -381,12 +352,3 @@ func (cmsg *Cmsghdr) SetLen(length int) {
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) { func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint32(length) rsa.Service_name_len = uint32(length)
} }
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

@ -7,8 +7,6 @@
package unix package unix
//sys dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
@ -21,17 +19,6 @@ package unix
//sysnb Getgid() (gid int) //sysnb Getgid() (gid int)
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) //sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Getuid() (uid int) //sysnb Getuid() (uid int)
//sysnb inotifyInit() (fd int, err error)
func InotifyInit() (fd int, err error) {
// First try inotify_init1, because Android's seccomp policy blocks the latter.
fd, err = InotifyInit1(0)
if err == ENOSYS {
fd, err = inotifyInit()
}
return
}
//sys Ioperm(from int, num int, on int) (err error) //sys Ioperm(from int, num int, on int) (err error)
//sys Iopl(level int) (err error) //sys Iopl(level int) (err error)
//sys Lchown(path string, uid int, gid int) (err error) //sys Lchown(path string, uid int, gid int) (err error)
@ -126,32 +113,6 @@ func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: usec} return Timeval{Sec: sec, Usec: usec}
} }
//sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe(&pp)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
func (r *PtraceRegs) PC() uint64 { return r.Rip } func (r *PtraceRegs) PC() uint64 { return r.Rip }
func (r *PtraceRegs) SetPC(pc uint64) { r.Rip = pc } func (r *PtraceRegs) SetPC(pc uint64) { r.Rip = pc }
@ -176,15 +137,6 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint64(length) rsa.Service_name_len = uint64(length)
} }
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) //sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error { func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {

@ -19,36 +19,6 @@ func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: int32(sec), Usec: int32(usec)} return Timeval{Sec: int32(sec), Usec: int32(usec)}
} }
//sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
// Try pipe2 first for Android O, then try pipe for kernel 2.6.23.
err = pipe2(&pp, 0)
if err == ENOSYS {
err = pipe(&pp)
}
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
newoffset, errno := seek(fd, offset, whence) newoffset, errno := seek(fd, offset, whence)
if errno != 0 { if errno != 0 {
@ -76,8 +46,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
// 64-bit file system and 32-bit uid calls // 64-bit file system and 32-bit uid calls
// (16-bit uid calls are not always supported in newer kernels) // (16-bit uid calls are not always supported in newer kernels)
//sys dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32 //sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
@ -86,7 +54,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
//sysnb Geteuid() (euid int) = SYS_GETEUID32 //sysnb Geteuid() (euid int) = SYS_GETEUID32
//sysnb Getgid() (gid int) = SYS_GETGID32 //sysnb Getgid() (gid int) = SYS_GETGID32
//sysnb Getuid() (uid int) = SYS_GETUID32 //sysnb Getuid() (uid int) = SYS_GETUID32
//sysnb InotifyInit() (fd int, err error)
//sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32 //sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
//sys Listen(s int, n int) (err error) //sys Listen(s int, n int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
@ -184,7 +151,7 @@ const rlimInf32 = ^uint32(0)
const rlimInf64 = ^uint64(0) const rlimInf64 = ^uint64(0)
func Getrlimit(resource int, rlim *Rlimit) (err error) { func Getrlimit(resource int, rlim *Rlimit) (err error) {
err = prlimit(0, resource, nil, rlim) err = Prlimit(0, resource, nil, rlim)
if err != ENOSYS { if err != ENOSYS {
return err return err
} }
@ -212,7 +179,7 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) {
//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT //sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
func Setrlimit(resource int, rlim *Rlimit) (err error) { func Setrlimit(resource int, rlim *Rlimit) (err error) {
err = prlimit(0, resource, rlim, nil) err = Prlimit(0, resource, rlim, nil)
if err != ENOSYS { if err != ENOSYS {
return err return err
} }
@ -260,15 +227,6 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint32(length) rsa.Service_name_len = uint32(length)
} }
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}
//sys armSyncFileRange(fd int, flags int, off int64, n int64) (err error) = SYS_ARM_SYNC_FILE_RANGE //sys armSyncFileRange(fd int, flags int, off int64, n int64) (err error) = SYS_ARM_SYNC_FILE_RANGE
func SyncFileRange(fd int, off int64, n int64, flags int) error { func SyncFileRange(fd int, off int64, n int64, flags int) error {

@ -9,13 +9,6 @@ package unix
import "unsafe" import "unsafe"
func EpollCreate(size int) (fd int, err error) {
if size <= 0 {
return -1, EINVAL
}
return EpollCreate1(0)
}
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
@ -145,33 +138,9 @@ func utimes(path string, tv *[2]Timeval) (err error) {
return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
} }
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, 0)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
// Getrlimit prefers the prlimit64 system call. See issue 38604. // Getrlimit prefers the prlimit64 system call. See issue 38604.
func Getrlimit(resource int, rlim *Rlimit) error { func Getrlimit(resource int, rlim *Rlimit) error {
err := prlimit(0, resource, nil, rlim) err := Prlimit(0, resource, nil, rlim)
if err != ENOSYS { if err != ENOSYS {
return err return err
} }
@ -180,7 +149,7 @@ func Getrlimit(resource int, rlim *Rlimit) error {
// Setrlimit prefers the prlimit64 system call. See issue 38604. // Setrlimit prefers the prlimit64 system call. See issue 38604.
func Setrlimit(resource int, rlim *Rlimit) error { func Setrlimit(resource int, rlim *Rlimit) error {
err := prlimit(0, resource, rlim, nil) err := Prlimit(0, resource, rlim, nil)
if err != ENOSYS { if err != ENOSYS {
return err return err
} }
@ -211,31 +180,11 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint64(length) rsa.Service_name_len = uint64(length)
} }
func InotifyInit() (fd int, err error) {
return InotifyInit1(0)
}
// dup2 exists because func Dup3 in syscall_linux.go references
// it in an unreachable path. dup2 isn't available on arm64.
func dup2(oldfd int, newfd int) error
func Pause() error { func Pause() error {
_, err := ppoll(nil, 0, nil, nil) _, err := ppoll(nil, 0, nil, nil)
return err return err
} }
func Poll(fds []PollFd, timeout int) (n int, err error) {
var ts *Timespec
if timeout >= 0 {
ts = new(Timespec)
*ts = NsecToTimespec(int64(timeout) * 1e6)
}
if len(fds) == 0 {
return ppoll(nil, 0, ts, nil)
}
return ppoll(&fds[0], len(fds), ts, nil)
}
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) //sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error { func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {

@ -8,8 +8,6 @@
package unix package unix
//sys dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
@ -94,30 +92,6 @@ func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: usec} return Timeval{Sec: sec, Usec: usec}
} }
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, 0)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
func Ioperm(from int, num int, on int) (err error) { func Ioperm(from int, num int, on int) (err error) {
return ENOSYS return ENOSYS
} }
@ -220,16 +194,3 @@ func (cmsg *Cmsghdr) SetLen(length int) {
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) { func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint64(length) rsa.Service_name_len = uint64(length)
} }
func InotifyInit() (fd int, err error) {
return InotifyInit1(0)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

@ -15,8 +15,6 @@ import (
func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
//sys dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
@ -60,7 +58,6 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sysnb InotifyInit() (fd int, err error)
//sys Ioperm(from int, num int, on int) (err error) //sys Ioperm(from int, num int, on int) (err error)
//sys Iopl(level int) (err error) //sys Iopl(level int) (err error)
@ -113,29 +110,6 @@ func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: int32(sec), Usec: int32(usec)} return Timeval{Sec: int32(sec), Usec: int32(usec)}
} }
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe() (p1 int, p2 int, err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
p[0], p[1], err = pipe()
return
}
//sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) //sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) { func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
@ -157,7 +131,7 @@ type rlimit32 struct {
//sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT //sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
func Getrlimit(resource int, rlim *Rlimit) (err error) { func Getrlimit(resource int, rlim *Rlimit) (err error) {
err = prlimit(0, resource, nil, rlim) err = Prlimit(0, resource, nil, rlim)
if err != ENOSYS { if err != ENOSYS {
return err return err
} }
@ -185,7 +159,7 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) {
//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT //sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
func Setrlimit(resource int, rlim *Rlimit) (err error) { func Setrlimit(resource int, rlim *Rlimit) (err error) {
err = prlimit(0, resource, rlim, nil) err = Prlimit(0, resource, rlim, nil)
if err != ENOSYS { if err != ENOSYS {
return err return err
} }
@ -232,12 +206,3 @@ func (cmsg *Cmsghdr) SetLen(length int) {
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) { func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint32(length) rsa.Service_name_len = uint32(length)
} }
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

@ -3,8 +3,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build linux && ppc //go:build linux && ppc
// +build linux // +build linux,ppc
// +build ppc
package unix package unix
@ -13,8 +12,6 @@ import (
"unsafe" "unsafe"
) )
//sys dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
@ -24,7 +21,6 @@ import (
//sysnb Geteuid() (euid int) //sysnb Geteuid() (euid int)
//sysnb Getgid() (gid int) //sysnb Getgid() (gid int)
//sysnb Getuid() (uid int) //sysnb Getuid() (uid int)
//sysnb InotifyInit() (fd int, err error)
//sys Ioperm(from int, num int, on int) (err error) //sys Ioperm(from int, num int, on int) (err error)
//sys Iopl(level int) (err error) //sys Iopl(level int) (err error)
//sys Lchown(path string, uid int, gid int) (err error) //sys Lchown(path string, uid int, gid int) (err error)
@ -143,7 +139,7 @@ const rlimInf32 = ^uint32(0)
const rlimInf64 = ^uint64(0) const rlimInf64 = ^uint64(0)
func Getrlimit(resource int, rlim *Rlimit) (err error) { func Getrlimit(resource int, rlim *Rlimit) (err error) {
err = prlimit(0, resource, nil, rlim) err = Prlimit(0, resource, nil, rlim)
if err != ENOSYS { if err != ENOSYS {
return err return err
} }
@ -171,7 +167,7 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) {
//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT //sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
func Setrlimit(resource int, rlim *Rlimit) (err error) { func Setrlimit(resource int, rlim *Rlimit) (err error) {
err = prlimit(0, resource, rlim, nil) err = Prlimit(0, resource, rlim, nil)
if err != ENOSYS { if err != ENOSYS {
return err return err
} }
@ -219,41 +215,6 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint32(length) rsa.Service_name_len = uint32(length)
} }
//sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe(&pp)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}
//sys syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2 //sys syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2
func SyncFileRange(fd int, off int64, n int64, flags int) error { func SyncFileRange(fd int, off int64, n int64, flags int) error {

@ -8,8 +8,6 @@
package unix package unix
//sys dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
@ -22,7 +20,6 @@ package unix
//sysnb Getgid() (gid int) //sysnb Getgid() (gid int)
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_UGETRLIMIT //sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_UGETRLIMIT
//sysnb Getuid() (uid int) //sysnb Getuid() (uid int)
//sysnb InotifyInit() (fd int, err error)
//sys Ioperm(from int, num int, on int) (err error) //sys Ioperm(from int, num int, on int) (err error)
//sys Iopl(level int) (err error) //sys Iopl(level int) (err error)
//sys Lchown(path string, uid int, gid int) (err error) //sys Lchown(path string, uid int, gid int) (err error)
@ -104,41 +101,6 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint64(length) rsa.Service_name_len = uint64(length)
} }
//sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe(&pp)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}
//sys syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2 //sys syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2
func SyncFileRange(fd int, off int64, n int64, flags int) error { func SyncFileRange(fd int, off int64, n int64, flags int) error {

@ -9,13 +9,6 @@ package unix
import "unsafe" import "unsafe"
func EpollCreate(size int) (fd int, err error) {
if size <= 0 {
return -1, EINVAL
}
return EpollCreate1(0)
}
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
@ -144,30 +137,6 @@ func utimes(path string, tv *[2]Timeval) (err error) {
return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
} }
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, 0)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
func (r *PtraceRegs) PC() uint64 { return r.Pc } func (r *PtraceRegs) PC() uint64 { return r.Pc }
func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc } func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc }
@ -192,27 +161,11 @@ func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint64(length) rsa.Service_name_len = uint64(length)
} }
func InotifyInit() (fd int, err error) {
return InotifyInit1(0)
}
func Pause() error { func Pause() error {
_, err := ppoll(nil, 0, nil, nil) _, err := ppoll(nil, 0, nil, nil)
return err return err
} }
func Poll(fds []PollFd, timeout int) (n int, err error) {
var ts *Timespec
if timeout >= 0 {
ts = new(Timespec)
*ts = NsecToTimespec(int64(timeout) * 1e6)
}
if len(fds) == 0 {
return ppoll(nil, 0, ts, nil)
}
return ppoll(&fds[0], len(fds), ts, nil)
}
func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
return Renameat2(olddirfd, oldpath, newdirfd, newpath, 0) return Renameat2(olddirfd, oldpath, newdirfd, newpath, 0)
} }
@ -229,7 +182,3 @@ func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error
} }
return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags) return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)
} }
// dup2 exists because func Dup3 in syscall_linux.go references
// it in an unreachable path. dup2 isn't available on arm64.
func dup2(oldfd int, newfd int) error

@ -11,8 +11,6 @@ import (
"unsafe" "unsafe"
) )
//sys dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
@ -25,7 +23,6 @@ import (
//sysnb Getgid() (gid int) //sysnb Getgid() (gid int)
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) //sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Getuid() (uid int) //sysnb Getuid() (uid int)
//sysnb InotifyInit() (fd int, err error)
//sys Lchown(path string, uid int, gid int) (err error) //sys Lchown(path string, uid int, gid int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error) //sys Lstat(path string, stat *Stat_t) (err error)
//sys Pause() (err error) //sys Pause() (err error)
@ -77,30 +74,6 @@ func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: usec} return Timeval{Sec: sec, Usec: usec}
} }
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, 0) // pipe2 is the same as pipe when flags are set to 0.
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
func Ioperm(from int, num int, on int) (err error) { func Ioperm(from int, num int, on int) (err error) {
return ENOSYS return ENOSYS
} }
@ -324,15 +297,6 @@ func Shutdown(s, how int) error {
return nil return nil
} }
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) //sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error { func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {

@ -9,7 +9,6 @@ package unix
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys dup2(oldfd int, newfd int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 //sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
@ -20,7 +19,6 @@ package unix
//sysnb Getgid() (gid int) //sysnb Getgid() (gid int)
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) //sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Getuid() (uid int) //sysnb Getuid() (uid int)
//sysnb InotifyInit() (fd int, err error)
//sys Lchown(path string, uid int, gid int) (err error) //sys Lchown(path string, uid int, gid int) (err error)
//sys Listen(s int, n int) (err error) //sys Listen(s int, n int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error) //sys Lstat(path string, stat *Stat_t) (err error)
@ -119,38 +117,3 @@ func (cmsg *Cmsghdr) SetLen(length int) {
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) { func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint64(length) rsa.Service_name_len = uint64(length)
} }
//sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe(&pp)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

@ -13,7 +13,10 @@
package unix package unix
import ( import (
"fmt"
"os"
"runtime" "runtime"
"sync"
"syscall" "syscall"
"unsafe" "unsafe"
) )
@ -89,9 +92,7 @@ func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
p[0] = byte(sa.Port >> 8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
} }
@ -104,9 +105,7 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
p[0] = byte(sa.Port >> 8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
sa.raw.Scope_id = sa.ZoneId sa.raw.Scope_id = sa.ZoneId
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
} }
@ -414,9 +413,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
sa := new(SockaddrInet4) sa := new(SockaddrInet4)
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1]) sa.Port = int(p[0])<<8 + int(p[1])
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
case AF_INET6: case AF_INET6:
@ -425,9 +422,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1]) sa.Port = int(p[0])<<8 + int(p[1])
sa.ZoneId = pp.Scope_id sa.ZoneId = pp.Scope_id
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
} }
return nil, EAFNOSUPPORT return nil, EAFNOSUPPORT
@ -744,3 +739,240 @@ func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, e
func Munmap(b []byte) (err error) { func Munmap(b []byte) (err error) {
return mapper.Munmap(b) return mapper.Munmap(b)
} }
// Event Ports
type fileObjCookie struct {
fobj *fileObj
cookie interface{}
}
// EventPort provides a safe abstraction on top of Solaris/illumos Event Ports.
type EventPort struct {
port int
mu sync.Mutex
fds map[uintptr]interface{}
paths map[string]*fileObjCookie
}
// PortEvent is an abstraction of the port_event C struct.
// Compare Source against PORT_SOURCE_FILE or PORT_SOURCE_FD
// to see if Path or Fd was the event source. The other will be
// uninitialized.
type PortEvent struct {
Cookie interface{}
Events int32
Fd uintptr
Path string
Source uint16
fobj *fileObj
}
// NewEventPort creates a new EventPort including the
// underlying call to port_create(3c).
func NewEventPort() (*EventPort, error) {
port, err := port_create()
if err != nil {
return nil, err
}
e := &EventPort{
port: port,
fds: make(map[uintptr]interface{}),
paths: make(map[string]*fileObjCookie),
}
return e, nil
}
//sys port_create() (n int, err error)
//sys port_associate(port int, source int, object uintptr, events int, user *byte) (n int, err error)
//sys port_dissociate(port int, source int, object uintptr) (n int, err error)
//sys port_get(port int, pe *portEvent, timeout *Timespec) (n int, err error)
//sys port_getn(port int, pe *portEvent, max uint32, nget *uint32, timeout *Timespec) (n int, err error)
// Close closes the event port.
func (e *EventPort) Close() error {
e.mu.Lock()
defer e.mu.Unlock()
e.fds = nil
e.paths = nil
return Close(e.port)
}
// PathIsWatched checks to see if path is associated with this EventPort.
func (e *EventPort) PathIsWatched(path string) bool {
e.mu.Lock()
defer e.mu.Unlock()
_, found := e.paths[path]
return found
}
// FdIsWatched checks to see if fd is associated with this EventPort.
func (e *EventPort) FdIsWatched(fd uintptr) bool {
e.mu.Lock()
defer e.mu.Unlock()
_, found := e.fds[fd]
return found
}
// AssociatePath wraps port_associate(3c) for a filesystem path including
// creating the necessary file_obj from the provided stat information.
func (e *EventPort) AssociatePath(path string, stat os.FileInfo, events int, cookie interface{}) error {
e.mu.Lock()
defer e.mu.Unlock()
if _, found := e.paths[path]; found {
return fmt.Errorf("%v is already associated with this Event Port", path)
}
fobj, err := createFileObj(path, stat)
if err != nil {
return err
}
fCookie := &fileObjCookie{fobj, cookie}
_, err = port_associate(e.port, PORT_SOURCE_FILE, uintptr(unsafe.Pointer(fobj)), events, (*byte)(unsafe.Pointer(&fCookie.cookie)))
if err != nil {
return err
}
e.paths[path] = fCookie
return nil
}
// DissociatePath wraps port_dissociate(3c) for a filesystem path.
func (e *EventPort) DissociatePath(path string) error {
e.mu.Lock()
defer e.mu.Unlock()
f, ok := e.paths[path]
if !ok {
return fmt.Errorf("%v is not associated with this Event Port", path)
}
_, err := port_dissociate(e.port, PORT_SOURCE_FILE, uintptr(unsafe.Pointer(f.fobj)))
if err != nil {
return err
}
delete(e.paths, path)
return nil
}
// AssociateFd wraps calls to port_associate(3c) on file descriptors.
func (e *EventPort) AssociateFd(fd uintptr, events int, cookie interface{}) error {
e.mu.Lock()
defer e.mu.Unlock()
if _, found := e.fds[fd]; found {
return fmt.Errorf("%v is already associated with this Event Port", fd)
}
pcookie := &cookie
_, err := port_associate(e.port, PORT_SOURCE_FD, fd, events, (*byte)(unsafe.Pointer(pcookie)))
if err != nil {
return err
}
e.fds[fd] = pcookie
return nil
}
// DissociateFd wraps calls to port_dissociate(3c) on file descriptors.
func (e *EventPort) DissociateFd(fd uintptr) error {
e.mu.Lock()
defer e.mu.Unlock()
_, ok := e.fds[fd]
if !ok {
return fmt.Errorf("%v is not associated with this Event Port", fd)
}
_, err := port_dissociate(e.port, PORT_SOURCE_FD, fd)
if err != nil {
return err
}
delete(e.fds, fd)
return nil
}
func createFileObj(name string, stat os.FileInfo) (*fileObj, error) {
fobj := new(fileObj)
bs, err := ByteSliceFromString(name)
if err != nil {
return nil, err
}
fobj.Name = (*int8)(unsafe.Pointer(&bs[0]))
s := stat.Sys().(*syscall.Stat_t)
fobj.Atim.Sec = s.Atim.Sec
fobj.Atim.Nsec = s.Atim.Nsec
fobj.Mtim.Sec = s.Mtim.Sec
fobj.Mtim.Nsec = s.Mtim.Nsec
fobj.Ctim.Sec = s.Ctim.Sec
fobj.Ctim.Nsec = s.Ctim.Nsec
return fobj, nil
}
// GetOne wraps port_get(3c) and returns a single PortEvent.
func (e *EventPort) GetOne(t *Timespec) (*PortEvent, error) {
pe := new(portEvent)
_, err := port_get(e.port, pe, t)
if err != nil {
return nil, err
}
p := new(PortEvent)
p.Events = pe.Events
p.Source = pe.Source
e.mu.Lock()
defer e.mu.Unlock()
switch pe.Source {
case PORT_SOURCE_FD:
p.Fd = uintptr(pe.Object)
cookie := (*interface{})(unsafe.Pointer(pe.User))
p.Cookie = *cookie
delete(e.fds, p.Fd)
case PORT_SOURCE_FILE:
p.fobj = (*fileObj)(unsafe.Pointer(uintptr(pe.Object)))
p.Path = BytePtrToString((*byte)(unsafe.Pointer(p.fobj.Name)))
cookie := (*interface{})(unsafe.Pointer(pe.User))
p.Cookie = *cookie
delete(e.paths, p.Path)
}
return p, nil
}
// Pending wraps port_getn(3c) and returns how many events are pending.
func (e *EventPort) Pending() (int, error) {
var n uint32 = 0
_, err := port_getn(e.port, nil, 0, &n, nil)
return int(n), err
}
// Get wraps port_getn(3c) and fills a slice of PortEvent.
// It will block until either min events have been received
// or the timeout has been exceeded. It will return how many
// events were actually received along with any error information.
func (e *EventPort) Get(s []PortEvent, min int, timeout *Timespec) (int, error) {
if min == 0 {
return 0, fmt.Errorf("need to request at least one event or use Pending() instead")
}
if len(s) < min {
return 0, fmt.Errorf("len(s) (%d) is less than min events requested (%d)", len(s), min)
}
got := uint32(min)
max := uint32(len(s))
var err error
ps := make([]portEvent, max, max)
_, err = port_getn(e.port, &ps[0], max, &got, timeout)
// got will be trustworthy with ETIME, but not any other error.
if err != nil && err != ETIME {
return 0, err
}
e.mu.Lock()
defer e.mu.Unlock()
for i := 0; i < int(got); i++ {
s[i].Events = ps[i].Events
s[i].Source = ps[i].Source
switch ps[i].Source {
case PORT_SOURCE_FD:
s[i].Fd = uintptr(ps[i].Object)
cookie := (*interface{})(unsafe.Pointer(ps[i].User))
s[i].Cookie = *cookie
delete(e.fds, s[i].Fd)
case PORT_SOURCE_FILE:
s[i].fobj = (*fileObj)(unsafe.Pointer(uintptr(ps[i].Object)))
s[i].Path = BytePtrToString((*byte)(unsafe.Pointer(s[i].fobj.Name)))
cookie := (*interface{})(unsafe.Pointer(ps[i].User))
s[i].Cookie = *cookie
delete(e.paths, s[i].Path)
}
}
return int(got), err
}

@ -313,6 +313,10 @@ func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
return return
} }
func Send(s int, buf []byte, flags int) (err error) {
return sendto(s, buf, flags, nil, 0)
}
func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) { func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
ptr, n, err := to.sockaddr() ptr, n, err := to.sockaddr()
if err != nil { if err != nil {

@ -67,9 +67,7 @@ func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
p[0] = byte(sa.Port >> 8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
} }
@ -83,9 +81,7 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
p[0] = byte(sa.Port >> 8) p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port) p[1] = byte(sa.Port)
sa.raw.Scope_id = sa.ZoneId sa.raw.Scope_id = sa.ZoneId
for i := 0; i < len(sa.Addr); i++ { sa.raw.Addr = sa.Addr
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
} }
@ -144,9 +140,7 @@ func anyToSockaddr(_ int, rsa *RawSockaddrAny) (Sockaddr, error) {
sa := new(SockaddrInet4) sa := new(SockaddrInet4)
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1]) sa.Port = int(p[0])<<8 + int(p[1])
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
case AF_INET6: case AF_INET6:
@ -155,9 +149,7 @@ func anyToSockaddr(_ int, rsa *RawSockaddrAny) (Sockaddr, error) {
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1]) sa.Port = int(p[0])<<8 + int(p[1])
sa.ZoneId = pp.Scope_id sa.ZoneId = pp.Scope_id
for i := 0; i < len(sa.Addr); i++ { sa.Addr = pp.Addr
sa.Addr[i] = pp.Addr[i]
}
return sa, nil return sa, nil
} }
return nil, EAFNOSUPPORT return nil, EAFNOSUPPORT

@ -0,0 +1,21 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build linux
// +build linux
package unix
import "runtime"
// SysvShmCtl performs control operations on the shared memory segment
// specified by id.
func SysvShmCtl(id, cmd int, desc *SysvShmDesc) (result int, err error) {
if runtime.GOARCH == "arm" ||
runtime.GOARCH == "mips64" || runtime.GOARCH == "mips64le" {
cmd |= ipc_64
}
return shmctl(id, cmd, desc)
}

@ -0,0 +1,61 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build (darwin && !ios) || linux
// +build darwin,!ios linux
package unix
import (
"unsafe"
"golang.org/x/sys/internal/unsafeheader"
)
// SysvShmAttach attaches the Sysv shared memory segment associated with the
// shared memory identifier id.
func SysvShmAttach(id int, addr uintptr, flag int) ([]byte, error) {
addr, errno := shmat(id, addr, flag)
if errno != nil {
return nil, errno
}
// Retrieve the size of the shared memory to enable slice creation
var info SysvShmDesc
_, err := SysvShmCtl(id, IPC_STAT, &info)
if err != nil {
// release the shared memory if we can't find the size
// ignoring error from shmdt as there's nothing sensible to return here
shmdt(addr)
return nil, err
}
// Use unsafe to convert addr into a []byte.
// TODO: convert to unsafe.Slice once we can assume Go 1.17
var b []byte
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
hdr.Data = unsafe.Pointer(addr)
hdr.Cap = int(info.Segsz)
hdr.Len = int(info.Segsz)
return b, nil
}
// SysvShmDetach unmaps the shared memory slice returned from SysvShmAttach.
//
// It is not safe to use the slice after calling this function.
func SysvShmDetach(data []byte) error {
if len(data) == 0 {
return EINVAL
}
return shmdt(uintptr(unsafe.Pointer(&data[0])))
}
// SysvShmGet returns the Sysv shared memory identifier associated with key.
// If the IPC_CREAT flag is specified a new segment is created.
func SysvShmGet(key, size, flag int) (id int, err error) {
return shmget(key, size, flag)
}

@ -0,0 +1,14 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin && !ios
// +build darwin,!ios
package unix
// SysvShmCtl performs control operations on the shared memory segment
// specified by id.
func SysvShmCtl(id, cmd int, desc *SysvShmDesc) (result int, err error) {
return shmctl(id, cmd, desc)
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,4 +1,4 @@
// Code generated by mkmerge.go; DO NOT EDIT. // Code generated by mkmerge; DO NOT EDIT.
//go:build linux //go:build linux
// +build linux // +build linux
@ -116,6 +116,7 @@ const (
ARPHRD_LAPB = 0x204 ARPHRD_LAPB = 0x204
ARPHRD_LOCALTLK = 0x305 ARPHRD_LOCALTLK = 0x305
ARPHRD_LOOPBACK = 0x304 ARPHRD_LOOPBACK = 0x304
ARPHRD_MCTP = 0x122
ARPHRD_METRICOM = 0x17 ARPHRD_METRICOM = 0x17
ARPHRD_NETLINK = 0x338 ARPHRD_NETLINK = 0x338
ARPHRD_NETROM = 0x0 ARPHRD_NETROM = 0x0
@ -228,7 +229,11 @@ const (
BPF_OR = 0x40 BPF_OR = 0x40
BPF_PSEUDO_BTF_ID = 0x3 BPF_PSEUDO_BTF_ID = 0x3
BPF_PSEUDO_CALL = 0x1 BPF_PSEUDO_CALL = 0x1
BPF_PSEUDO_FUNC = 0x4
BPF_PSEUDO_KFUNC_CALL = 0x2
BPF_PSEUDO_MAP_FD = 0x1 BPF_PSEUDO_MAP_FD = 0x1
BPF_PSEUDO_MAP_IDX = 0x5
BPF_PSEUDO_MAP_IDX_VALUE = 0x6
BPF_PSEUDO_MAP_VALUE = 0x2 BPF_PSEUDO_MAP_VALUE = 0x2
BPF_RET = 0x6 BPF_RET = 0x6
BPF_RSH = 0x70 BPF_RSH = 0x70
@ -468,6 +473,7 @@ const (
DM_DEV_WAIT = 0xc138fd08 DM_DEV_WAIT = 0xc138fd08
DM_DIR = "mapper" DM_DIR = "mapper"
DM_GET_TARGET_VERSION = 0xc138fd11 DM_GET_TARGET_VERSION = 0xc138fd11
DM_IMA_MEASUREMENT_FLAG = 0x80000
DM_INACTIVE_PRESENT_FLAG = 0x40 DM_INACTIVE_PRESENT_FLAG = 0x40
DM_INTERNAL_SUSPEND_FLAG = 0x40000 DM_INTERNAL_SUSPEND_FLAG = 0x40000
DM_IOCTL = 0xfd DM_IOCTL = 0xfd
@ -475,6 +481,8 @@ const (
DM_LIST_VERSIONS = 0xc138fd0d DM_LIST_VERSIONS = 0xc138fd0d
DM_MAX_TYPE_NAME = 0x10 DM_MAX_TYPE_NAME = 0x10
DM_NAME_LEN = 0x80 DM_NAME_LEN = 0x80
DM_NAME_LIST_FLAG_DOESNT_HAVE_UUID = 0x2
DM_NAME_LIST_FLAG_HAS_UUID = 0x1
DM_NOFLUSH_FLAG = 0x800 DM_NOFLUSH_FLAG = 0x800
DM_PERSISTENT_DEV_FLAG = 0x8 DM_PERSISTENT_DEV_FLAG = 0x8
DM_QUERY_INACTIVE_TABLE_FLAG = 0x1000 DM_QUERY_INACTIVE_TABLE_FLAG = 0x1000
@ -494,9 +502,9 @@ const (
DM_UUID_FLAG = 0x4000 DM_UUID_FLAG = 0x4000
DM_UUID_LEN = 0x81 DM_UUID_LEN = 0x81
DM_VERSION = 0xc138fd00 DM_VERSION = 0xc138fd00
DM_VERSION_EXTRA = "-ioctl (2021-02-01)" DM_VERSION_EXTRA = "-ioctl (2021-03-22)"
DM_VERSION_MAJOR = 0x4 DM_VERSION_MAJOR = 0x4
DM_VERSION_MINOR = 0x2c DM_VERSION_MINOR = 0x2d
DM_VERSION_PATCHLEVEL = 0x0 DM_VERSION_PATCHLEVEL = 0x0
DT_BLK = 0x6 DT_BLK = 0x6
DT_CHR = 0x2 DT_CHR = 0x2
@ -710,6 +718,7 @@ const (
ETH_P_LOOPBACK = 0x9000 ETH_P_LOOPBACK = 0x9000
ETH_P_MACSEC = 0x88e5 ETH_P_MACSEC = 0x88e5
ETH_P_MAP = 0xf9 ETH_P_MAP = 0xf9
ETH_P_MCTP = 0xfa
ETH_P_MOBITEX = 0x15 ETH_P_MOBITEX = 0x15
ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_MC = 0x8848
ETH_P_MPLS_UC = 0x8847 ETH_P_MPLS_UC = 0x8847
@ -745,6 +754,21 @@ const (
ETH_P_WCCP = 0x883e ETH_P_WCCP = 0x883e
ETH_P_X25 = 0x805 ETH_P_X25 = 0x805
ETH_P_XDSA = 0xf8 ETH_P_XDSA = 0xf8
EV_ABS = 0x3
EV_CNT = 0x20
EV_FF = 0x15
EV_FF_STATUS = 0x17
EV_KEY = 0x1
EV_LED = 0x11
EV_MAX = 0x1f
EV_MSC = 0x4
EV_PWR = 0x16
EV_REL = 0x2
EV_REP = 0x14
EV_SND = 0x12
EV_SW = 0x5
EV_SYN = 0x0
EV_VERSION = 0x10001
EXABYTE_ENABLE_NEST = 0xf0 EXABYTE_ENABLE_NEST = 0xf0
EXT2_SUPER_MAGIC = 0xef53 EXT2_SUPER_MAGIC = 0xef53
EXT3_SUPER_MAGIC = 0xef53 EXT3_SUPER_MAGIC = 0xef53
@ -783,9 +807,11 @@ const (
FAN_DELETE_SELF = 0x400 FAN_DELETE_SELF = 0x400
FAN_DENY = 0x2 FAN_DENY = 0x2
FAN_ENABLE_AUDIT = 0x40 FAN_ENABLE_AUDIT = 0x40
FAN_EPIDFD = -0x2
FAN_EVENT_INFO_TYPE_DFID = 0x3 FAN_EVENT_INFO_TYPE_DFID = 0x3
FAN_EVENT_INFO_TYPE_DFID_NAME = 0x2 FAN_EVENT_INFO_TYPE_DFID_NAME = 0x2
FAN_EVENT_INFO_TYPE_FID = 0x1 FAN_EVENT_INFO_TYPE_FID = 0x1
FAN_EVENT_INFO_TYPE_PIDFD = 0x4
FAN_EVENT_METADATA_LEN = 0x18 FAN_EVENT_METADATA_LEN = 0x18
FAN_EVENT_ON_CHILD = 0x8000000 FAN_EVENT_ON_CHILD = 0x8000000
FAN_MARK_ADD = 0x1 FAN_MARK_ADD = 0x1
@ -805,6 +831,7 @@ const (
FAN_MOVE_SELF = 0x800 FAN_MOVE_SELF = 0x800
FAN_NOFD = -0x1 FAN_NOFD = -0x1
FAN_NONBLOCK = 0x2 FAN_NONBLOCK = 0x2
FAN_NOPIDFD = -0x1
FAN_ONDIR = 0x40000000 FAN_ONDIR = 0x40000000
FAN_OPEN = 0x20 FAN_OPEN = 0x20
FAN_OPEN_EXEC = 0x1000 FAN_OPEN_EXEC = 0x1000
@ -815,6 +842,7 @@ const (
FAN_REPORT_DIR_FID = 0x400 FAN_REPORT_DIR_FID = 0x400
FAN_REPORT_FID = 0x200 FAN_REPORT_FID = 0x200
FAN_REPORT_NAME = 0x800 FAN_REPORT_NAME = 0x800
FAN_REPORT_PIDFD = 0x80
FAN_REPORT_TID = 0x100 FAN_REPORT_TID = 0x100
FAN_UNLIMITED_MARKS = 0x20 FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10 FAN_UNLIMITED_QUEUE = 0x10
@ -981,12 +1009,6 @@ const (
HPFS_SUPER_MAGIC = 0xf995e849 HPFS_SUPER_MAGIC = 0xf995e849
HUGETLBFS_MAGIC = 0x958458f6 HUGETLBFS_MAGIC = 0x958458f6
IBSHIFT = 0x10 IBSHIFT = 0x10
ICMPV6_FILTER = 0x1
ICMPV6_FILTER_BLOCK = 0x1
ICMPV6_FILTER_BLOCKOTHERS = 0x3
ICMPV6_FILTER_PASS = 0x2
ICMPV6_FILTER_PASSONLY = 0x4
ICMP_FILTER = 0x1
ICRNL = 0x100 ICRNL = 0x100
IFA_F_DADFAILED = 0x8 IFA_F_DADFAILED = 0x8
IFA_F_DEPRECATED = 0x20 IFA_F_DEPRECATED = 0x20
@ -1257,6 +1279,7 @@ const (
KEXEC_ARCH_PARISC = 0xf0000 KEXEC_ARCH_PARISC = 0xf0000
KEXEC_ARCH_PPC = 0x140000 KEXEC_ARCH_PPC = 0x140000
KEXEC_ARCH_PPC64 = 0x150000 KEXEC_ARCH_PPC64 = 0x150000
KEXEC_ARCH_RISCV = 0xf30000
KEXEC_ARCH_S390 = 0x160000 KEXEC_ARCH_S390 = 0x160000
KEXEC_ARCH_SH = 0x2a0000 KEXEC_ARCH_SH = 0x2a0000
KEXEC_ARCH_X86_64 = 0x3e0000 KEXEC_ARCH_X86_64 = 0x3e0000
@ -1332,6 +1355,20 @@ const (
KEY_SPEC_THREAD_KEYRING = -0x1 KEY_SPEC_THREAD_KEYRING = -0x1
KEY_SPEC_USER_KEYRING = -0x4 KEY_SPEC_USER_KEYRING = -0x4
KEY_SPEC_USER_SESSION_KEYRING = -0x5 KEY_SPEC_USER_SESSION_KEYRING = -0x5
LANDLOCK_ACCESS_FS_EXECUTE = 0x1
LANDLOCK_ACCESS_FS_MAKE_BLOCK = 0x800
LANDLOCK_ACCESS_FS_MAKE_CHAR = 0x40
LANDLOCK_ACCESS_FS_MAKE_DIR = 0x80
LANDLOCK_ACCESS_FS_MAKE_FIFO = 0x400
LANDLOCK_ACCESS_FS_MAKE_REG = 0x100
LANDLOCK_ACCESS_FS_MAKE_SOCK = 0x200
LANDLOCK_ACCESS_FS_MAKE_SYM = 0x1000
LANDLOCK_ACCESS_FS_READ_DIR = 0x8
LANDLOCK_ACCESS_FS_READ_FILE = 0x4
LANDLOCK_ACCESS_FS_REMOVE_DIR = 0x10
LANDLOCK_ACCESS_FS_REMOVE_FILE = 0x20
LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2
LANDLOCK_CREATE_RULESET_VERSION = 0x1
LINUX_REBOOT_CMD_CAD_OFF = 0x0 LINUX_REBOOT_CMD_CAD_OFF = 0x0
LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef
LINUX_REBOOT_CMD_HALT = 0xcdef0123 LINUX_REBOOT_CMD_HALT = 0xcdef0123
@ -1382,6 +1419,8 @@ const (
MADV_NOHUGEPAGE = 0xf MADV_NOHUGEPAGE = 0xf
MADV_NORMAL = 0x0 MADV_NORMAL = 0x0
MADV_PAGEOUT = 0x15 MADV_PAGEOUT = 0x15
MADV_POPULATE_READ = 0x16
MADV_POPULATE_WRITE = 0x17
MADV_RANDOM = 0x1 MADV_RANDOM = 0x1
MADV_REMOVE = 0x9 MADV_REMOVE = 0x9
MADV_SEQUENTIAL = 0x2 MADV_SEQUENTIAL = 0x2
@ -1437,6 +1476,18 @@ const (
MNT_FORCE = 0x1 MNT_FORCE = 0x1
MODULE_INIT_IGNORE_MODVERSIONS = 0x1 MODULE_INIT_IGNORE_MODVERSIONS = 0x1
MODULE_INIT_IGNORE_VERMAGIC = 0x2 MODULE_INIT_IGNORE_VERMAGIC = 0x2
MOUNT_ATTR_IDMAP = 0x100000
MOUNT_ATTR_NOATIME = 0x10
MOUNT_ATTR_NODEV = 0x4
MOUNT_ATTR_NODIRATIME = 0x80
MOUNT_ATTR_NOEXEC = 0x8
MOUNT_ATTR_NOSUID = 0x2
MOUNT_ATTR_NOSYMFOLLOW = 0x200000
MOUNT_ATTR_RDONLY = 0x1
MOUNT_ATTR_RELATIME = 0x0
MOUNT_ATTR_SIZE_VER0 = 0x20
MOUNT_ATTR_STRICTATIME = 0x20
MOUNT_ATTR__ATIME = 0x70
MSDOS_SUPER_MAGIC = 0x4d44 MSDOS_SUPER_MAGIC = 0x4d44
MSG_BATCH = 0x40000 MSG_BATCH = 0x40000
MSG_CMSG_CLOEXEC = 0x40000000 MSG_CMSG_CLOEXEC = 0x40000000
@ -1636,11 +1687,12 @@ const (
NFNL_MSG_BATCH_END = 0x11 NFNL_MSG_BATCH_END = 0x11
NFNL_NFA_NEST = 0x8000 NFNL_NFA_NEST = 0x8000
NFNL_SUBSYS_ACCT = 0x7 NFNL_SUBSYS_ACCT = 0x7
NFNL_SUBSYS_COUNT = 0xc NFNL_SUBSYS_COUNT = 0xd
NFNL_SUBSYS_CTHELPER = 0x9 NFNL_SUBSYS_CTHELPER = 0x9
NFNL_SUBSYS_CTNETLINK = 0x1 NFNL_SUBSYS_CTNETLINK = 0x1
NFNL_SUBSYS_CTNETLINK_EXP = 0x2 NFNL_SUBSYS_CTNETLINK_EXP = 0x2
NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8 NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8
NFNL_SUBSYS_HOOK = 0xc
NFNL_SUBSYS_IPSET = 0x6 NFNL_SUBSYS_IPSET = 0x6
NFNL_SUBSYS_NFTABLES = 0xa NFNL_SUBSYS_NFTABLES = 0xa
NFNL_SUBSYS_NFT_COMPAT = 0xb NFNL_SUBSYS_NFT_COMPAT = 0xb
@ -1756,14 +1808,19 @@ const (
PERF_ATTR_SIZE_VER4 = 0x68 PERF_ATTR_SIZE_VER4 = 0x68
PERF_ATTR_SIZE_VER5 = 0x70 PERF_ATTR_SIZE_VER5 = 0x70
PERF_ATTR_SIZE_VER6 = 0x78 PERF_ATTR_SIZE_VER6 = 0x78
PERF_ATTR_SIZE_VER7 = 0x80
PERF_AUX_FLAG_COLLISION = 0x8 PERF_AUX_FLAG_COLLISION = 0x8
PERF_AUX_FLAG_CORESIGHT_FORMAT_CORESIGHT = 0x0
PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW = 0x100
PERF_AUX_FLAG_OVERWRITE = 0x2 PERF_AUX_FLAG_OVERWRITE = 0x2
PERF_AUX_FLAG_PARTIAL = 0x4 PERF_AUX_FLAG_PARTIAL = 0x4
PERF_AUX_FLAG_PMU_FORMAT_TYPE_MASK = 0xff00
PERF_AUX_FLAG_TRUNCATED = 0x1 PERF_AUX_FLAG_TRUNCATED = 0x1
PERF_FLAG_FD_CLOEXEC = 0x8 PERF_FLAG_FD_CLOEXEC = 0x8
PERF_FLAG_FD_NO_GROUP = 0x1 PERF_FLAG_FD_NO_GROUP = 0x1
PERF_FLAG_FD_OUTPUT = 0x2 PERF_FLAG_FD_OUTPUT = 0x2
PERF_FLAG_PID_CGROUP = 0x4 PERF_FLAG_PID_CGROUP = 0x4
PERF_HW_EVENT_MASK = 0xffffffff
PERF_MAX_CONTEXTS_PER_STACK = 0x8 PERF_MAX_CONTEXTS_PER_STACK = 0x8
PERF_MAX_STACK_DEPTH = 0x7f PERF_MAX_STACK_DEPTH = 0x7f
PERF_MEM_BLK_ADDR = 0x4 PERF_MEM_BLK_ADDR = 0x4
@ -1822,6 +1879,7 @@ const (
PERF_MEM_TLB_OS = 0x40 PERF_MEM_TLB_OS = 0x40
PERF_MEM_TLB_SHIFT = 0x1a PERF_MEM_TLB_SHIFT = 0x1a
PERF_MEM_TLB_WK = 0x20 PERF_MEM_TLB_WK = 0x20
PERF_PMU_TYPE_SHIFT = 0x20
PERF_RECORD_KSYMBOL_FLAGS_UNREGISTER = 0x1 PERF_RECORD_KSYMBOL_FLAGS_UNREGISTER = 0x1
PERF_RECORD_MISC_COMM_EXEC = 0x2000 PERF_RECORD_MISC_COMM_EXEC = 0x2000
PERF_RECORD_MISC_CPUMODE_MASK = 0x7 PERF_RECORD_MISC_CPUMODE_MASK = 0x7
@ -1921,7 +1979,15 @@ const (
PR_PAC_APGAKEY = 0x10 PR_PAC_APGAKEY = 0x10
PR_PAC_APIAKEY = 0x1 PR_PAC_APIAKEY = 0x1
PR_PAC_APIBKEY = 0x2 PR_PAC_APIBKEY = 0x2
PR_PAC_GET_ENABLED_KEYS = 0x3d
PR_PAC_RESET_KEYS = 0x36 PR_PAC_RESET_KEYS = 0x36
PR_PAC_SET_ENABLED_KEYS = 0x3c
PR_SCHED_CORE = 0x3e
PR_SCHED_CORE_CREATE = 0x1
PR_SCHED_CORE_GET = 0x0
PR_SCHED_CORE_MAX = 0x4
PR_SCHED_CORE_SHARE_FROM = 0x3
PR_SCHED_CORE_SHARE_TO = 0x2
PR_SET_CHILD_SUBREAPER = 0x24 PR_SET_CHILD_SUBREAPER = 0x24
PR_SET_DUMPABLE = 0x4 PR_SET_DUMPABLE = 0x4
PR_SET_ENDIAN = 0x14 PR_SET_ENDIAN = 0x14
@ -1965,6 +2031,7 @@ const (
PR_SPEC_ENABLE = 0x2 PR_SPEC_ENABLE = 0x2
PR_SPEC_FORCE_DISABLE = 0x8 PR_SPEC_FORCE_DISABLE = 0x8
PR_SPEC_INDIRECT_BRANCH = 0x1 PR_SPEC_INDIRECT_BRANCH = 0x1
PR_SPEC_L1D_FLUSH = 0x2
PR_SPEC_NOT_AFFECTED = 0x0 PR_SPEC_NOT_AFFECTED = 0x0
PR_SPEC_PRCTL = 0x1 PR_SPEC_PRCTL = 0x1
PR_SPEC_STORE_BYPASS = 0x0 PR_SPEC_STORE_BYPASS = 0x0
@ -2003,6 +2070,7 @@ const (
PTRACE_GETREGSET = 0x4204 PTRACE_GETREGSET = 0x4204
PTRACE_GETSIGINFO = 0x4202 PTRACE_GETSIGINFO = 0x4202
PTRACE_GETSIGMASK = 0x420a PTRACE_GETSIGMASK = 0x420a
PTRACE_GET_RSEQ_CONFIGURATION = 0x420f
PTRACE_GET_SYSCALL_INFO = 0x420e PTRACE_GET_SYSCALL_INFO = 0x420e
PTRACE_INTERRUPT = 0x4207 PTRACE_INTERRUPT = 0x4207
PTRACE_KILL = 0x8 PTRACE_KILL = 0x8
@ -2163,6 +2231,7 @@ const (
RTM_DELNEIGH = 0x1d RTM_DELNEIGH = 0x1d
RTM_DELNETCONF = 0x51 RTM_DELNETCONF = 0x51
RTM_DELNEXTHOP = 0x69 RTM_DELNEXTHOP = 0x69
RTM_DELNEXTHOPBUCKET = 0x75
RTM_DELNSID = 0x59 RTM_DELNSID = 0x59
RTM_DELQDISC = 0x25 RTM_DELQDISC = 0x25
RTM_DELROUTE = 0x19 RTM_DELROUTE = 0x19
@ -2193,6 +2262,7 @@ const (
RTM_GETNEIGHTBL = 0x42 RTM_GETNEIGHTBL = 0x42
RTM_GETNETCONF = 0x52 RTM_GETNETCONF = 0x52
RTM_GETNEXTHOP = 0x6a RTM_GETNEXTHOP = 0x6a
RTM_GETNEXTHOPBUCKET = 0x76
RTM_GETNSID = 0x5a RTM_GETNSID = 0x5a
RTM_GETQDISC = 0x26 RTM_GETQDISC = 0x26
RTM_GETROUTE = 0x1a RTM_GETROUTE = 0x1a
@ -2201,7 +2271,7 @@ const (
RTM_GETTCLASS = 0x2a RTM_GETTCLASS = 0x2a
RTM_GETTFILTER = 0x2e RTM_GETTFILTER = 0x2e
RTM_GETVLAN = 0x72 RTM_GETVLAN = 0x72
RTM_MAX = 0x73 RTM_MAX = 0x77
RTM_NEWACTION = 0x30 RTM_NEWACTION = 0x30
RTM_NEWADDR = 0x14 RTM_NEWADDR = 0x14
RTM_NEWADDRLABEL = 0x48 RTM_NEWADDRLABEL = 0x48
@ -2215,6 +2285,7 @@ const (
RTM_NEWNEIGHTBL = 0x40 RTM_NEWNEIGHTBL = 0x40
RTM_NEWNETCONF = 0x50 RTM_NEWNETCONF = 0x50
RTM_NEWNEXTHOP = 0x68 RTM_NEWNEXTHOP = 0x68
RTM_NEWNEXTHOPBUCKET = 0x74
RTM_NEWNSID = 0x58 RTM_NEWNSID = 0x58
RTM_NEWNVLAN = 0x70 RTM_NEWNVLAN = 0x70
RTM_NEWPREFIX = 0x34 RTM_NEWPREFIX = 0x34
@ -2224,8 +2295,8 @@ const (
RTM_NEWSTATS = 0x5c RTM_NEWSTATS = 0x5c
RTM_NEWTCLASS = 0x28 RTM_NEWTCLASS = 0x28
RTM_NEWTFILTER = 0x2c RTM_NEWTFILTER = 0x2c
RTM_NR_FAMILIES = 0x19 RTM_NR_FAMILIES = 0x1a
RTM_NR_MSGTYPES = 0x64 RTM_NR_MSGTYPES = 0x68
RTM_SETDCB = 0x4f RTM_SETDCB = 0x4f
RTM_SETLINK = 0x13 RTM_SETLINK = 0x13
RTM_SETNEIGHTBL = 0x43 RTM_SETNEIGHTBL = 0x43
@ -2253,6 +2324,7 @@ const (
RTPROT_MROUTED = 0x11 RTPROT_MROUTED = 0x11
RTPROT_MRT = 0xa RTPROT_MRT = 0xa
RTPROT_NTK = 0xf RTPROT_NTK = 0xf
RTPROT_OPENR = 0x63
RTPROT_OSPF = 0xbc RTPROT_OSPF = 0xbc
RTPROT_RA = 0x9 RTPROT_RA = 0x9
RTPROT_REDIRECT = 0x1 RTPROT_REDIRECT = 0x1
@ -2283,6 +2355,7 @@ const (
SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_DISABLED = 0x0
SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_FILTER = 0x2
SECCOMP_MODE_STRICT = 0x1 SECCOMP_MODE_STRICT = 0x1
SECRETMEM_MAGIC = 0x5345434d
SECURITYFS_MAGIC = 0x73636673 SECURITYFS_MAGIC = 0x73636673
SEEK_CUR = 0x1 SEEK_CUR = 0x1
SEEK_DATA = 0x3 SEEK_DATA = 0x3
@ -2394,12 +2467,15 @@ const (
SMART_WRITE_THRESHOLDS = 0xd7 SMART_WRITE_THRESHOLDS = 0xd7
SMB_SUPER_MAGIC = 0x517b SMB_SUPER_MAGIC = 0x517b
SOCKFS_MAGIC = 0x534f434b SOCKFS_MAGIC = 0x534f434b
SOCK_BUF_LOCK_MASK = 0x3
SOCK_DCCP = 0x6 SOCK_DCCP = 0x6
SOCK_IOC_TYPE = 0x89 SOCK_IOC_TYPE = 0x89
SOCK_PACKET = 0xa SOCK_PACKET = 0xa
SOCK_RAW = 0x3 SOCK_RAW = 0x3
SOCK_RCVBUF_LOCK = 0x2
SOCK_RDM = 0x4 SOCK_RDM = 0x4
SOCK_SEQPACKET = 0x5 SOCK_SEQPACKET = 0x5
SOCK_SNDBUF_LOCK = 0x1
SOL_AAL = 0x109 SOL_AAL = 0x109
SOL_ALG = 0x117 SOL_ALG = 0x117
SOL_ATM = 0x108 SOL_ATM = 0x108
@ -2536,6 +2612,14 @@ const (
TCOFLUSH = 0x1 TCOFLUSH = 0x1
TCOOFF = 0x0 TCOOFF = 0x0
TCOON = 0x1 TCOON = 0x1
TCPOPT_EOL = 0x0
TCPOPT_MAXSEG = 0x2
TCPOPT_NOP = 0x1
TCPOPT_SACK = 0x5
TCPOPT_SACK_PERMITTED = 0x4
TCPOPT_TIMESTAMP = 0x8
TCPOPT_TSTAMP_HDR = 0x101080a
TCPOPT_WINDOW = 0x3
TCP_CC_INFO = 0x1a TCP_CC_INFO = 0x1a
TCP_CM_INQ = 0x24 TCP_CM_INQ = 0x24
TCP_CONGESTION = 0xd TCP_CONGESTION = 0xd

@ -5,7 +5,7 @@
// +build 386,linux // +build 386,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT. // Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m32 /build/_const.go // cgo -godefs -- -Wall -Werror -static -I/tmp/include -m32 /build/unix/_const.go
package unix package unix
@ -147,6 +147,7 @@ const (
NS_GET_USERNS = 0xb701 NS_GET_USERNS = 0xb701
OLCUC = 0x2 OLCUC = 0x2
ONLCR = 0x4 ONLCR = 0x4
OTPERASE = 0x400c4d19
OTPGETREGIONCOUNT = 0x40044d0e OTPGETREGIONCOUNT = 0x40044d0e
OTPGETREGIONINFO = 0x400c4d0f OTPGETREGIONINFO = 0x400c4d0f
OTPLOCK = 0x800c4d10 OTPLOCK = 0x800c4d10
@ -292,6 +293,7 @@ const (
SO_BPF_EXTENSIONS = 0x30 SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x6 SO_BROADCAST = 0x6
SO_BSDCOMPAT = 0xe SO_BSDCOMPAT = 0xe
SO_BUF_LOCK = 0x48
SO_BUSY_POLL = 0x2e SO_BUSY_POLL = 0x2e
SO_BUSY_POLL_BUDGET = 0x46 SO_BUSY_POLL_BUDGET = 0x46
SO_CNX_ADVICE = 0x35 SO_CNX_ADVICE = 0x35
@ -308,6 +310,7 @@ const (
SO_MARK = 0x24 SO_MARK = 0x24
SO_MAX_PACING_RATE = 0x2f SO_MAX_PACING_RATE = 0x2f
SO_MEMINFO = 0x37 SO_MEMINFO = 0x37
SO_NETNS_COOKIE = 0x47
SO_NOFCS = 0x2b SO_NOFCS = 0x2b
SO_OOBINLINE = 0xa SO_OOBINLINE = 0xa
SO_PASSCRED = 0x10 SO_PASSCRED = 0x10

@ -5,7 +5,7 @@
// +build amd64,linux // +build amd64,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT. // Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m64 /build/_const.go // cgo -godefs -- -Wall -Werror -static -I/tmp/include -m64 /build/unix/_const.go
package unix package unix
@ -147,6 +147,7 @@ const (
NS_GET_USERNS = 0xb701 NS_GET_USERNS = 0xb701
OLCUC = 0x2 OLCUC = 0x2
ONLCR = 0x4 ONLCR = 0x4
OTPERASE = 0x400c4d19
OTPGETREGIONCOUNT = 0x40044d0e OTPGETREGIONCOUNT = 0x40044d0e
OTPGETREGIONINFO = 0x400c4d0f OTPGETREGIONINFO = 0x400c4d0f
OTPLOCK = 0x800c4d10 OTPLOCK = 0x800c4d10
@ -293,6 +294,7 @@ const (
SO_BPF_EXTENSIONS = 0x30 SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x6 SO_BROADCAST = 0x6
SO_BSDCOMPAT = 0xe SO_BSDCOMPAT = 0xe
SO_BUF_LOCK = 0x48
SO_BUSY_POLL = 0x2e SO_BUSY_POLL = 0x2e
SO_BUSY_POLL_BUDGET = 0x46 SO_BUSY_POLL_BUDGET = 0x46
SO_CNX_ADVICE = 0x35 SO_CNX_ADVICE = 0x35
@ -309,6 +311,7 @@ const (
SO_MARK = 0x24 SO_MARK = 0x24
SO_MAX_PACING_RATE = 0x2f SO_MAX_PACING_RATE = 0x2f
SO_MEMINFO = 0x37 SO_MEMINFO = 0x37
SO_NETNS_COOKIE = 0x47
SO_NOFCS = 0x2b SO_NOFCS = 0x2b
SO_OOBINLINE = 0xa SO_OOBINLINE = 0xa
SO_PASSCRED = 0x10 SO_PASSCRED = 0x10

@ -5,7 +5,7 @@
// +build arm,linux // +build arm,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT. // Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go // cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/unix/_const.go
package unix package unix
@ -145,6 +145,7 @@ const (
NS_GET_USERNS = 0xb701 NS_GET_USERNS = 0xb701
OLCUC = 0x2 OLCUC = 0x2
ONLCR = 0x4 ONLCR = 0x4
OTPERASE = 0x400c4d19
OTPGETREGIONCOUNT = 0x40044d0e OTPGETREGIONCOUNT = 0x40044d0e
OTPGETREGIONINFO = 0x400c4d0f OTPGETREGIONINFO = 0x400c4d0f
OTPLOCK = 0x800c4d10 OTPLOCK = 0x800c4d10
@ -299,6 +300,7 @@ const (
SO_BPF_EXTENSIONS = 0x30 SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x6 SO_BROADCAST = 0x6
SO_BSDCOMPAT = 0xe SO_BSDCOMPAT = 0xe
SO_BUF_LOCK = 0x48
SO_BUSY_POLL = 0x2e SO_BUSY_POLL = 0x2e
SO_BUSY_POLL_BUDGET = 0x46 SO_BUSY_POLL_BUDGET = 0x46
SO_CNX_ADVICE = 0x35 SO_CNX_ADVICE = 0x35
@ -315,6 +317,7 @@ const (
SO_MARK = 0x24 SO_MARK = 0x24
SO_MAX_PACING_RATE = 0x2f SO_MAX_PACING_RATE = 0x2f
SO_MEMINFO = 0x37 SO_MEMINFO = 0x37
SO_NETNS_COOKIE = 0x47
SO_NOFCS = 0x2b SO_NOFCS = 0x2b
SO_OOBINLINE = 0xa SO_OOBINLINE = 0xa
SO_PASSCRED = 0x10 SO_PASSCRED = 0x10

@ -5,7 +5,7 @@
// +build arm64,linux // +build arm64,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT. // Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char /build/_const.go // cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char /build/unix/_const.go
package unix package unix
@ -148,6 +148,7 @@ const (
NS_GET_USERNS = 0xb701 NS_GET_USERNS = 0xb701
OLCUC = 0x2 OLCUC = 0x2
ONLCR = 0x4 ONLCR = 0x4
OTPERASE = 0x400c4d19
OTPGETREGIONCOUNT = 0x40044d0e OTPGETREGIONCOUNT = 0x40044d0e
OTPGETREGIONINFO = 0x400c4d0f OTPGETREGIONINFO = 0x400c4d0f
OTPLOCK = 0x800c4d10 OTPLOCK = 0x800c4d10
@ -289,6 +290,7 @@ const (
SO_BPF_EXTENSIONS = 0x30 SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x6 SO_BROADCAST = 0x6
SO_BSDCOMPAT = 0xe SO_BSDCOMPAT = 0xe
SO_BUF_LOCK = 0x48
SO_BUSY_POLL = 0x2e SO_BUSY_POLL = 0x2e
SO_BUSY_POLL_BUDGET = 0x46 SO_BUSY_POLL_BUDGET = 0x46
SO_CNX_ADVICE = 0x35 SO_CNX_ADVICE = 0x35
@ -305,6 +307,7 @@ const (
SO_MARK = 0x24 SO_MARK = 0x24
SO_MAX_PACING_RATE = 0x2f SO_MAX_PACING_RATE = 0x2f
SO_MEMINFO = 0x37 SO_MEMINFO = 0x37
SO_NETNS_COOKIE = 0x47
SO_NOFCS = 0x2b SO_NOFCS = 0x2b
SO_OOBINLINE = 0xa SO_OOBINLINE = 0xa
SO_PASSCRED = 0x10 SO_PASSCRED = 0x10

@ -5,7 +5,7 @@
// +build mips,linux // +build mips,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT. // Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go // cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/unix/_const.go
package unix package unix
@ -145,6 +145,7 @@ const (
NS_GET_USERNS = 0x2000b701 NS_GET_USERNS = 0x2000b701
OLCUC = 0x2 OLCUC = 0x2
ONLCR = 0x4 ONLCR = 0x4
OTPERASE = 0x800c4d19
OTPGETREGIONCOUNT = 0x80044d0e OTPGETREGIONCOUNT = 0x80044d0e
OTPGETREGIONINFO = 0x800c4d0f OTPGETREGIONINFO = 0x800c4d0f
OTPLOCK = 0x400c4d10 OTPLOCK = 0x400c4d10
@ -292,6 +293,7 @@ const (
SO_BPF_EXTENSIONS = 0x30 SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x20 SO_BROADCAST = 0x20
SO_BSDCOMPAT = 0xe SO_BSDCOMPAT = 0xe
SO_BUF_LOCK = 0x48
SO_BUSY_POLL = 0x2e SO_BUSY_POLL = 0x2e
SO_BUSY_POLL_BUDGET = 0x46 SO_BUSY_POLL_BUDGET = 0x46
SO_CNX_ADVICE = 0x35 SO_CNX_ADVICE = 0x35
@ -308,6 +310,7 @@ const (
SO_MARK = 0x24 SO_MARK = 0x24
SO_MAX_PACING_RATE = 0x2f SO_MAX_PACING_RATE = 0x2f
SO_MEMINFO = 0x37 SO_MEMINFO = 0x37
SO_NETNS_COOKIE = 0x47
SO_NOFCS = 0x2b SO_NOFCS = 0x2b
SO_OOBINLINE = 0x100 SO_OOBINLINE = 0x100
SO_PASSCRED = 0x11 SO_PASSCRED = 0x11

@ -5,7 +5,7 @@
// +build mips64,linux // +build mips64,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT. // Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go // cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/unix/_const.go
package unix package unix
@ -145,6 +145,7 @@ const (
NS_GET_USERNS = 0x2000b701 NS_GET_USERNS = 0x2000b701
OLCUC = 0x2 OLCUC = 0x2
ONLCR = 0x4 ONLCR = 0x4
OTPERASE = 0x800c4d19
OTPGETREGIONCOUNT = 0x80044d0e OTPGETREGIONCOUNT = 0x80044d0e
OTPGETREGIONINFO = 0x800c4d0f OTPGETREGIONINFO = 0x800c4d0f
OTPLOCK = 0x400c4d10 OTPLOCK = 0x400c4d10
@ -292,6 +293,7 @@ const (
SO_BPF_EXTENSIONS = 0x30 SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x20 SO_BROADCAST = 0x20
SO_BSDCOMPAT = 0xe SO_BSDCOMPAT = 0xe
SO_BUF_LOCK = 0x48
SO_BUSY_POLL = 0x2e SO_BUSY_POLL = 0x2e
SO_BUSY_POLL_BUDGET = 0x46 SO_BUSY_POLL_BUDGET = 0x46
SO_CNX_ADVICE = 0x35 SO_CNX_ADVICE = 0x35
@ -308,6 +310,7 @@ const (
SO_MARK = 0x24 SO_MARK = 0x24
SO_MAX_PACING_RATE = 0x2f SO_MAX_PACING_RATE = 0x2f
SO_MEMINFO = 0x37 SO_MEMINFO = 0x37
SO_NETNS_COOKIE = 0x47
SO_NOFCS = 0x2b SO_NOFCS = 0x2b
SO_OOBINLINE = 0x100 SO_OOBINLINE = 0x100
SO_PASSCRED = 0x11 SO_PASSCRED = 0x11

@ -5,7 +5,7 @@
// +build mips64le,linux // +build mips64le,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT. // Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/_const.go // cgo -godefs -- -Wall -Werror -static -I/tmp/include /build/unix/_const.go
package unix package unix
@ -145,6 +145,7 @@ const (
NS_GET_USERNS = 0x2000b701 NS_GET_USERNS = 0x2000b701
OLCUC = 0x2 OLCUC = 0x2
ONLCR = 0x4 ONLCR = 0x4
OTPERASE = 0x800c4d19
OTPGETREGIONCOUNT = 0x80044d0e OTPGETREGIONCOUNT = 0x80044d0e
OTPGETREGIONINFO = 0x800c4d0f OTPGETREGIONINFO = 0x800c4d0f
OTPLOCK = 0x400c4d10 OTPLOCK = 0x400c4d10
@ -292,6 +293,7 @@ const (
SO_BPF_EXTENSIONS = 0x30 SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x20 SO_BROADCAST = 0x20
SO_BSDCOMPAT = 0xe SO_BSDCOMPAT = 0xe
SO_BUF_LOCK = 0x48
SO_BUSY_POLL = 0x2e SO_BUSY_POLL = 0x2e
SO_BUSY_POLL_BUDGET = 0x46 SO_BUSY_POLL_BUDGET = 0x46
SO_CNX_ADVICE = 0x35 SO_CNX_ADVICE = 0x35
@ -308,6 +310,7 @@ const (
SO_MARK = 0x24 SO_MARK = 0x24
SO_MAX_PACING_RATE = 0x2f SO_MAX_PACING_RATE = 0x2f
SO_MEMINFO = 0x37 SO_MEMINFO = 0x37
SO_NETNS_COOKIE = 0x47
SO_NOFCS = 0x2b SO_NOFCS = 0x2b
SO_OOBINLINE = 0x100 SO_OOBINLINE = 0x100
SO_PASSCRED = 0x11 SO_PASSCRED = 0x11

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save