version 3 relesed
parent
ecba5e76ff
commit
623cc55dbd
@ -0,0 +1,274 @@
|
|||||||
|
package starlog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"b612.me/staros"
|
||||||
|
|
||||||
|
"b612.me/starmap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Archive interface {
|
||||||
|
ShouldArchiveNow(string, os.FileInfo) bool
|
||||||
|
NextLogFilePath(string, os.FileInfo) string
|
||||||
|
Interval() int64
|
||||||
|
HookBeforArchive() func(string, os.FileInfo) error
|
||||||
|
HookAfterArchive() func(string, string, os.FileInfo) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type logfileinfo struct {
|
||||||
|
fullpath string
|
||||||
|
pointer *os.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetLogFile(path string, logger *StarLogger, appendMode bool) error {
|
||||||
|
var fileMode int
|
||||||
|
if appendMode {
|
||||||
|
fileMode = os.O_APPEND | os.O_CREATE
|
||||||
|
} else {
|
||||||
|
fileMode = os.O_CREATE | os.O_WRONLY
|
||||||
|
}
|
||||||
|
fullpath, err := filepath.Abs(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !appendMode && staros.Exists(fullpath) {
|
||||||
|
os.Remove(fullpath)
|
||||||
|
}
|
||||||
|
fp, err := os.OpenFile(fullpath, fileMode, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if starmap.MustGet(logger.logcore.id) != nil {
|
||||||
|
logger.SetSwitching(true)
|
||||||
|
err := starmap.MustGet(logger.logcore.id).(logfileinfo).pointer.Close()
|
||||||
|
if err != nil {
|
||||||
|
logger.logcore.output = nil
|
||||||
|
logger.SetSwitching(false)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = starmap.Delete(logger.logcore.id)
|
||||||
|
if err != nil {
|
||||||
|
logger.logcore.output = nil
|
||||||
|
logger.SetSwitching(false)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = starmap.Store(logger.logcore.id, logfileinfo{
|
||||||
|
fullpath: fullpath,
|
||||||
|
pointer: fp,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
fp.Close()
|
||||||
|
logger.logcore.output = nil
|
||||||
|
logger.SetSwitching(false)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logger.SetSwitching(true)
|
||||||
|
logger.logcore.output = fp
|
||||||
|
logger.SetSwitching(false)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Close(logger *StarLogger) error {
|
||||||
|
defer logger.SetSwitching(false)
|
||||||
|
if starmap.MustGet(logger.logcore.id) != nil {
|
||||||
|
logger.SetSwitching(true)
|
||||||
|
err := starmap.MustGet(logger.logcore.id).(*os.File).Close()
|
||||||
|
if err != nil {
|
||||||
|
logger.logcore.output = nil
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = starmap.Delete(logger.logcore.id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetLogFileInfo(logger *StarLogger) (os.FileInfo, error) {
|
||||||
|
if starmap.MustGet(logger.logcore.id) != nil {
|
||||||
|
return starmap.MustGet(logger.logcore.id).(logfileinfo).pointer.Stat()
|
||||||
|
}
|
||||||
|
return nil, errors.New("logger don't have a register logfile")
|
||||||
|
}
|
||||||
|
|
||||||
|
func StartArchive(logger *StarLogger, arch Archive) error {
|
||||||
|
if starmap.MustGet("arch"+logger.logcore.id) != nil {
|
||||||
|
return errors.New("already running")
|
||||||
|
}
|
||||||
|
stopChan := make(chan int)
|
||||||
|
starmap.Store("arch"+logger.logcore.id, stopChan)
|
||||||
|
go func(stopChan chan int, arch Archive, logger *StarLogger) {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-stopChan:
|
||||||
|
return
|
||||||
|
case <-time.After(time.Second * time.Duration(arch.Interval())):
|
||||||
|
}
|
||||||
|
fileinfo, err := GetLogFileInfo(logger)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("cannot get log file info,reason is %v\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if starmap.MustGet(logger.logcore.id) == nil {
|
||||||
|
logger.Errorf("cannot get log core info from the map:no such keys\n")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fullpath := starmap.MustGet(logger.logcore.id).(logfileinfo).fullpath
|
||||||
|
if !arch.ShouldArchiveNow(fullpath, fileinfo) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
newLogPath := arch.NextLogFilePath(fullpath, fileinfo)
|
||||||
|
if arch.HookBeforArchive() != nil {
|
||||||
|
if err := arch.HookBeforArchive()(fullpath, fileinfo); err != nil {
|
||||||
|
logger.Errorf("error occur while executing hook before archive,detail is %v\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := SetLogFile(newLogPath, logger, false); err != nil {
|
||||||
|
logger.Errorf("error occur while executing coverting new log file,detail is %v\n", err)
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
logger.Debugln("Set Log Success")
|
||||||
|
}
|
||||||
|
fileinfo, err = GetLogFileInfo(logger)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("cannot get new log core info from the map:no such keys\n")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if arch.HookAfterArchive() != nil {
|
||||||
|
if err := arch.HookAfterArchive()(fullpath, newLogPath, fileinfo); err != nil {
|
||||||
|
logger.Errorf("error occur while executing hook after archive,detail is %v\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}(stopChan, arch, logger)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsArchiveRun(logger *StarLogger) bool {
|
||||||
|
if starmap.MustGet("arch"+logger.logcore.id) == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func StopArchive(logger *StarLogger) {
|
||||||
|
if starmap.MustGet("arch"+logger.logcore.id) == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
starmap.MustGet("arch" + logger.logcore.id).(chan int) <- 1
|
||||||
|
}
|
||||||
|
|
||||||
|
type ArchiveByDate struct {
|
||||||
|
interval int64
|
||||||
|
checkInterval int64
|
||||||
|
newFileNameStyle string
|
||||||
|
hookBefor func(string, os.FileInfo) error
|
||||||
|
hookAfter func(string, string, os.FileInfo) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (abd *ArchiveByDate) ShouldArchiveNow(fullpath string, info os.FileInfo) bool {
|
||||||
|
if time.Now().Unix()-staros.GetFileCreationTime(info).Unix() > abd.interval {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (abd *ArchiveByDate) NextLogFilePath(oldpath string, info os.FileInfo) string {
|
||||||
|
dir := filepath.Dir(oldpath)
|
||||||
|
newName := time.Now().Format(abd.newFileNameStyle)
|
||||||
|
return filepath.Join(dir, newName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (abd *ArchiveByDate) Interval() int64 {
|
||||||
|
return abd.checkInterval
|
||||||
|
}
|
||||||
|
|
||||||
|
func (abd *ArchiveByDate) HookBeforArchive() func(string, os.FileInfo) error {
|
||||||
|
|
||||||
|
return abd.hookBefor
|
||||||
|
}
|
||||||
|
|
||||||
|
func (abd *ArchiveByDate) HookAfterArchive() func(string, string, os.FileInfo) error {
|
||||||
|
return abd.hookAfter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (abd *ArchiveByDate) SetHookBeforArchive(f func(string, os.FileInfo) error) {
|
||||||
|
|
||||||
|
abd.hookBefor = f
|
||||||
|
}
|
||||||
|
|
||||||
|
func (abd *ArchiveByDate) SetHookAfterArchive(f func(string, string, os.FileInfo) error) {
|
||||||
|
abd.hookAfter = f
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewArchiveByDate(archInterval int64, checkInterval int64, fileStyle string, hookbefor func(string, os.FileInfo) error, hookafter func(string, string, os.FileInfo) error) *ArchiveByDate {
|
||||||
|
return &ArchiveByDate{
|
||||||
|
interval: archInterval,
|
||||||
|
checkInterval: checkInterval,
|
||||||
|
newFileNameStyle: fileStyle,
|
||||||
|
hookBefor: hookbefor,
|
||||||
|
hookAfter: hookafter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ArchiveBySize struct {
|
||||||
|
size int64
|
||||||
|
checkInterval int64
|
||||||
|
newFileNameStyle string
|
||||||
|
hookBefor func(string, os.FileInfo) error
|
||||||
|
hookAfter func(string, string, os.FileInfo) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (abd *ArchiveBySize) ShouldArchiveNow(fullpath string, info os.FileInfo) bool {
|
||||||
|
if info.Size() > abd.size {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (abd *ArchiveBySize) NextLogFilePath(oldpath string, info os.FileInfo) string {
|
||||||
|
dir := filepath.Dir(oldpath)
|
||||||
|
newName := time.Now().Format(abd.newFileNameStyle)
|
||||||
|
return filepath.Join(dir, newName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (abd *ArchiveBySize) Interval() int64 {
|
||||||
|
return abd.checkInterval
|
||||||
|
}
|
||||||
|
|
||||||
|
func (abd *ArchiveBySize) HookBeforArchive() func(string, os.FileInfo) error {
|
||||||
|
|
||||||
|
return abd.hookBefor
|
||||||
|
}
|
||||||
|
|
||||||
|
func (abd *ArchiveBySize) HookAfterArchive() func(string, string, os.FileInfo) error {
|
||||||
|
return abd.hookAfter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (abd *ArchiveBySize) SetHookBeforArchive(f func(string, os.FileInfo) error) {
|
||||||
|
|
||||||
|
abd.hookBefor = f
|
||||||
|
}
|
||||||
|
|
||||||
|
func (abd *ArchiveBySize) SetHookAfterArchive(f func(string, string, os.FileInfo) error) {
|
||||||
|
abd.hookAfter = f
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewArchiveBySize(size int64, checkInterval int64, fileStyle string, hookbefor func(string, os.FileInfo) error, hookafter func(string, string, os.FileInfo) error) *ArchiveBySize {
|
||||||
|
return &ArchiveBySize{
|
||||||
|
size: size,
|
||||||
|
checkInterval: checkInterval,
|
||||||
|
newFileNameStyle: fileStyle,
|
||||||
|
hookBefor: hookbefor,
|
||||||
|
hookAfter: hookafter,
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,249 @@
|
|||||||
|
package starlog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (logger *starlog) build(thread string, isStd bool, handler func([]Attr, string), level int, logDetail string) {
|
||||||
|
logger.mu.Lock()
|
||||||
|
defer logger.mu.Unlock()
|
||||||
|
var skip, line int = 3, 0
|
||||||
|
var funcname, fileName string
|
||||||
|
now := time.Now()
|
||||||
|
if isStd {
|
||||||
|
skip++
|
||||||
|
}
|
||||||
|
if logger.showDeatilFile || logger.showFuncName {
|
||||||
|
pc, fName, codeln, ok := runtime.Caller(skip)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
line = codeln
|
||||||
|
funcname = runtime.FuncForPC(pc).Name()
|
||||||
|
funcname = filepath.Ext(funcname)
|
||||||
|
funcname = strings.TrimPrefix(funcname, ".")
|
||||||
|
fileName = filepath.Base(fName)
|
||||||
|
}
|
||||||
|
|
||||||
|
y, m, d := now.Date()
|
||||||
|
h, i, s := now.Clock()
|
||||||
|
micro := now.Nanosecond() / 1e3
|
||||||
|
logStr := fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d.%06d", y, m, d, h, i, s, micro)
|
||||||
|
if logger.showDeatilFile {
|
||||||
|
logStr += " " + fileName + ":" + strconv.Itoa(line)
|
||||||
|
}
|
||||||
|
if logger.showFuncName {
|
||||||
|
logStr += " <" + funcname + ">"
|
||||||
|
}
|
||||||
|
if logger.showThread {
|
||||||
|
logStr += " |" + thread + "|"
|
||||||
|
}
|
||||||
|
if logger.showLevel {
|
||||||
|
logStr += " " + `[` + levels[level] + `]`
|
||||||
|
}
|
||||||
|
logStr += " " + logDetail
|
||||||
|
if logger.showStd {
|
||||||
|
if !logger.showColor {
|
||||||
|
fmt.Print(logStr)
|
||||||
|
} else {
|
||||||
|
//logcolor := NewColor(logger.colorList[level]...)
|
||||||
|
logger.colorMe[level].Fprint(stdScreen, logStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if handler != nil {
|
||||||
|
stacks.Push(logTransfer{
|
||||||
|
handlerFunc: handler,
|
||||||
|
colors: logger.colorList[level],
|
||||||
|
logStr: logStr,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if !logger.stopWriter {
|
||||||
|
logger.write(logStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) write(logStr string) {
|
||||||
|
if logger.output == nil || logger.stopWriter {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var count int = 0
|
||||||
|
for logger.switching {
|
||||||
|
time.Sleep(time.Millisecond * 100)
|
||||||
|
count++
|
||||||
|
if count > 50 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if logger.output == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
logger.output.Write([]byte(logStr))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) print(str ...interface{}) string {
|
||||||
|
return fmt.Sprint(str...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) printf(format string, str ...interface{}) string {
|
||||||
|
return fmt.Sprintf(format, str...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) println(str ...interface{}) string {
|
||||||
|
return fmt.Sprintln(str...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Debug(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
logger.build(thread, isStd, handler, LvDebug, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Debugf(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
logger.build(thread, isStd, handler, LvDebug, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Debugln(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
logger.build(thread, isStd, handler, LvDebug, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Info(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
logger.build(thread, isStd, handler, LvInfo, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Infof(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
logger.build(thread, isStd, handler, LvInfo, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Infoln(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
logger.build(thread, isStd, handler, LvInfo, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Notice(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
logger.build(thread, isStd, handler, LvNotice, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Noticef(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
logger.build(thread, isStd, handler, LvNotice, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Noticeln(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
logger.build(thread, isStd, handler, LvNotice, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Warning(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
logger.build(thread, isStd, handler, LvWarning, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Warningf(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
logger.build(thread, isStd, handler, LvWarning, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Warningln(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
logger.build(thread, isStd, handler, LvWarning, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Error(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
logger.build(thread, isStd, handler, LvError, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Errorf(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
logger.build(thread, isStd, handler, LvError, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Errorln(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
logger.build(thread, isStd, handler, LvError, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Critical(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
logger.build(thread, isStd, handler, LvCritical, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Criticalf(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
logger.build(thread, isStd, handler, LvCritical, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Criticalln(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
logger.build(thread, isStd, handler, LvCritical, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Fatal(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
logger.build(thread, isStd, handler, LvFatal, strs)
|
||||||
|
os.Exit(9)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Fatalf(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
logger.build(thread, isStd, handler, LvFatal, strs)
|
||||||
|
os.Exit(9)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Fatalln(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
logger.build(thread, isStd, handler, LvFatal, strs)
|
||||||
|
os.Exit(9)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Panic(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
logger.build(thread, isStd, handler, LvPanic, strs)
|
||||||
|
panic(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Panicf(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
logger.build(thread, isStd, handler, LvPanic, strs)
|
||||||
|
panic(fmt.Sprintf(format, str...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Panicln(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
logger.build(thread, isStd, handler, LvPanic, strs)
|
||||||
|
panic(fmt.Sprintln(str...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Print(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
if logger.showStd {
|
||||||
|
fmt.Print(strs)
|
||||||
|
}
|
||||||
|
logger.write(strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Printf(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
if logger.showStd {
|
||||||
|
fmt.Print(strs)
|
||||||
|
}
|
||||||
|
logger.write(strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *starlog) Println(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
if logger.showStd {
|
||||||
|
fmt.Print(strs)
|
||||||
|
}
|
||||||
|
logger.write(strs)
|
||||||
|
}
|
@ -0,0 +1,271 @@
|
|||||||
|
package starlog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"math/rand"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Std *StarLogger
|
||||||
|
var stdmu sync.Mutex
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
stackStopChan = make(chan int)
|
||||||
|
StartStacks()
|
||||||
|
Std = NewStarlog(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetShowColor(val bool) {
|
||||||
|
Std.SetShowColor(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetShowColor() bool {
|
||||||
|
return Std.GetShowColor()
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetLevelColor(level int, color []Attr) {
|
||||||
|
Std.SetLevelColor(level, color)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetLevelColor(level int) []Attr {
|
||||||
|
return Std.GetLevelColor(level)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Debug(str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Debug(str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Debugf(format string, str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Debugf(format, str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Debugln(str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Debugln(str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Info(str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Info(str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Infof(format string, str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Infof(format, str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Infoln(str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Infoln(str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Notice(str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Notice(str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Noticef(format string, str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Noticef(format, str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Noticeln(str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Noticeln(str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Warning(str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Warning(str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Warningf(format string, str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Warningf(format, str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Warningln(str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Warningln(str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Error(str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Error(str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Errorf(format string, str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Errorf(format, str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Errorln(str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Errorln(str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Critical(str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Critical(str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Criticalf(format string, str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Criticalf(format, str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Criticalln(str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Criticalln(str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fatal(str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Fatal(str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fatalf(format string, str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Fatalf(format, str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Panicln(str ...interface{}) {
|
||||||
|
stdmu.Lock()
|
||||||
|
defer stdmu.Unlock()
|
||||||
|
Std.isStd = true
|
||||||
|
Std.Fatal(str...)
|
||||||
|
Std.isStd = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetWriter(wr io.Writer) {
|
||||||
|
Std.SetWriter(wr)
|
||||||
|
}
|
||||||
|
func GetWriter() io.Writer {
|
||||||
|
return Std.GetWriter()
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetHandler(f func([]Attr, string)) {
|
||||||
|
Std.SetHandler(f)
|
||||||
|
}
|
||||||
|
func GetHandler() func([]Attr, string) {
|
||||||
|
return Std.GetHandler()
|
||||||
|
}
|
||||||
|
func SetSwitching(sw bool) {
|
||||||
|
Std.SetSwitching(sw)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetShowOriginFile(val bool) {
|
||||||
|
Std.SetShowOriginFile(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetShowOriginFile() bool {
|
||||||
|
return Std.GetShowOriginFile()
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetShowFuncName(val bool) {
|
||||||
|
Std.logcore.showFuncName = val
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetShowFuncName() bool {
|
||||||
|
return Std.logcore.showFuncName
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetShowLevel(val bool) {
|
||||||
|
Std.SetShowLevel(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetShowLevel() bool {
|
||||||
|
return Std.GetShowLevel()
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetShowFlag(val bool) {
|
||||||
|
Std.SetShowFlag(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetShowFlag() bool {
|
||||||
|
return Std.GetShowFlag()
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetShowStd(val bool) {
|
||||||
|
Std.SetShowStd(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetShowStd() bool {
|
||||||
|
return Std.GetShowStd()
|
||||||
|
}
|
||||||
|
|
||||||
|
func StopWrite() {
|
||||||
|
Std.StopWrite()
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnbaleWrite() {
|
||||||
|
Std.EnbaleWrite()
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsWriteStoed() bool {
|
||||||
|
return Std.IsWriteStoed()
|
||||||
|
}
|
@ -1,704 +1,175 @@
|
|||||||
package starlog
|
package starlog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"b612.me/starmap"
|
|
||||||
|
|
||||||
"github.com/mattn/go-colorable"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
func (logger *StarLogger) SetShowColor(val bool) {
|
||||||
LvDebug = iota
|
logger.logcore.showColor = val
|
||||||
LvInfo
|
|
||||||
LvNotice
|
|
||||||
LvWarning
|
|
||||||
LvError
|
|
||||||
LvCritical
|
|
||||||
LvPanic
|
|
||||||
LvFatal
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
levels = map[int]string{
|
|
||||||
LvDebug: "DEBUG",
|
|
||||||
LvInfo: "INFO",
|
|
||||||
LvNotice: "NOTICE",
|
|
||||||
LvWarning: "WARNING",
|
|
||||||
LvError: "ERROR",
|
|
||||||
LvCritical: "CRITICAL",
|
|
||||||
LvPanic: "PANIC",
|
|
||||||
LvFatal: "FATAL",
|
|
||||||
}
|
|
||||||
Colors = map[int][]Attr{
|
|
||||||
LvDebug: []Attr{FgWhite},
|
|
||||||
LvInfo: []Attr{FgGreen},
|
|
||||||
LvNotice: []Attr{FgBlue},
|
|
||||||
LvWarning: []Attr{FgYellow},
|
|
||||||
LvError: []Attr{FgMagenta},
|
|
||||||
LvCritical: []Attr{FgRed, Bold},
|
|
||||||
LvPanic: []Attr{FgRed, Bold},
|
|
||||||
LvFatal: []Attr{FgRed},
|
|
||||||
}
|
|
||||||
stdLock sync.Mutex
|
|
||||||
logmaps sync.Map
|
|
||||||
)
|
|
||||||
|
|
||||||
type StarLogger struct {
|
|
||||||
mu *sync.Mutex
|
|
||||||
lock *sync.Mutex
|
|
||||||
Flag string
|
|
||||||
out io.Writer
|
|
||||||
ShowLine bool
|
|
||||||
ShowLevel bool
|
|
||||||
ShowFunc bool
|
|
||||||
ShowThread bool
|
|
||||||
DoWrite bool
|
|
||||||
DoShow bool
|
|
||||||
switching bool
|
|
||||||
isStd bool
|
|
||||||
//handleFunc
|
|
||||||
stopChan chan int
|
|
||||||
setChan chan int
|
|
||||||
outshow io.Writer
|
|
||||||
LogLevel int
|
|
||||||
handleFunc func([]Attr, string)
|
|
||||||
StdFuncColor bool
|
|
||||||
logbuf string
|
|
||||||
BufSize int
|
|
||||||
stacks starmap.StarStack
|
|
||||||
}
|
|
||||||
|
|
||||||
type logTran struct {
|
|
||||||
color []Attr
|
|
||||||
log string
|
|
||||||
}
|
|
||||||
|
|
||||||
var Std = New(nil)
|
|
||||||
var StdFile *os.File
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
Std.DoShow = true
|
|
||||||
Std.Flag = "MAN"
|
|
||||||
Std.isStd = true
|
|
||||||
logmaps.Store("std", Std)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Close() error {
|
|
||||||
if StdFile == nil {
|
|
||||||
return errors.New("File not Open")
|
|
||||||
}
|
|
||||||
if err := Std.Flush(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return StdFile.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(out io.Writer) *StarLogger {
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
|
||||||
logger := new(StarLogger)
|
|
||||||
logger.DoShow = false
|
|
||||||
logger.mu = new(sync.Mutex)
|
|
||||||
logger.lock = new(sync.Mutex)
|
|
||||||
logger.ShowLevel = true
|
|
||||||
logger.ShowLine = true
|
|
||||||
logger.DoWrite = true
|
|
||||||
logger.ShowThread = true
|
|
||||||
logger.ShowFunc = false
|
|
||||||
logger.out = out
|
|
||||||
logger.outshow = colorable.NewColorableStdout()
|
|
||||||
logger.StdFuncColor = true
|
|
||||||
logger.BufSize = 0
|
|
||||||
logger.Flag = "MAN"
|
|
||||||
logger.stopChan, logger.setChan = make(chan int), make(chan int)
|
|
||||||
go logger.runTransfer()
|
|
||||||
logmaps.Store(fmt.Sprint(time.Now().UnixNano()), logger)
|
|
||||||
return logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) SetHandleFunc(funcs func([]Attr, string)) {
|
|
||||||
if logger.handleFunc == nil {
|
|
||||||
logger.setChan <- 1
|
|
||||||
}
|
|
||||||
logger.handleFunc = funcs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) GetHandleFunc() func([]Attr, string) {
|
|
||||||
return logger.handleFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) Flush() error {
|
|
||||||
logger.mu.Lock()
|
|
||||||
defer logger.mu.Unlock()
|
|
||||||
logger.write(logger.logbuf)
|
|
||||||
logger.logbuf = ""
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) Close() error {
|
|
||||||
logger.stopChan <- 1
|
|
||||||
logmaps.Range(func(k, v interface{}) bool {
|
|
||||||
if v.(*StarLogger) == logger {
|
|
||||||
logmaps.Delete(k)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
logger = nil
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (logger *StarLogger) runTransfer() {
|
|
||||||
if logger.handleFunc == nil {
|
|
||||||
select {
|
|
||||||
case <-logger.stopChan:
|
|
||||||
return
|
|
||||||
case <-logger.setChan:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-logger.stopChan:
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
if logger.handleFunc == nil {
|
|
||||||
time.Sleep(time.Millisecond * 100)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
poped := logger.stacks.MustPop()
|
|
||||||
if poped == nil {
|
|
||||||
time.Sleep(time.Millisecond * 20)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
val := poped.(logTran)
|
|
||||||
logger.handleFunc(val.color, val.log)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFlag() *StarLogger {
|
|
||||||
return Std.NewFlag()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) NewFlag() *StarLogger {
|
|
||||||
logger2 := new(StarLogger)
|
|
||||||
logger2.out = logger.out
|
|
||||||
logger2.ShowThread = logger.ShowThread
|
|
||||||
logger2.ShowFunc = logger.ShowFunc
|
|
||||||
logger2.DoShow = logger.DoShow
|
|
||||||
logger2.ShowLevel = logger.ShowLevel
|
|
||||||
logger2.ShowLine = logger.ShowLine
|
|
||||||
logger2.DoWrite = logger.DoWrite
|
|
||||||
logger2.outshow = logger.outshow
|
|
||||||
logger2.mu = logger.mu
|
|
||||||
logger2.lock = logger.lock
|
|
||||||
logger2.Flag = string([]byte{uint8(rand.Intn(26) + 65), uint8(rand.Intn(26) + 65), uint8(rand.Intn(26) + 65)})
|
|
||||||
logger2.stopChan, logger2.setChan = make(chan int), make(chan int)
|
|
||||||
logger2.handleFunc = logger.handleFunc
|
|
||||||
go logger2.runTransfer()
|
|
||||||
if logger2.Flag == "MAN" {
|
|
||||||
logger2.Flag = "RYZ"
|
|
||||||
}
|
|
||||||
logmaps.Store(fmt.Sprint(time.Now().UnixNano()), logger2)
|
|
||||||
return logger2
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) write(logstr string) {
|
|
||||||
if (!logger.DoWrite) || (logger.out == nil) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
i := 0
|
|
||||||
for logger.switching {
|
|
||||||
time.Sleep(time.Millisecond * 100)
|
|
||||||
i++
|
|
||||||
if i > 20 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if &(logger.out) == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
logger.out.Write([]byte(logstr))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) OutPut(logstr string) {
|
|
||||||
logger.out.Write([]byte(logstr))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) output(level int, logstr string) {
|
|
||||||
var logs string
|
|
||||||
var skip int = 2
|
|
||||||
logger.mu.Lock()
|
|
||||||
defer logger.mu.Unlock()
|
|
||||||
if level < logger.LogLevel {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if logger.isStd {
|
|
||||||
skip++
|
|
||||||
}
|
|
||||||
logger.isStd = false
|
|
||||||
pc, fname, line, ok := runtime.Caller(skip)
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
funcname := runtime.FuncForPC(pc).Name()
|
|
||||||
funcname = filepath.Ext(funcname)
|
|
||||||
funcname = strings.TrimPrefix(funcname, ".")
|
|
||||||
fname = filepath.Base(fname)
|
|
||||||
date := time.Now().Format("2006-01-02 15:04:05.000 Mon")
|
|
||||||
logs = date
|
|
||||||
if logger.ShowLine {
|
|
||||||
logs += " " + fname + ":" + strconv.Itoa(line)
|
|
||||||
}
|
|
||||||
if logger.ShowFunc {
|
|
||||||
logs += " <" + funcname + ">"
|
|
||||||
}
|
|
||||||
if logger.ShowThread {
|
|
||||||
logs += " |" + logger.Flag + "|"
|
|
||||||
}
|
|
||||||
if logger.ShowLevel {
|
|
||||||
logs += " " + `[` + levels[level] + `]`
|
|
||||||
}
|
|
||||||
logs += " " + logstr
|
|
||||||
if logger.DoShow {
|
|
||||||
logcolor := NewColor(Colors[level]...)
|
|
||||||
logcolor.Fprint(logger.outshow, logs)
|
|
||||||
}
|
|
||||||
if logger.handleFunc != nil {
|
|
||||||
//logger.handleFunc(Colors[level], logs)
|
|
||||||
logger.stacks.Push(logTran{Colors[level], logs})
|
|
||||||
}
|
|
||||||
if logger.DoWrite {
|
|
||||||
if logger.BufSize == 0 {
|
|
||||||
logger.write(logs)
|
|
||||||
} else {
|
|
||||||
logger.logbuf += logs
|
|
||||||
if len(logger.logbuf) >= logger.BufSize {
|
|
||||||
logger.write(logs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) Debug(str ...interface{}) {
|
|
||||||
strs := fmt.Sprint(str...)
|
|
||||||
logger.output(LvDebug, strs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Debug(str ...interface{}) {
|
|
||||||
stdLock.Lock()
|
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Debug(str...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *StarLogger) Debugf(format string, str ...interface{}) {
|
func (logger *StarLogger) GetShowColor() bool {
|
||||||
strs := fmt.Sprintf(format, str...)
|
return logger.logcore.showColor
|
||||||
logger.output(LvDebug, strs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Debugf(format string, str ...interface{}) {
|
func (logger *StarLogger) SetLevelColor(level int, color []Attr) {
|
||||||
stdLock.Lock()
|
logger.logcore.colorList[level] = color
|
||||||
defer stdLock.Unlock()
|
logger.logcore.colorMe[level] = NewColor(color...)
|
||||||
Std.isStd = true
|
|
||||||
Std.Debugf(format, str...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *StarLogger) Debugln(str ...interface{}) {
|
func (logger *StarLogger) GetLevelColor(level int) []Attr {
|
||||||
strs := fmt.Sprintln(str...)
|
return logger.logcore.colorList[level]
|
||||||
logger.output(LvDebug, strs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Debugln(str ...interface{}) {
|
func (logger *StarLogger) SetWriter(wr io.Writer) {
|
||||||
stdLock.Lock()
|
logger.logcore.output = wr
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Debugln(str...)
|
|
||||||
}
|
}
|
||||||
|
func (logger *StarLogger) GetWriter() io.Writer {
|
||||||
func (logger *StarLogger) Info(str ...interface{}) {
|
return logger.logcore.output
|
||||||
strs := fmt.Sprint(str...)
|
|
||||||
logger.output(LvInfo, strs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Info(str ...interface{}) {
|
func (logger *StarLogger) SetHandler(f func([]Attr, string)) {
|
||||||
stdLock.Lock()
|
logger.handlerFunc = f
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Info(str...)
|
|
||||||
}
|
}
|
||||||
|
func (logger *StarLogger) GetHandler() func([]Attr, string) {
|
||||||
func (logger *StarLogger) Infof(format string, str ...interface{}) {
|
return logger.handlerFunc
|
||||||
strs := fmt.Sprintf(format, str...)
|
|
||||||
logger.output(LvInfo, strs)
|
|
||||||
}
|
}
|
||||||
|
func (logger *StarLogger) SetSwitching(sw bool) {
|
||||||
func Infof(format string, str ...interface{}) {
|
logger.logcore.switching = sw
|
||||||
stdLock.Lock()
|
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Infof(format, str...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *StarLogger) Infoln(str ...interface{}) {
|
func (logger *StarLogger) SetShowOriginFile(val bool) {
|
||||||
strs := fmt.Sprintln(str...)
|
logger.logcore.showDeatilFile = val
|
||||||
logger.output(LvInfo, strs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Infoln(str ...interface{}) {
|
func (logger *StarLogger) GetShowOriginFile() bool {
|
||||||
stdLock.Lock()
|
return logger.logcore.showDeatilFile
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Infoln(str...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *StarLogger) Notice(str ...interface{}) {
|
func (logger *StarLogger) SetShowFuncName(val bool) {
|
||||||
strs := fmt.Sprint(str...)
|
logger.logcore.showFuncName = val
|
||||||
logger.output(LvNotice, strs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Notice(str ...interface{}) {
|
func (logger *StarLogger) GetShowFuncName() bool {
|
||||||
stdLock.Lock()
|
return logger.logcore.showFuncName
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Notice(str...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *StarLogger) Noticef(format string, str ...interface{}) {
|
func (logger *StarLogger) SetShowLevel(val bool) {
|
||||||
strs := fmt.Sprintf(format, str...)
|
logger.logcore.showLevel = val
|
||||||
logger.output(LvNotice, strs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Noticef(format string, str ...interface{}) {
|
func (logger *StarLogger) GetShowLevel() bool {
|
||||||
stdLock.Lock()
|
return logger.logcore.showLevel
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Noticef(format, str...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *StarLogger) Noticeln(str ...interface{}) {
|
func (logger *StarLogger) SetShowFlag(val bool) {
|
||||||
strs := fmt.Sprintln(str...)
|
logger.logcore.showThread = val
|
||||||
logger.output(LvNotice, strs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Noticeln(str ...interface{}) {
|
func (logger *StarLogger) GetShowFlag() bool {
|
||||||
stdLock.Lock()
|
return logger.logcore.showThread
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Noticeln(str...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *StarLogger) Warning(str ...interface{}) {
|
func (logger *StarLogger) SetShowStd(val bool) {
|
||||||
strs := fmt.Sprint(str...)
|
logger.logcore.showStd = val
|
||||||
logger.output(LvWarning, strs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Warning(str ...interface{}) {
|
func (logger *StarLogger) GetShowStd() bool {
|
||||||
stdLock.Lock()
|
return logger.logcore.showStd
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Warning(str...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *StarLogger) Warningf(format string, str ...interface{}) {
|
func (logger *StarLogger) StopWrite() {
|
||||||
strs := fmt.Sprintf(format, str...)
|
logger.logcore.stopWriter = true
|
||||||
logger.output(LvWarning, strs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Warningf(format string, str ...interface{}) {
|
func (logger *StarLogger) EnbaleWrite() {
|
||||||
stdLock.Lock()
|
logger.logcore.stopWriter = false
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Warningf(format, str...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *StarLogger) Warningln(str ...interface{}) {
|
func (logger *StarLogger) IsWriteStoed() bool {
|
||||||
strs := fmt.Sprintln(str...)
|
return logger.logcore.stopWriter
|
||||||
logger.output(LvWarning, strs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Warningln(str ...interface{}) {
|
func (logger *StarLogger) Debug(str ...interface{}) {
|
||||||
stdLock.Lock()
|
logger.logcore.Debug(logger.thread, logger.isStd, logger.handlerFunc, str...)
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Warningln(str...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) Error(str ...interface{}) {
|
|
||||||
strs := fmt.Sprint(str...)
|
|
||||||
logger.output(LvError, strs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Error(str ...interface{}) {
|
|
||||||
stdLock.Lock()
|
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Error(str...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) Errorf(format string, str ...interface{}) {
|
|
||||||
strs := fmt.Sprintf(format, str...)
|
|
||||||
logger.output(LvError, strs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Errorf(format string, str ...interface{}) {
|
|
||||||
stdLock.Lock()
|
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Errorf(format, str...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) Errorln(str ...interface{}) {
|
|
||||||
strs := fmt.Sprintln(str...)
|
|
||||||
logger.output(LvError, strs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Errorln(str ...interface{}) {
|
|
||||||
stdLock.Lock()
|
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Errorln(str...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) Critical(str ...interface{}) {
|
|
||||||
strs := fmt.Sprint(str...)
|
|
||||||
logger.output(LvCritical, strs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Critical(str ...interface{}) {
|
|
||||||
stdLock.Lock()
|
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Critical(str...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) Criticalf(format string, str ...interface{}) {
|
|
||||||
strs := fmt.Sprintf(format, str...)
|
|
||||||
logger.output(LvCritical, strs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Criticalf(format string, str ...interface{}) {
|
|
||||||
stdLock.Lock()
|
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Criticalf(format, str...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) Criticalln(str ...interface{}) {
|
|
||||||
strs := fmt.Sprintln(str...)
|
|
||||||
logger.output(LvCritical, strs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Criticalln(str ...interface{}) {
|
|
||||||
stdLock.Lock()
|
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Criticalln(str...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) Fatal(str ...interface{}) {
|
|
||||||
strs := fmt.Sprint(str...)
|
|
||||||
logger.output(LvFatal, strs)
|
|
||||||
os.Exit(9)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Fatal(str ...interface{}) {
|
|
||||||
stdLock.Lock()
|
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Fatal(str...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) Fatalf(format string, str ...interface{}) {
|
|
||||||
strs := fmt.Sprintf(format, str...)
|
|
||||||
logger.output(LvFatal, strs)
|
|
||||||
os.Exit(9)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Fatalf(format string, str ...interface{}) {
|
|
||||||
stdLock.Lock()
|
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Fatalf(format, str...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) Fatalln(str ...interface{}) {
|
|
||||||
strs := fmt.Sprintln(str...)
|
|
||||||
logger.output(LvFatal, strs)
|
|
||||||
os.Exit(9)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Fatalln(str ...interface{}) {
|
|
||||||
stdLock.Lock()
|
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Fatalln(str...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *StarLogger) Panic(str ...interface{}) {
|
|
||||||
strs := fmt.Sprint(str...)
|
|
||||||
logger.output(LvPanic, strs)
|
|
||||||
panic(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Panic(str ...interface{}) {
|
|
||||||
stdLock.Lock()
|
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Panic(str...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *StarLogger) Panicf(format string, str ...interface{}) {
|
func (logger *StarLogger) Debugf(format string, str ...interface{}) {
|
||||||
strs := fmt.Sprintf(format, str...)
|
logger.logcore.Debugf(logger.thread, logger.isStd, logger.handlerFunc, format, str...)
|
||||||
logger.output(LvPanic, strs)
|
|
||||||
panic(fmt.Sprintf(format, str...))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Panicf(format string, str ...interface{}) {
|
func (logger *StarLogger) Debugln(str ...interface{}) {
|
||||||
stdLock.Lock()
|
logger.logcore.Debugln(logger.thread, logger.isStd, logger.handlerFunc, str...)
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Panicf(format, str...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *StarLogger) Panicln(str ...interface{}) {
|
func (logger *StarLogger) Info(str ...interface{}) {
|
||||||
strs := fmt.Sprintln(str...)
|
logger.logcore.Info(logger.thread, logger.isStd, logger.handlerFunc, str...)
|
||||||
logger.output(LvPanic, strs)
|
|
||||||
panic(fmt.Sprintln(str...))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Panicln(str ...interface{}) {
|
func (logger *StarLogger) Infof(format string, str ...interface{}) {
|
||||||
stdLock.Lock()
|
logger.logcore.Infof(logger.thread, logger.isStd, logger.handlerFunc, format, str...)
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Panicln(str...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *StarLogger) Print(str ...interface{}) {
|
func (logger *StarLogger) Infoln(str ...interface{}) {
|
||||||
logger.lock.Lock()
|
logger.logcore.Infoln(logger.thread, logger.isStd, logger.handlerFunc, str...)
|
||||||
defer logger.lock.Unlock()
|
|
||||||
strs := fmt.Sprint(str...)
|
|
||||||
logger.OutPut(strs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Print(str ...interface{}) {
|
func (logger *StarLogger) Notice(str ...interface{}) {
|
||||||
stdLock.Lock()
|
logger.logcore.Notice(logger.thread, logger.isStd, logger.handlerFunc, str...)
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Print(str...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *StarLogger) Printf(format string, str ...interface{}) {
|
func (logger *StarLogger) Noticef(format string, str ...interface{}) {
|
||||||
logger.lock.Lock()
|
logger.logcore.Noticef(logger.thread, logger.isStd, logger.handlerFunc, format, str...)
|
||||||
defer logger.lock.Unlock()
|
|
||||||
strs := fmt.Sprintf(format, str...)
|
|
||||||
logger.OutPut(strs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Printf(format string, str ...interface{}) {
|
func (logger *StarLogger) Noticeln(str ...interface{}) {
|
||||||
stdLock.Lock()
|
logger.logcore.Noticeln(logger.thread, logger.isStd, logger.handlerFunc, str...)
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Printf(format, str...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *StarLogger) Println(str ...interface{}) {
|
func (logger *StarLogger) Warning(str ...interface{}) {
|
||||||
logger.lock.Lock()
|
logger.logcore.Warning(logger.thread, logger.isStd, logger.handlerFunc, str...)
|
||||||
defer logger.lock.Unlock()
|
|
||||||
strs := fmt.Sprintln(str...)
|
|
||||||
logger.OutPut(strs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Println(str ...interface{}) {
|
func (logger *StarLogger) Warningf(format string, str ...interface{}) {
|
||||||
stdLock.Lock()
|
logger.logcore.Warningf(logger.thread, logger.isStd, logger.handlerFunc, format, str...)
|
||||||
defer stdLock.Unlock()
|
|
||||||
Std.isStd = true
|
|
||||||
Std.Println(str...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func StdPrint(c []Attr, str ...interface{}) {
|
func (logger *StarLogger) Warningln(str ...interface{}) {
|
||||||
Std.lock.Lock()
|
logger.logcore.Warningln(logger.thread, logger.isStd, logger.handlerFunc, str...)
|
||||||
defer Std.lock.Unlock()
|
|
||||||
colorstr := NewColor(c...)
|
|
||||||
colorstr.Print(str...)
|
|
||||||
if Std.StdFuncColor && Std.handleFunc != nil {
|
|
||||||
go Std.handleFunc(c, fmt.Sprint(str...))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func StdPrintf(c []Attr, format string, str ...interface{}) {
|
func (logger *StarLogger) Error(str ...interface{}) {
|
||||||
Std.lock.Lock()
|
logger.logcore.Error(logger.thread, logger.isStd, logger.handlerFunc, str...)
|
||||||
defer Std.lock.Unlock()
|
|
||||||
colorstr := NewColor(c...)
|
|
||||||
colorstr.Printf(format, str...)
|
|
||||||
if Std.StdFuncColor && Std.handleFunc != nil {
|
|
||||||
go Std.handleFunc(c, fmt.Sprintf(format, str...))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func StdPrintln(c []Attr, str ...interface{}) {
|
func (logger *StarLogger) Errorf(format string, str ...interface{}) {
|
||||||
Std.lock.Lock()
|
logger.logcore.Errorf(logger.thread, logger.isStd, logger.handlerFunc, format, str...)
|
||||||
defer Std.lock.Unlock()
|
|
||||||
colorstr := NewColor(c...)
|
|
||||||
colorstr.Println(str...)
|
|
||||||
if Std.StdFuncColor && Std.handleFunc != nil {
|
|
||||||
go Std.handleFunc(c, fmt.Sprintln(str...))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *StarLogger) SwitchOut(out io.Writer) {
|
func (logger *StarLogger) Errorln(str ...interface{}) {
|
||||||
logger.lock.Lock()
|
logger.logcore.Errorln(logger.thread, logger.isStd, logger.handlerFunc, str...)
|
||||||
defer logger.lock.Unlock()
|
|
||||||
logger.switching = true
|
|
||||||
logger.out = out
|
|
||||||
logger.switching = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *StarLogger) SetSwitching(out bool) {
|
func (logger *StarLogger) Critical(str ...interface{}) {
|
||||||
logger.lock.Lock()
|
logger.logcore.Critical(logger.thread, logger.isStd, logger.handlerFunc, str...)
|
||||||
defer logger.lock.Unlock()
|
|
||||||
logger.switching = out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetSwitchingAll(out bool) {
|
func (logger *StarLogger) Criticalf(format string, str ...interface{}) {
|
||||||
logmaps.Range(func(k, v interface{}) bool {
|
logger.logcore.Criticalf(logger.thread, logger.isStd, logger.handlerFunc, format, str...)
|
||||||
v.(*StarLogger).SetSwitching(out)
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SwitchOutAll(out io.Writer) {
|
func (logger *StarLogger) Criticalln(str ...interface{}) {
|
||||||
logmaps.Range(func(k, v interface{}) bool {
|
logger.logcore.Criticalln(logger.thread, logger.isStd, logger.handlerFunc, str...)
|
||||||
v.(*StarLogger).SwitchOut(out)
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SethandleFuncAll(fn func([]Attr, string)) {
|
func (logger *StarLogger) Fatal(str ...interface{}) {
|
||||||
logmaps.Range(func(k, v interface{}) bool {
|
logger.logcore.Fatal(logger.thread, logger.isStd, logger.handlerFunc, str...)
|
||||||
v.(*StarLogger).handleFunc = fn
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetLogFile(path string) error {
|
func (logger *StarLogger) Fatalf(format string, str ...interface{}) {
|
||||||
var err error
|
logger.logcore.Fatalf(logger.thread, logger.isStd, logger.handlerFunc, format, str...)
|
||||||
StdFile, err = os.Create(path)
|
|
||||||
Std.out = StdFile
|
|
||||||
Std.switching = false
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SwitchFile(path string) error {
|
func (logger *StarLogger) Fatalln(str ...interface{}) {
|
||||||
Std.switching = true
|
logger.logcore.Fatalln(logger.thread, logger.isStd, logger.handlerFunc, str...)
|
||||||
return SetLogFile(path)
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,179 @@
|
|||||||
|
package starlog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"math/rand"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"b612.me/starmap"
|
||||||
|
"github.com/mattn/go-colorable"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LvDebug = iota
|
||||||
|
LvInfo
|
||||||
|
LvNotice
|
||||||
|
LvWarning
|
||||||
|
LvError
|
||||||
|
LvCritical
|
||||||
|
LvPanic
|
||||||
|
LvFatal
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
levels = map[int]string{
|
||||||
|
LvDebug: "DEBUG",
|
||||||
|
LvInfo: "INFO",
|
||||||
|
LvNotice: "NOTICE",
|
||||||
|
LvWarning: "WARNING",
|
||||||
|
LvError: "ERROR",
|
||||||
|
LvCritical: "CRITICAL",
|
||||||
|
LvPanic: "PANIC",
|
||||||
|
LvFatal: "FATAL",
|
||||||
|
}
|
||||||
|
stacks starmap.StarStack
|
||||||
|
stackStarted bool = false
|
||||||
|
stackStopChan chan int
|
||||||
|
stdScreen io.Writer = colorable.NewColorableStdout()
|
||||||
|
)
|
||||||
|
|
||||||
|
type starlog struct {
|
||||||
|
mu *sync.Mutex
|
||||||
|
output io.Writer
|
||||||
|
showFuncName bool
|
||||||
|
showThread bool
|
||||||
|
showLevel bool
|
||||||
|
showDeatilFile bool
|
||||||
|
showColor bool
|
||||||
|
switching bool
|
||||||
|
showStd bool
|
||||||
|
stopWriter bool
|
||||||
|
id string
|
||||||
|
|
||||||
|
colorList map[int][]Attr
|
||||||
|
colorMe map[int]*Color
|
||||||
|
}
|
||||||
|
|
||||||
|
type StarLogger struct {
|
||||||
|
thread string
|
||||||
|
handlerFunc func([]Attr, string)
|
||||||
|
logcore *starlog
|
||||||
|
isStd bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type logTransfer struct {
|
||||||
|
handlerFunc func([]Attr, string)
|
||||||
|
colors []Attr
|
||||||
|
logStr string
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLogCore(out io.Writer) *starlog {
|
||||||
|
return &starlog{
|
||||||
|
mu: &sync.Mutex{},
|
||||||
|
output: out,
|
||||||
|
showFuncName: true,
|
||||||
|
showThread: true,
|
||||||
|
showLevel: true,
|
||||||
|
showStd: true,
|
||||||
|
showDeatilFile: true,
|
||||||
|
switching: false,
|
||||||
|
stopWriter: false,
|
||||||
|
showColor: true,
|
||||||
|
id: generateId(),
|
||||||
|
colorList: map[int][]Attr{
|
||||||
|
LvDebug: []Attr{FgWhite},
|
||||||
|
LvInfo: []Attr{FgGreen},
|
||||||
|
LvNotice: []Attr{FgBlue},
|
||||||
|
LvWarning: []Attr{FgYellow},
|
||||||
|
LvError: []Attr{FgMagenta},
|
||||||
|
LvCritical: []Attr{FgRed, Bold},
|
||||||
|
LvPanic: []Attr{FgRed, Bold},
|
||||||
|
LvFatal: []Attr{FgRed},
|
||||||
|
},
|
||||||
|
colorMe: map[int]*Color{
|
||||||
|
LvDebug: NewColor([]Attr{FgWhite}...),
|
||||||
|
LvInfo: NewColor([]Attr{FgGreen}...),
|
||||||
|
LvNotice: NewColor([]Attr{FgBlue}...),
|
||||||
|
LvWarning: NewColor([]Attr{FgYellow}...),
|
||||||
|
LvError: NewColor([]Attr{FgMagenta}...),
|
||||||
|
LvCritical: NewColor([]Attr{FgRed, Bold}...),
|
||||||
|
LvPanic: NewColor([]Attr{FgRed, Bold}...),
|
||||||
|
LvFatal: NewColor([]Attr{FgRed}...),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStarlog(out io.Writer) *StarLogger {
|
||||||
|
return &StarLogger{
|
||||||
|
handlerFunc: nil,
|
||||||
|
thread: "MAN",
|
||||||
|
logcore: newLogCore(out),
|
||||||
|
isStd: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *StarLogger) NewFlag() *StarLogger {
|
||||||
|
return &StarLogger{
|
||||||
|
thread: getRandomFlag(false),
|
||||||
|
handlerFunc: logger.handlerFunc,
|
||||||
|
logcore: logger.logcore,
|
||||||
|
isStd: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (logger *StarLogger) SetNewRandomFlag() {
|
||||||
|
logger.thread = getRandomFlag(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRandomFlag(isMain bool) string {
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
if isMain {
|
||||||
|
return "MAN"
|
||||||
|
}
|
||||||
|
flag := "MAN"
|
||||||
|
for flag == "MAN" {
|
||||||
|
flag = string([]byte{uint8(rand.Intn(26) + 65), uint8(rand.Intn(26) + 65), uint8(rand.Intn(26) + 65)})
|
||||||
|
}
|
||||||
|
return flag
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateId() string {
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
return fmt.Sprintf("%dstar%db612%d", time.Now().UnixNano(), rand.Intn(1000000), rand.Intn(1000000))
|
||||||
|
}
|
||||||
|
|
||||||
|
func StartStacks() {
|
||||||
|
if stackStarted {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
stackStarted = true
|
||||||
|
defer func() {
|
||||||
|
stackStarted = false
|
||||||
|
}()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-stackStopChan:
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
poped := stacks.MustPop()
|
||||||
|
if poped == nil {
|
||||||
|
time.Sleep(time.Millisecond * 10)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val := poped.(logTransfer)
|
||||||
|
if val.handlerFunc != nil {
|
||||||
|
val.handlerFunc(val.colors, val.logStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func StopStacks() {
|
||||||
|
if !stackStarted {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
stackStopChan <- 1
|
||||||
|
}
|
@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2016 Yasuhiro Matsumoto
|
|
||||||
|
|
||||||
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.
|
|
@ -1,48 +0,0 @@
|
|||||||
# go-colorable
|
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/mattn/go-colorable.svg?branch=master)](https://travis-ci.org/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)
|
|
||||||
[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable)
|
|
||||||
|
|
||||||
Colorable writer for windows.
|
|
||||||
|
|
||||||
For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.)
|
|
||||||
This package is possible to handle escape sequence for ansi color on windows.
|
|
||||||
|
|
||||||
## Too Bad!
|
|
||||||
|
|
||||||
![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png)
|
|
||||||
|
|
||||||
|
|
||||||
## So Good!
|
|
||||||
|
|
||||||
![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```go
|
|
||||||
logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true})
|
|
||||||
logrus.SetOutput(colorable.NewColorableStdout())
|
|
||||||
|
|
||||||
logrus.Info("succeeded")
|
|
||||||
logrus.Warn("not correct")
|
|
||||||
logrus.Error("something error")
|
|
||||||
logrus.Fatal("panic")
|
|
||||||
```
|
|
||||||
|
|
||||||
You can compile above code on non-windows OSs.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```
|
|
||||||
$ go get github.com/mattn/go-colorable
|
|
||||||
```
|
|
||||||
|
|
||||||
# License
|
|
||||||
|
|
||||||
MIT
|
|
||||||
|
|
||||||
# Author
|
|
||||||
|
|
||||||
Yasuhiro Matsumoto (a.k.a mattn)
|
|
@ -1,37 +0,0 @@
|
|||||||
// +build appengine
|
|
||||||
|
|
||||||
package colorable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
_ "github.com/mattn/go-isatty"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewColorable returns new instance of Writer which handles escape sequence.
|
|
||||||
func NewColorable(file *os.File) io.Writer {
|
|
||||||
if file == nil {
|
|
||||||
panic("nil passed instead of *os.File to NewColorable()")
|
|
||||||
}
|
|
||||||
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.
|
|
||||||
func NewColorableStdout() io.Writer {
|
|
||||||
return os.Stdout
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.
|
|
||||||
func NewColorableStderr() io.Writer {
|
|
||||||
return os.Stderr
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnableColorsStdout enable colors if possible.
|
|
||||||
func EnableColorsStdout(enabled *bool) func() {
|
|
||||||
if enabled != nil {
|
|
||||||
*enabled = true
|
|
||||||
}
|
|
||||||
return func() {}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
// +build !windows
|
|
||||||
// +build !appengine
|
|
||||||
|
|
||||||
package colorable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
_ "github.com/mattn/go-isatty"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewColorable returns new instance of Writer which handles escape sequence.
|
|
||||||
func NewColorable(file *os.File) io.Writer {
|
|
||||||
if file == nil {
|
|
||||||
panic("nil passed instead of *os.File to NewColorable()")
|
|
||||||
}
|
|
||||||
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.
|
|
||||||
func NewColorableStdout() io.Writer {
|
|
||||||
return os.Stdout
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.
|
|
||||||
func NewColorableStderr() io.Writer {
|
|
||||||
return os.Stderr
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnableColorsStdout enable colors if possible.
|
|
||||||
func EnableColorsStdout(enabled *bool) func() {
|
|
||||||
if enabled != nil {
|
|
||||||
*enabled = true
|
|
||||||
}
|
|
||||||
return func() {}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,12 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
echo "" > coverage.txt
|
|
||||||
|
|
||||||
for d in $(go list ./... | grep -v vendor); do
|
|
||||||
go test -race -coverprofile=profile.out -covermode=atomic "$d"
|
|
||||||
if [ -f profile.out ]; then
|
|
||||||
cat profile.out >> coverage.txt
|
|
||||||
rm profile.out
|
|
||||||
fi
|
|
||||||
done
|
|
@ -1,55 +0,0 @@
|
|||||||
package colorable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NonColorable holds writer but removes escape sequence.
|
|
||||||
type NonColorable struct {
|
|
||||||
out io.Writer
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewNonColorable returns new instance of Writer which removes escape sequence from Writer.
|
|
||||||
func NewNonColorable(w io.Writer) io.Writer {
|
|
||||||
return &NonColorable{out: w}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write writes data on console
|
|
||||||
func (w *NonColorable) Write(data []byte) (n int, err error) {
|
|
||||||
er := bytes.NewReader(data)
|
|
||||||
var bw [1]byte
|
|
||||||
loop:
|
|
||||||
for {
|
|
||||||
c1, err := er.ReadByte()
|
|
||||||
if err != nil {
|
|
||||||
break loop
|
|
||||||
}
|
|
||||||
if c1 != 0x1b {
|
|
||||||
bw[0] = c1
|
|
||||||
w.out.Write(bw[:])
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
c2, err := er.ReadByte()
|
|
||||||
if err != nil {
|
|
||||||
break loop
|
|
||||||
}
|
|
||||||
if c2 != 0x5b {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var buf bytes.Buffer
|
|
||||||
for {
|
|
||||||
c, err := er.ReadByte()
|
|
||||||
if err != nil {
|
|
||||||
break loop
|
|
||||||
}
|
|
||||||
if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
buf.Write([]byte(string(c)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return len(data), nil
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
Copyright (c) Yasuhiro MATSUMOTO <mattn.jp@gmail.com>
|
|
||||||
|
|
||||||
MIT License (Expat)
|
|
||||||
|
|
||||||
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.
|
|
@ -1,50 +0,0 @@
|
|||||||
# go-isatty
|
|
||||||
|
|
||||||
[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty)
|
|
||||||
[![Codecov](https://codecov.io/gh/mattn/go-isatty/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-isatty)
|
|
||||||
[![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master)
|
|
||||||
[![Go Report Card](https://goreportcard.com/badge/mattn/go-isatty)](https://goreportcard.com/report/mattn/go-isatty)
|
|
||||||
|
|
||||||
isatty for golang
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/mattn/go-isatty"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
|
||||||
fmt.Println("Is Terminal")
|
|
||||||
} else if isatty.IsCygwinTerminal(os.Stdout.Fd()) {
|
|
||||||
fmt.Println("Is Cygwin/MSYS2 Terminal")
|
|
||||||
} else {
|
|
||||||
fmt.Println("Is Not Terminal")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```
|
|
||||||
$ go get github.com/mattn/go-isatty
|
|
||||||
```
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT
|
|
||||||
|
|
||||||
## Author
|
|
||||||
|
|
||||||
Yasuhiro Matsumoto (a.k.a mattn)
|
|
||||||
|
|
||||||
## Thanks
|
|
||||||
|
|
||||||
* k-takata: base idea for IsCygwinTerminal
|
|
||||||
|
|
||||||
https://github.com/k-takata/go-iscygpty
|
|
@ -1,2 +0,0 @@
|
|||||||
// Package isatty implements interface to isatty
|
|
||||||
package isatty
|
|
@ -1,12 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
echo "" > coverage.txt
|
|
||||||
|
|
||||||
for d in $(go list ./... | grep -v vendor); do
|
|
||||||
go test -race -coverprofile=profile.out -covermode=atomic "$d"
|
|
||||||
if [ -f profile.out ]; then
|
|
||||||
cat profile.out >> coverage.txt
|
|
||||||
rm profile.out
|
|
||||||
fi
|
|
||||||
done
|
|
@ -1,18 +0,0 @@
|
|||||||
// +build darwin freebsd openbsd netbsd dragonfly
|
|
||||||
// +build !appengine
|
|
||||||
|
|
||||||
package isatty
|
|
||||||
|
|
||||||
import "golang.org/x/sys/unix"
|
|
||||||
|
|
||||||
// IsTerminal return true if the file descriptor is terminal.
|
|
||||||
func IsTerminal(fd uintptr) bool {
|
|
||||||
_, err := unix.IoctlGetTermios(int(fd), unix.TIOCGETA)
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
|
|
||||||
// terminal. This is also always false on this environment.
|
|
||||||
func IsCygwinTerminal(fd uintptr) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
// +build appengine js nacl wasm
|
|
||||||
|
|
||||||
package isatty
|
|
||||||
|
|
||||||
// IsTerminal returns true if the file descriptor is terminal which
|
|
||||||
// is always false on js and appengine classic which is a sandboxed PaaS.
|
|
||||||
func IsTerminal(fd uintptr) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
|
|
||||||
// terminal. This is also always false on this environment.
|
|
||||||
func IsCygwinTerminal(fd uintptr) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
// +build plan9
|
|
||||||
|
|
||||||
package isatty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
|
||||||
func IsTerminal(fd uintptr) bool {
|
|
||||||
path, err := syscall.Fd2path(int(fd))
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return path == "/dev/cons" || path == "/mnt/term/dev/cons"
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
|
|
||||||
// terminal. This is also always false on this environment.
|
|
||||||
func IsCygwinTerminal(fd uintptr) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
// +build solaris
|
|
||||||
// +build !appengine
|
|
||||||
|
|
||||||
package isatty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
|
||||||
// see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c
|
|
||||||
func IsTerminal(fd uintptr) bool {
|
|
||||||
var termio unix.Termio
|
|
||||||
err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio)
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
|
|
||||||
// terminal. This is also always false on this environment.
|
|
||||||
func IsCygwinTerminal(fd uintptr) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
// +build linux aix
|
|
||||||
// +build !appengine
|
|
||||||
|
|
||||||
package isatty
|
|
||||||
|
|
||||||
import "golang.org/x/sys/unix"
|
|
||||||
|
|
||||||
// IsTerminal return true if the file descriptor is terminal.
|
|
||||||
func IsTerminal(fd uintptr) bool {
|
|
||||||
_, err := unix.IoctlGetTermios(int(fd), unix.TCGETS)
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
|
|
||||||
// terminal. This is also always false on this environment.
|
|
||||||
func IsCygwinTerminal(fd uintptr) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
@ -1,125 +0,0 @@
|
|||||||
// +build windows
|
|
||||||
// +build !appengine
|
|
||||||
|
|
||||||
package isatty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
"unicode/utf16"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
objectNameInfo uintptr = 1
|
|
||||||
fileNameInfo = 2
|
|
||||||
fileTypePipe = 3
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
||||||
ntdll = syscall.NewLazyDLL("ntdll.dll")
|
|
||||||
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
|
||||||
procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx")
|
|
||||||
procGetFileType = kernel32.NewProc("GetFileType")
|
|
||||||
procNtQueryObject = ntdll.NewProc("NtQueryObject")
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// Check if GetFileInformationByHandleEx is available.
|
|
||||||
if procGetFileInformationByHandleEx.Find() != nil {
|
|
||||||
procGetFileInformationByHandleEx = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsTerminal return true if the file descriptor is terminal.
|
|
||||||
func IsTerminal(fd uintptr) bool {
|
|
||||||
var st uint32
|
|
||||||
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)
|
|
||||||
return r != 0 && e == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check pipe name is used for cygwin/msys2 pty.
|
|
||||||
// Cygwin/MSYS2 PTY has a name like:
|
|
||||||
// \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master
|
|
||||||
func isCygwinPipeName(name string) bool {
|
|
||||||
token := strings.Split(name, "-")
|
|
||||||
if len(token) < 5 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if token[0] != `\msys` &&
|
|
||||||
token[0] != `\cygwin` &&
|
|
||||||
token[0] != `\Device\NamedPipe\msys` &&
|
|
||||||
token[0] != `\Device\NamedPipe\cygwin` {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if token[1] == "" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.HasPrefix(token[2], "pty") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if token[3] != `from` && token[3] != `to` {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if token[4] != "master" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// getFileNameByHandle use the undocomented ntdll NtQueryObject to get file full name from file handler
|
|
||||||
// since GetFileInformationByHandleEx is not avilable under windows Vista and still some old fashion
|
|
||||||
// guys are using Windows XP, this is a workaround for those guys, it will also work on system from
|
|
||||||
// Windows vista to 10
|
|
||||||
// see https://stackoverflow.com/a/18792477 for details
|
|
||||||
func getFileNameByHandle(fd uintptr) (string, error) {
|
|
||||||
if procNtQueryObject == nil {
|
|
||||||
return "", errors.New("ntdll.dll: NtQueryObject not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
var buf [4 + syscall.MAX_PATH]uint16
|
|
||||||
var result int
|
|
||||||
r, _, e := syscall.Syscall6(procNtQueryObject.Addr(), 5,
|
|
||||||
fd, objectNameInfo, uintptr(unsafe.Pointer(&buf)), uintptr(2*len(buf)), uintptr(unsafe.Pointer(&result)), 0)
|
|
||||||
if r != 0 {
|
|
||||||
return "", e
|
|
||||||
}
|
|
||||||
return string(utf16.Decode(buf[4 : 4+buf[0]/2])), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
|
|
||||||
// terminal.
|
|
||||||
func IsCygwinTerminal(fd uintptr) bool {
|
|
||||||
if procGetFileInformationByHandleEx == nil {
|
|
||||||
name, err := getFileNameByHandle(fd)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return isCygwinPipeName(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cygwin/msys's pty is a pipe.
|
|
||||||
ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0)
|
|
||||||
if ft != fileTypePipe || e != 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var buf [2 + syscall.MAX_PATH]uint16
|
|
||||||
r, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(),
|
|
||||||
4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)),
|
|
||||||
uintptr(len(buf)*2), 0, 0)
|
|
||||||
if r == 0 || e != 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
l := *(*uint32)(unsafe.Pointer(&buf))
|
|
||||||
return isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2])))
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
* Neither the name of Google Inc. nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,22 +0,0 @@
|
|||||||
Additional IP Rights Grant (Patents)
|
|
||||||
|
|
||||||
"This implementation" means the copyrightable works distributed by
|
|
||||||
Google as part of the Go project.
|
|
||||||
|
|
||||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
|
||||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
|
||||||
patent license to make, have made, use, offer to sell, sell, import,
|
|
||||||
transfer and otherwise run, modify and propagate the contents of this
|
|
||||||
implementation of Go, where such license applies only to those patent
|
|
||||||
claims, both currently owned or controlled by Google and acquired in
|
|
||||||
the future, licensable by Google that are necessarily infringed by this
|
|
||||||
implementation of Go. This grant does not include claims that would be
|
|
||||||
infringed only as a consequence of further modification of this
|
|
||||||
implementation. If you or your agent or exclusive licensee institute or
|
|
||||||
order or agree to the institution of patent litigation against any
|
|
||||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
|
||||||
that this implementation of Go or any code incorporated within this
|
|
||||||
implementation of Go constitutes direct or contributory patent
|
|
||||||
infringement, or inducement of patent infringement, then any patent
|
|
||||||
rights granted to you under this License for this implementation of Go
|
|
||||||
shall terminate as of the date such litigation is filed.
|
|
@ -1,30 +0,0 @@
|
|||||||
// Copyright 2020 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 unsafeheader contains header declarations for the Go runtime's
|
|
||||||
// slice and string implementations.
|
|
||||||
//
|
|
||||||
// This package allows x/sys to use types equivalent to
|
|
||||||
// reflect.SliceHeader and reflect.StringHeader without introducing
|
|
||||||
// a dependency on the (relatively heavy) "reflect" package.
|
|
||||||
package unsafeheader
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Slice is the runtime representation of a slice.
|
|
||||||
// It cannot be used safely or portably and its representation may change in a later release.
|
|
||||||
type Slice struct {
|
|
||||||
Data unsafe.Pointer
|
|
||||||
Len int
|
|
||||||
Cap int
|
|
||||||
}
|
|
||||||
|
|
||||||
// String is the runtime representation of a string.
|
|
||||||
// It cannot be used safely or portably and its representation may change in a later release.
|
|
||||||
type String struct {
|
|
||||||
Data unsafe.Pointer
|
|
||||||
Len int
|
|
||||||
}
|
|
@ -1,184 +0,0 @@
|
|||||||
# Building `sys/unix`
|
|
||||||
|
|
||||||
The sys/unix package provides access to the raw system call interface of the
|
|
||||||
underlying operating system. See: https://godoc.org/golang.org/x/sys/unix
|
|
||||||
|
|
||||||
Porting Go to a new architecture/OS combination or adding syscalls, types, or
|
|
||||||
constants to an existing architecture/OS pair requires some manual effort;
|
|
||||||
however, there are tools that automate much of the process.
|
|
||||||
|
|
||||||
## Build Systems
|
|
||||||
|
|
||||||
There are currently two ways we generate the necessary files. We are currently
|
|
||||||
migrating the build system to use containers so the builds are reproducible.
|
|
||||||
This is being done on an OS-by-OS basis. Please update this documentation as
|
|
||||||
components of the build system change.
|
|
||||||
|
|
||||||
### Old Build System (currently for `GOOS != "linux"`)
|
|
||||||
|
|
||||||
The old build system generates the Go files based on the C header files
|
|
||||||
present on your system. This means that files
|
|
||||||
for a given GOOS/GOARCH pair must be generated on a system with that OS and
|
|
||||||
architecture. This also means that the generated code can differ from system
|
|
||||||
to system, based on differences in the header files.
|
|
||||||
|
|
||||||
To avoid this, if you are using the old build system, only generate the Go
|
|
||||||
files on an installation with unmodified header files. It is also important to
|
|
||||||
keep track of which version of the OS the files were generated from (ex.
|
|
||||||
Darwin 14 vs Darwin 15). This makes it easier to track the progress of changes
|
|
||||||
and have each OS upgrade correspond to a single change.
|
|
||||||
|
|
||||||
To build the files for your current OS and architecture, make sure GOOS and
|
|
||||||
GOARCH are set correctly and run `mkall.sh`. This will generate the files for
|
|
||||||
your specific system. Running `mkall.sh -n` shows the commands that will be run.
|
|
||||||
|
|
||||||
Requirements: bash, go
|
|
||||||
|
|
||||||
### New Build System (currently for `GOOS == "linux"`)
|
|
||||||
|
|
||||||
The new build system uses a Docker container to generate the go files directly
|
|
||||||
from source checkouts of the kernel and various system libraries. This means
|
|
||||||
that on any platform that supports Docker, all the files using the new build
|
|
||||||
system can be generated at once, and generated files will not change based on
|
|
||||||
what the person running the scripts has installed on their computer.
|
|
||||||
|
|
||||||
The OS specific files for the new build system are located in the `${GOOS}`
|
|
||||||
directory, and the build is coordinated by the `${GOOS}/mkall.go` program. When
|
|
||||||
the kernel or system library updates, modify the Dockerfile at
|
|
||||||
`${GOOS}/Dockerfile` to checkout the new release of the source.
|
|
||||||
|
|
||||||
To build all the files under the new build system, you must be on an amd64/Linux
|
|
||||||
system and have your GOOS and GOARCH set accordingly. Running `mkall.sh` will
|
|
||||||
then generate all of the files for all of the GOOS/GOARCH pairs in the new build
|
|
||||||
system. Running `mkall.sh -n` shows the commands that will be run.
|
|
||||||
|
|
||||||
Requirements: bash, go, docker
|
|
||||||
|
|
||||||
## Component files
|
|
||||||
|
|
||||||
This section describes the various files used in the code generation process.
|
|
||||||
It also contains instructions on how to modify these files to add a new
|
|
||||||
architecture/OS or to add additional syscalls, types, or constants. Note that
|
|
||||||
if you are using the new build system, the scripts/programs cannot be called normally.
|
|
||||||
They must be called from within the docker container.
|
|
||||||
|
|
||||||
### asm files
|
|
||||||
|
|
||||||
The hand-written assembly file at `asm_${GOOS}_${GOARCH}.s` implements system
|
|
||||||
call dispatch. There are three entry points:
|
|
||||||
```
|
|
||||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
|
||||||
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
|
|
||||||
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
|
||||||
```
|
|
||||||
The first and second are the standard ones; they differ only in how many
|
|
||||||
arguments can be passed to the kernel. The third is for low-level use by the
|
|
||||||
ForkExec wrapper. Unlike the first two, it does not call into the scheduler to
|
|
||||||
let it know that a system call is running.
|
|
||||||
|
|
||||||
When porting Go to an new architecture/OS, this file must be implemented for
|
|
||||||
each GOOS/GOARCH pair.
|
|
||||||
|
|
||||||
### mksysnum
|
|
||||||
|
|
||||||
Mksysnum is a Go program located at `${GOOS}/mksysnum.go` (or `mksysnum_${GOOS}.go`
|
|
||||||
for the old system). This program takes in a list of header files containing the
|
|
||||||
syscall number declarations and parses them to produce the corresponding list of
|
|
||||||
Go numeric constants. See `zsysnum_${GOOS}_${GOARCH}.go` for the generated
|
|
||||||
constants.
|
|
||||||
|
|
||||||
Adding new syscall numbers is mostly done by running the build on a sufficiently
|
|
||||||
new installation of the target OS (or updating the source checkouts for the
|
|
||||||
new build system). However, depending on the OS, you may need to update the
|
|
||||||
parsing in mksysnum.
|
|
||||||
|
|
||||||
### mksyscall.go
|
|
||||||
|
|
||||||
The `syscall.go`, `syscall_${GOOS}.go`, `syscall_${GOOS}_${GOARCH}.go` are
|
|
||||||
hand-written Go files which implement system calls (for unix, the specific OS,
|
|
||||||
or the specific OS/Architecture pair respectively) that need special handling
|
|
||||||
and list `//sys` comments giving prototypes for ones that can be generated.
|
|
||||||
|
|
||||||
The mksyscall.go program takes the `//sys` and `//sysnb` comments and converts
|
|
||||||
them into syscalls. This requires the name of the prototype in the comment to
|
|
||||||
match a syscall number in the `zsysnum_${GOOS}_${GOARCH}.go` file. The function
|
|
||||||
prototype can be exported (capitalized) or not.
|
|
||||||
|
|
||||||
Adding a new syscall often just requires adding a new `//sys` function prototype
|
|
||||||
with the desired arguments and a capitalized name so it is exported. However, if
|
|
||||||
you want the interface to the syscall to be different, often one will make an
|
|
||||||
unexported `//sys` prototype, an then write a custom wrapper in
|
|
||||||
`syscall_${GOOS}.go`.
|
|
||||||
|
|
||||||
### types files
|
|
||||||
|
|
||||||
For each OS, there is a hand-written Go file at `${GOOS}/types.go` (or
|
|
||||||
`types_${GOOS}.go` on the old system). This file includes standard C headers and
|
|
||||||
creates Go type aliases to the corresponding C types. The file is then fed
|
|
||||||
through godef to get the Go compatible definitions. Finally, the generated code
|
|
||||||
is fed though mkpost.go to format the code correctly and remove any hidden or
|
|
||||||
private identifiers. This cleaned-up code is written to
|
|
||||||
`ztypes_${GOOS}_${GOARCH}.go`.
|
|
||||||
|
|
||||||
The hardest part about preparing this file is figuring out which headers to
|
|
||||||
include and which symbols need to be `#define`d to get the actual data
|
|
||||||
structures that pass through to the kernel system calls. Some C libraries
|
|
||||||
preset alternate versions for binary compatibility and translate them on the
|
|
||||||
way in and out of system calls, but there is almost always a `#define` that can
|
|
||||||
get the real ones.
|
|
||||||
See `types_darwin.go` and `linux/types.go` for examples.
|
|
||||||
|
|
||||||
To add a new type, add in the necessary include statement at the top of the
|
|
||||||
file (if it is not already there) and add in a type alias line. Note that if
|
|
||||||
your type is significantly different on different architectures, you may need
|
|
||||||
some `#if/#elif` macros in your include statements.
|
|
||||||
|
|
||||||
### mkerrors.sh
|
|
||||||
|
|
||||||
This script is used to generate the system's various constants. This doesn't
|
|
||||||
just include the error numbers and error strings, but also the signal numbers
|
|
||||||
an a wide variety of miscellaneous constants. The constants come from the list
|
|
||||||
of include files in the `includes_${uname}` variable. A regex then picks out
|
|
||||||
the desired `#define` statements, and generates the corresponding Go constants.
|
|
||||||
The error numbers and strings are generated from `#include <errno.h>`, and the
|
|
||||||
signal numbers and strings are generated from `#include <signal.h>`. All of
|
|
||||||
these constants are written to `zerrors_${GOOS}_${GOARCH}.go` via a C program,
|
|
||||||
`_errors.c`, which prints out all the constants.
|
|
||||||
|
|
||||||
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
|
|
||||||
the regex too broad to avoid matching unintended constants.
|
|
||||||
|
|
||||||
### mkmerge.go
|
|
||||||
|
|
||||||
This program is used to extract duplicate const, func, and type declarations
|
|
||||||
from the generated architecture-specific files listed below, and merge these
|
|
||||||
into a common file for each OS.
|
|
||||||
|
|
||||||
The merge is performed in the following steps:
|
|
||||||
1. Construct the set of common code that is idential in all architecture-specific files.
|
|
||||||
2. Write this common code to the merged file.
|
|
||||||
3. Remove the common code from all architecture-specific files.
|
|
||||||
|
|
||||||
|
|
||||||
## Generated files
|
|
||||||
|
|
||||||
### `zerrors_${GOOS}_${GOARCH}.go`
|
|
||||||
|
|
||||||
A file containing all of the system's generated error numbers, error strings,
|
|
||||||
signal numbers, and constants. Generated by `mkerrors.sh` (see above).
|
|
||||||
|
|
||||||
### `zsyscall_${GOOS}_${GOARCH}.go`
|
|
||||||
|
|
||||||
A file containing all the generated syscalls for a specific GOOS and GOARCH.
|
|
||||||
Generated by `mksyscall.go` (see above).
|
|
||||||
|
|
||||||
### `zsysnum_${GOOS}_${GOARCH}.go`
|
|
||||||
|
|
||||||
A list of numeric constants for all the syscall number of the specific GOOS
|
|
||||||
and GOARCH. Generated by mksysnum (see above).
|
|
||||||
|
|
||||||
### `ztypes_${GOOS}_${GOARCH}.go`
|
|
||||||
|
|
||||||
A file containing Go types for passing into (or returning from) syscalls.
|
|
||||||
Generated by godefs and the types file (see above).
|
|
@ -1,86 +0,0 @@
|
|||||||
// Copyright 2018 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.
|
|
||||||
|
|
||||||
// CPU affinity functions
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/bits"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const cpuSetSize = _CPU_SETSIZE / _NCPUBITS
|
|
||||||
|
|
||||||
// CPUSet represents a CPU affinity mask.
|
|
||||||
type CPUSet [cpuSetSize]cpuMask
|
|
||||||
|
|
||||||
func schedAffinity(trap uintptr, pid int, set *CPUSet) error {
|
|
||||||
_, _, e := RawSyscall(trap, uintptr(pid), uintptr(unsafe.Sizeof(*set)), uintptr(unsafe.Pointer(set)))
|
|
||||||
if e != 0 {
|
|
||||||
return errnoErr(e)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SchedGetaffinity gets the CPU affinity mask of the thread specified by pid.
|
|
||||||
// If pid is 0 the calling thread is used.
|
|
||||||
func SchedGetaffinity(pid int, set *CPUSet) error {
|
|
||||||
return schedAffinity(SYS_SCHED_GETAFFINITY, pid, set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SchedSetaffinity sets the CPU affinity mask of the thread specified by pid.
|
|
||||||
// If pid is 0 the calling thread is used.
|
|
||||||
func SchedSetaffinity(pid int, set *CPUSet) error {
|
|
||||||
return schedAffinity(SYS_SCHED_SETAFFINITY, pid, set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zero clears the set s, so that it contains no CPUs.
|
|
||||||
func (s *CPUSet) Zero() {
|
|
||||||
for i := range s {
|
|
||||||
s[i] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func cpuBitsIndex(cpu int) int {
|
|
||||||
return cpu / _NCPUBITS
|
|
||||||
}
|
|
||||||
|
|
||||||
func cpuBitsMask(cpu int) cpuMask {
|
|
||||||
return cpuMask(1 << (uint(cpu) % _NCPUBITS))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set adds cpu to the set s.
|
|
||||||
func (s *CPUSet) Set(cpu int) {
|
|
||||||
i := cpuBitsIndex(cpu)
|
|
||||||
if i < len(s) {
|
|
||||||
s[i] |= cpuBitsMask(cpu)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear removes cpu from the set s.
|
|
||||||
func (s *CPUSet) Clear(cpu int) {
|
|
||||||
i := cpuBitsIndex(cpu)
|
|
||||||
if i < len(s) {
|
|
||||||
s[i] &^= cpuBitsMask(cpu)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsSet reports whether cpu is in the set s.
|
|
||||||
func (s *CPUSet) IsSet(cpu int) bool {
|
|
||||||
i := cpuBitsIndex(cpu)
|
|
||||||
if i < len(s) {
|
|
||||||
return s[i]&cpuBitsMask(cpu) != 0
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count returns the number of CPUs in the set s.
|
|
||||||
func (s *CPUSet) Count() int {
|
|
||||||
c := 0
|
|
||||||
for _, b := range s {
|
|
||||||
c += bits.OnesCount64(uint64(b))
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
// Copyright 2018 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.
|
|
||||||
|
|
||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
|
||||||
// +build go1.9
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
type Signal = syscall.Signal
|
|
||||||
type Errno = syscall.Errno
|
|
||||||
type SysProcAttr = syscall.SysProcAttr
|
|
@ -1,17 +0,0 @@
|
|||||||
// Copyright 2018 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for ppc64, AIX are implemented in runtime/syscall_aix.go
|
|
||||||
//
|
|
||||||
|
|
||||||
TEXT ·syscall6(SB),NOSPLIT,$0-88
|
|
||||||
JMP syscall·syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·rawSyscall6(SB),NOSPLIT,$0-88
|
|
||||||
JMP syscall·rawSyscall6(SB)
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2009 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for 386, Darwin
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2009 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for AMD64, Darwin
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
@ -1,30 +0,0 @@
|
|||||||
// Copyright 2015 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
// +build arm,darwin
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for ARM, Darwin
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|
||||||
B syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|
||||||
B syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
|
||||||
B syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|
||||||
B syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|
||||||
B syscall·RawSyscall6(SB)
|
|
@ -1,30 +0,0 @@
|
|||||||
// Copyright 2015 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
// +build arm64,darwin
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for AMD64, Darwin
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
B syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
B syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
|
||||||
B syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
B syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
B syscall·RawSyscall6(SB)
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2009 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for AMD64, DragonFly
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2009 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for 386, FreeBSD
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2009 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for AMD64, FreeBSD
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2012 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for ARM, FreeBSD
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|
||||||
B syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|
||||||
B syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
|
||||||
B syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|
||||||
B syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|
||||||
B syscall·RawSyscall6(SB)
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2018 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for ARM64, FreeBSD
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
@ -1,65 +0,0 @@
|
|||||||
// Copyright 2009 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for 386, Linux
|
|
||||||
//
|
|
||||||
|
|
||||||
// See ../runtime/sys_linux_386.s for the reason why we always use int 0x80
|
|
||||||
// instead of the glibc-specific "CALL 0x10(GS)".
|
|
||||||
#define INVOKE_SYSCALL INT $0x80
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-24
|
|
||||||
CALL runtime·entersyscall(SB)
|
|
||||||
MOVL trap+0(FP), AX // syscall entry
|
|
||||||
MOVL a1+4(FP), BX
|
|
||||||
MOVL a2+8(FP), CX
|
|
||||||
MOVL a3+12(FP), DX
|
|
||||||
MOVL $0, SI
|
|
||||||
MOVL $0, DI
|
|
||||||
INVOKE_SYSCALL
|
|
||||||
MOVL AX, r1+16(FP)
|
|
||||||
MOVL DX, r2+20(FP)
|
|
||||||
CALL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24
|
|
||||||
MOVL trap+0(FP), AX // syscall entry
|
|
||||||
MOVL a1+4(FP), BX
|
|
||||||
MOVL a2+8(FP), CX
|
|
||||||
MOVL a3+12(FP), DX
|
|
||||||
MOVL $0, SI
|
|
||||||
MOVL $0, DI
|
|
||||||
INVOKE_SYSCALL
|
|
||||||
MOVL AX, r1+16(FP)
|
|
||||||
MOVL DX, r2+20(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·socketcall(SB),NOSPLIT,$0-36
|
|
||||||
JMP syscall·socketcall(SB)
|
|
||||||
|
|
||||||
TEXT ·rawsocketcall(SB),NOSPLIT,$0-36
|
|
||||||
JMP syscall·rawsocketcall(SB)
|
|
||||||
|
|
||||||
TEXT ·seek(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·seek(SB)
|
|
@ -1,57 +0,0 @@
|
|||||||
// Copyright 2009 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for AMD64, Linux
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
CALL runtime·entersyscall(SB)
|
|
||||||
MOVQ a1+8(FP), DI
|
|
||||||
MOVQ a2+16(FP), SI
|
|
||||||
MOVQ a3+24(FP), DX
|
|
||||||
MOVQ $0, R10
|
|
||||||
MOVQ $0, R8
|
|
||||||
MOVQ $0, R9
|
|
||||||
MOVQ trap+0(FP), AX // syscall entry
|
|
||||||
SYSCALL
|
|
||||||
MOVQ AX, r1+32(FP)
|
|
||||||
MOVQ DX, r2+40(FP)
|
|
||||||
CALL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
MOVQ a1+8(FP), DI
|
|
||||||
MOVQ a2+16(FP), SI
|
|
||||||
MOVQ a3+24(FP), DX
|
|
||||||
MOVQ $0, R10
|
|
||||||
MOVQ $0, R8
|
|
||||||
MOVQ $0, R9
|
|
||||||
MOVQ trap+0(FP), AX // syscall entry
|
|
||||||
SYSCALL
|
|
||||||
MOVQ AX, r1+32(FP)
|
|
||||||
MOVQ DX, r2+40(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·gettimeofday(SB),NOSPLIT,$0-16
|
|
||||||
JMP syscall·gettimeofday(SB)
|
|
@ -1,56 +0,0 @@
|
|||||||
// Copyright 2009 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for arm, Linux
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|
||||||
B syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|
||||||
B syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-24
|
|
||||||
BL runtime·entersyscall(SB)
|
|
||||||
MOVW trap+0(FP), R7
|
|
||||||
MOVW a1+4(FP), R0
|
|
||||||
MOVW a2+8(FP), R1
|
|
||||||
MOVW a3+12(FP), R2
|
|
||||||
MOVW $0, R3
|
|
||||||
MOVW $0, R4
|
|
||||||
MOVW $0, R5
|
|
||||||
SWI $0
|
|
||||||
MOVW R0, r1+16(FP)
|
|
||||||
MOVW $0, R0
|
|
||||||
MOVW R0, r2+20(FP)
|
|
||||||
BL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|
||||||
B syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|
||||||
B syscall·RawSyscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24
|
|
||||||
MOVW trap+0(FP), R7 // syscall entry
|
|
||||||
MOVW a1+4(FP), R0
|
|
||||||
MOVW a2+8(FP), R1
|
|
||||||
MOVW a3+12(FP), R2
|
|
||||||
SWI $0
|
|
||||||
MOVW R0, r1+16(FP)
|
|
||||||
MOVW $0, R0
|
|
||||||
MOVW R0, r2+20(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·seek(SB),NOSPLIT,$0-28
|
|
||||||
B syscall·seek(SB)
|
|
@ -1,52 +0,0 @@
|
|||||||
// Copyright 2015 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.
|
|
||||||
|
|
||||||
// +build linux
|
|
||||||
// +build arm64
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
B syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
B syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
BL runtime·entersyscall(SB)
|
|
||||||
MOVD a1+8(FP), R0
|
|
||||||
MOVD a2+16(FP), R1
|
|
||||||
MOVD a3+24(FP), R2
|
|
||||||
MOVD $0, R3
|
|
||||||
MOVD $0, R4
|
|
||||||
MOVD $0, R5
|
|
||||||
MOVD trap+0(FP), R8 // syscall entry
|
|
||||||
SVC
|
|
||||||
MOVD R0, r1+32(FP) // r1
|
|
||||||
MOVD R1, r2+40(FP) // r2
|
|
||||||
BL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
B syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
B syscall·RawSyscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
MOVD a1+8(FP), R0
|
|
||||||
MOVD a2+16(FP), R1
|
|
||||||
MOVD a3+24(FP), R2
|
|
||||||
MOVD $0, R3
|
|
||||||
MOVD $0, R4
|
|
||||||
MOVD $0, R5
|
|
||||||
MOVD trap+0(FP), R8 // syscall entry
|
|
||||||
SVC
|
|
||||||
MOVD R0, r1+32(FP)
|
|
||||||
MOVD R1, r2+40(FP)
|
|
||||||
RET
|
|
@ -1,56 +0,0 @@
|
|||||||
// Copyright 2015 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.
|
|
||||||
|
|
||||||
// +build linux
|
|
||||||
// +build mips64 mips64le
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for mips64, Linux
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
JAL runtime·entersyscall(SB)
|
|
||||||
MOVV a1+8(FP), R4
|
|
||||||
MOVV a2+16(FP), R5
|
|
||||||
MOVV a3+24(FP), R6
|
|
||||||
MOVV R0, R7
|
|
||||||
MOVV R0, R8
|
|
||||||
MOVV R0, R9
|
|
||||||
MOVV trap+0(FP), R2 // syscall entry
|
|
||||||
SYSCALL
|
|
||||||
MOVV R2, r1+32(FP)
|
|
||||||
MOVV R3, r2+40(FP)
|
|
||||||
JAL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
MOVV a1+8(FP), R4
|
|
||||||
MOVV a2+16(FP), R5
|
|
||||||
MOVV a3+24(FP), R6
|
|
||||||
MOVV R0, R7
|
|
||||||
MOVV R0, R8
|
|
||||||
MOVV R0, R9
|
|
||||||
MOVV trap+0(FP), R2 // syscall entry
|
|
||||||
SYSCALL
|
|
||||||
MOVV R2, r1+32(FP)
|
|
||||||
MOVV R3, r2+40(FP)
|
|
||||||
RET
|
|
@ -1,54 +0,0 @@
|
|||||||
// Copyright 2016 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.
|
|
||||||
|
|
||||||
// +build linux
|
|
||||||
// +build mips mipsle
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for mips, Linux
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-24
|
|
||||||
JAL runtime·entersyscall(SB)
|
|
||||||
MOVW a1+4(FP), R4
|
|
||||||
MOVW a2+8(FP), R5
|
|
||||||
MOVW a3+12(FP), R6
|
|
||||||
MOVW R0, R7
|
|
||||||
MOVW trap+0(FP), R2 // syscall entry
|
|
||||||
SYSCALL
|
|
||||||
MOVW R2, r1+16(FP) // r1
|
|
||||||
MOVW R3, r2+20(FP) // r2
|
|
||||||
JAL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24
|
|
||||||
MOVW a1+4(FP), R4
|
|
||||||
MOVW a2+8(FP), R5
|
|
||||||
MOVW a3+12(FP), R6
|
|
||||||
MOVW trap+0(FP), R2 // syscall entry
|
|
||||||
SYSCALL
|
|
||||||
MOVW R2, r1+16(FP)
|
|
||||||
MOVW R3, r2+20(FP)
|
|
||||||
RET
|
|
@ -1,44 +0,0 @@
|
|||||||
// Copyright 2014 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.
|
|
||||||
|
|
||||||
// +build linux
|
|
||||||
// +build ppc64 ppc64le
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for ppc64, Linux
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
BL runtime·entersyscall(SB)
|
|
||||||
MOVD a1+8(FP), R3
|
|
||||||
MOVD a2+16(FP), R4
|
|
||||||
MOVD a3+24(FP), R5
|
|
||||||
MOVD R0, R6
|
|
||||||
MOVD R0, R7
|
|
||||||
MOVD R0, R8
|
|
||||||
MOVD trap+0(FP), R9 // syscall entry
|
|
||||||
SYSCALL R9
|
|
||||||
MOVD R3, r1+32(FP)
|
|
||||||
MOVD R4, r2+40(FP)
|
|
||||||
BL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
MOVD a1+8(FP), R3
|
|
||||||
MOVD a2+16(FP), R4
|
|
||||||
MOVD a3+24(FP), R5
|
|
||||||
MOVD R0, R6
|
|
||||||
MOVD R0, R7
|
|
||||||
MOVD R0, R8
|
|
||||||
MOVD trap+0(FP), R9 // syscall entry
|
|
||||||
SYSCALL R9
|
|
||||||
MOVD R3, r1+32(FP)
|
|
||||||
MOVD R4, r2+40(FP)
|
|
||||||
RET
|
|
@ -1,47 +0,0 @@
|
|||||||
// Copyright 2019 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.
|
|
||||||
|
|
||||||
// +build riscv64,!gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for linux/riscv64.
|
|
||||||
//
|
|
||||||
// Where available, just jump to package syscall's implementation of
|
|
||||||
// these functions.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
CALL runtime·entersyscall(SB)
|
|
||||||
MOV a1+8(FP), A0
|
|
||||||
MOV a2+16(FP), A1
|
|
||||||
MOV a3+24(FP), A2
|
|
||||||
MOV trap+0(FP), A7 // syscall entry
|
|
||||||
ECALL
|
|
||||||
MOV A0, r1+32(FP) // r1
|
|
||||||
MOV A1, r2+40(FP) // r2
|
|
||||||
CALL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
MOV a1+8(FP), A0
|
|
||||||
MOV a2+16(FP), A1
|
|
||||||
MOV a3+24(FP), A2
|
|
||||||
MOV trap+0(FP), A7 // syscall entry
|
|
||||||
ECALL
|
|
||||||
MOV A0, r1+32(FP)
|
|
||||||
MOV A1, r2+40(FP)
|
|
||||||
RET
|
|
@ -1,56 +0,0 @@
|
|||||||
// Copyright 2016 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.
|
|
||||||
|
|
||||||
// +build s390x
|
|
||||||
// +build linux
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for s390x, Linux
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
BR syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
BR syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
BL runtime·entersyscall(SB)
|
|
||||||
MOVD a1+8(FP), R2
|
|
||||||
MOVD a2+16(FP), R3
|
|
||||||
MOVD a3+24(FP), R4
|
|
||||||
MOVD $0, R5
|
|
||||||
MOVD $0, R6
|
|
||||||
MOVD $0, R7
|
|
||||||
MOVD trap+0(FP), R1 // syscall entry
|
|
||||||
SYSCALL
|
|
||||||
MOVD R2, r1+32(FP)
|
|
||||||
MOVD R3, r2+40(FP)
|
|
||||||
BL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
BR syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
BR syscall·RawSyscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
|
||||||
MOVD a1+8(FP), R2
|
|
||||||
MOVD a2+16(FP), R3
|
|
||||||
MOVD a3+24(FP), R4
|
|
||||||
MOVD $0, R5
|
|
||||||
MOVD $0, R6
|
|
||||||
MOVD $0, R7
|
|
||||||
MOVD trap+0(FP), R1 // syscall entry
|
|
||||||
SYSCALL
|
|
||||||
MOVD R2, r1+32(FP)
|
|
||||||
MOVD R3, r2+40(FP)
|
|
||||||
RET
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2009 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for 386, NetBSD
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2009 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for AMD64, NetBSD
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
@ -1,29 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for ARM, NetBSD
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|
||||||
B syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|
||||||
B syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
|
||||||
B syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|
||||||
B syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|
||||||
B syscall·RawSyscall6(SB)
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2019 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for ARM64, NetBSD
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
B syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
B syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
|
||||||
B syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
B syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
B syscall·RawSyscall6(SB)
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2009 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for 386, OpenBSD
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2009 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for AMD64, OpenBSD
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for ARM, OpenBSD
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|
||||||
B syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|
||||||
B syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
|
||||||
B syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|
||||||
B syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|
||||||
B syscall·RawSyscall6(SB)
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2019 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System call support for arm64, OpenBSD
|
|
||||||
//
|
|
||||||
|
|
||||||
// Just jump to package syscall's implementation for all these functions.
|
|
||||||
// The runtime may know about them.
|
|
||||||
|
|
||||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·Syscall(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·Syscall6(SB)
|
|
||||||
|
|
||||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
|
||||||
JMP syscall·Syscall9(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
|
||||||
JMP syscall·RawSyscall(SB)
|
|
||||||
|
|
||||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
|
||||||
JMP syscall·RawSyscall6(SB)
|
|
@ -1,17 +0,0 @@
|
|||||||
// Copyright 2014 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.
|
|
||||||
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go
|
|
||||||
//
|
|
||||||
|
|
||||||
TEXT ·sysvicall6(SB),NOSPLIT,$0-88
|
|
||||||
JMP syscall·sysvicall6(SB)
|
|
||||||
|
|
||||||
TEXT ·rawSysvicall6(SB),NOSPLIT,$0-88
|
|
||||||
JMP syscall·rawSysvicall6(SB)
|
|
@ -1,36 +0,0 @@
|
|||||||
// Copyright 2016 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.
|
|
||||||
|
|
||||||
// Bluetooth sockets and messages
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Bluetooth Protocols
|
|
||||||
const (
|
|
||||||
BTPROTO_L2CAP = 0
|
|
||||||
BTPROTO_HCI = 1
|
|
||||||
BTPROTO_SCO = 2
|
|
||||||
BTPROTO_RFCOMM = 3
|
|
||||||
BTPROTO_BNEP = 4
|
|
||||||
BTPROTO_CMTP = 5
|
|
||||||
BTPROTO_HIDP = 6
|
|
||||||
BTPROTO_AVDTP = 7
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
HCI_CHANNEL_RAW = 0
|
|
||||||
HCI_CHANNEL_USER = 1
|
|
||||||
HCI_CHANNEL_MONITOR = 2
|
|
||||||
HCI_CHANNEL_CONTROL = 3
|
|
||||||
HCI_CHANNEL_LOGGING = 4
|
|
||||||
)
|
|
||||||
|
|
||||||
// Socketoption Level
|
|
||||||
const (
|
|
||||||
SOL_BLUETOOTH = 0x112
|
|
||||||
SOL_HCI = 0x0
|
|
||||||
SOL_L2CAP = 0x6
|
|
||||||
SOL_RFCOMM = 0x12
|
|
||||||
SOL_SCO = 0x11
|
|
||||||
)
|
|
@ -1,195 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// +build freebsd
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Go implementation of C mostly found in /usr/src/sys/kern/subr_capability.c
|
|
||||||
|
|
||||||
const (
|
|
||||||
// This is the version of CapRights this package understands. See C implementation for parallels.
|
|
||||||
capRightsGoVersion = CAP_RIGHTS_VERSION_00
|
|
||||||
capArSizeMin = CAP_RIGHTS_VERSION_00 + 2
|
|
||||||
capArSizeMax = capRightsGoVersion + 2
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
bit2idx = []int{
|
|
||||||
-1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1,
|
|
||||||
4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func capidxbit(right uint64) int {
|
|
||||||
return int((right >> 57) & 0x1f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func rightToIndex(right uint64) (int, error) {
|
|
||||||
idx := capidxbit(right)
|
|
||||||
if idx < 0 || idx >= len(bit2idx) {
|
|
||||||
return -2, fmt.Errorf("index for right 0x%x out of range", right)
|
|
||||||
}
|
|
||||||
return bit2idx[idx], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func caprver(right uint64) int {
|
|
||||||
return int(right >> 62)
|
|
||||||
}
|
|
||||||
|
|
||||||
func capver(rights *CapRights) int {
|
|
||||||
return caprver(rights.Rights[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func caparsize(rights *CapRights) int {
|
|
||||||
return capver(rights) + 2
|
|
||||||
}
|
|
||||||
|
|
||||||
// CapRightsSet sets the permissions in setrights in rights.
|
|
||||||
func CapRightsSet(rights *CapRights, setrights []uint64) error {
|
|
||||||
// This is essentially a copy of cap_rights_vset()
|
|
||||||
if capver(rights) != CAP_RIGHTS_VERSION_00 {
|
|
||||||
return fmt.Errorf("bad rights version %d", capver(rights))
|
|
||||||
}
|
|
||||||
|
|
||||||
n := caparsize(rights)
|
|
||||||
if n < capArSizeMin || n > capArSizeMax {
|
|
||||||
return errors.New("bad rights size")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, right := range setrights {
|
|
||||||
if caprver(right) != CAP_RIGHTS_VERSION_00 {
|
|
||||||
return errors.New("bad right version")
|
|
||||||
}
|
|
||||||
i, err := rightToIndex(right)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if i >= n {
|
|
||||||
return errors.New("index overflow")
|
|
||||||
}
|
|
||||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
|
||||||
return errors.New("index mismatch")
|
|
||||||
}
|
|
||||||
rights.Rights[i] |= right
|
|
||||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
|
||||||
return errors.New("index mismatch (after assign)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CapRightsClear clears the permissions in clearrights from rights.
|
|
||||||
func CapRightsClear(rights *CapRights, clearrights []uint64) error {
|
|
||||||
// This is essentially a copy of cap_rights_vclear()
|
|
||||||
if capver(rights) != CAP_RIGHTS_VERSION_00 {
|
|
||||||
return fmt.Errorf("bad rights version %d", capver(rights))
|
|
||||||
}
|
|
||||||
|
|
||||||
n := caparsize(rights)
|
|
||||||
if n < capArSizeMin || n > capArSizeMax {
|
|
||||||
return errors.New("bad rights size")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, right := range clearrights {
|
|
||||||
if caprver(right) != CAP_RIGHTS_VERSION_00 {
|
|
||||||
return errors.New("bad right version")
|
|
||||||
}
|
|
||||||
i, err := rightToIndex(right)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if i >= n {
|
|
||||||
return errors.New("index overflow")
|
|
||||||
}
|
|
||||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
|
||||||
return errors.New("index mismatch")
|
|
||||||
}
|
|
||||||
rights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF)
|
|
||||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
|
||||||
return errors.New("index mismatch (after assign)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CapRightsIsSet checks whether all the permissions in setrights are present in rights.
|
|
||||||
func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) {
|
|
||||||
// This is essentially a copy of cap_rights_is_vset()
|
|
||||||
if capver(rights) != CAP_RIGHTS_VERSION_00 {
|
|
||||||
return false, fmt.Errorf("bad rights version %d", capver(rights))
|
|
||||||
}
|
|
||||||
|
|
||||||
n := caparsize(rights)
|
|
||||||
if n < capArSizeMin || n > capArSizeMax {
|
|
||||||
return false, errors.New("bad rights size")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, right := range setrights {
|
|
||||||
if caprver(right) != CAP_RIGHTS_VERSION_00 {
|
|
||||||
return false, errors.New("bad right version")
|
|
||||||
}
|
|
||||||
i, err := rightToIndex(right)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if i >= n {
|
|
||||||
return false, errors.New("index overflow")
|
|
||||||
}
|
|
||||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
|
||||||
return false, errors.New("index mismatch")
|
|
||||||
}
|
|
||||||
if (rights.Rights[i] & right) != right {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func capright(idx uint64, bit uint64) uint64 {
|
|
||||||
return ((1 << (57 + idx)) | bit)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CapRightsInit returns a pointer to an initialised CapRights structure filled with rights.
|
|
||||||
// See man cap_rights_init(3) and rights(4).
|
|
||||||
func CapRightsInit(rights []uint64) (*CapRights, error) {
|
|
||||||
var r CapRights
|
|
||||||
r.Rights[0] = (capRightsGoVersion << 62) | capright(0, 0)
|
|
||||||
r.Rights[1] = capright(1, 0)
|
|
||||||
|
|
||||||
err := CapRightsSet(&r, rights)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &r, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CapRightsLimit reduces the operations permitted on fd to at most those contained in rights.
|
|
||||||
// The capability rights on fd can never be increased by CapRightsLimit.
|
|
||||||
// See man cap_rights_limit(2) and rights(4).
|
|
||||||
func CapRightsLimit(fd uintptr, rights *CapRights) error {
|
|
||||||
return capRightsLimit(int(fd), rights)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CapRightsGet returns a CapRights structure containing the operations permitted on fd.
|
|
||||||
// See man cap_rights_get(3) and rights(4).
|
|
||||||
func CapRightsGet(fd uintptr) (*CapRights, error) {
|
|
||||||
r, err := CapRightsInit(nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = capRightsGet(capRightsGoVersion, int(fd), r)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return r, nil
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
// Copyright 2015 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.
|
|
||||||
|
|
||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
const (
|
|
||||||
R_OK = 0x4
|
|
||||||
W_OK = 0x2
|
|
||||||
X_OK = 0x1
|
|
||||||
)
|
|
@ -1,27 +0,0 @@
|
|||||||
// Copyright 2018 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.
|
|
||||||
|
|
||||||
// +build aix
|
|
||||||
// +build ppc
|
|
||||||
|
|
||||||
// Functions to access/create device major and minor numbers matching the
|
|
||||||
// encoding used by AIX.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Major returns the major component of a Linux device number.
|
|
||||||
func Major(dev uint64) uint32 {
|
|
||||||
return uint32((dev >> 16) & 0xffff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor component of a Linux device number.
|
|
||||||
func Minor(dev uint64) uint32 {
|
|
||||||
return uint32(dev & 0xffff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdev returns a Linux device number generated from the given major and minor
|
|
||||||
// components.
|
|
||||||
func Mkdev(major, minor uint32) uint64 {
|
|
||||||
return uint64(((major) << 16) | (minor))
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2018 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.
|
|
||||||
|
|
||||||
// +build aix
|
|
||||||
// +build ppc64
|
|
||||||
|
|
||||||
// Functions to access/create device major and minor numbers matching the
|
|
||||||
// encoding used AIX.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Major returns the major component of a Linux device number.
|
|
||||||
func Major(dev uint64) uint32 {
|
|
||||||
return uint32((dev & 0x3fffffff00000000) >> 32)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor component of a Linux device number.
|
|
||||||
func Minor(dev uint64) uint32 {
|
|
||||||
return uint32((dev & 0x00000000ffffffff) >> 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdev returns a Linux device number generated from the given major and minor
|
|
||||||
// components.
|
|
||||||
func Mkdev(major, minor uint32) uint64 {
|
|
||||||
var DEVNO64 uint64
|
|
||||||
DEVNO64 = 0x8000000000000000
|
|
||||||
return ((uint64(major) << 32) | (uint64(minor) & 0x00000000FFFFFFFF) | DEVNO64)
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// Functions to access/create device major and minor numbers matching the
|
|
||||||
// encoding used in Darwin's sys/types.h header.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Major returns the major component of a Darwin device number.
|
|
||||||
func Major(dev uint64) uint32 {
|
|
||||||
return uint32((dev >> 24) & 0xff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor component of a Darwin device number.
|
|
||||||
func Minor(dev uint64) uint32 {
|
|
||||||
return uint32(dev & 0xffffff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdev returns a Darwin device number generated from the given major and minor
|
|
||||||
// components.
|
|
||||||
func Mkdev(major, minor uint32) uint64 {
|
|
||||||
return (uint64(major) << 24) | uint64(minor)
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// Functions to access/create device major and minor numbers matching the
|
|
||||||
// encoding used in Dragonfly's sys/types.h header.
|
|
||||||
//
|
|
||||||
// The information below is extracted and adapted from sys/types.h:
|
|
||||||
//
|
|
||||||
// Minor gives a cookie instead of an index since in order to avoid changing the
|
|
||||||
// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for
|
|
||||||
// devices that don't use them.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Major returns the major component of a DragonFlyBSD device number.
|
|
||||||
func Major(dev uint64) uint32 {
|
|
||||||
return uint32((dev >> 8) & 0xff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor component of a DragonFlyBSD device number.
|
|
||||||
func Minor(dev uint64) uint32 {
|
|
||||||
return uint32(dev & 0xffff00ff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdev returns a DragonFlyBSD device number generated from the given major and
|
|
||||||
// minor components.
|
|
||||||
func Mkdev(major, minor uint32) uint64 {
|
|
||||||
return (uint64(major) << 8) | uint64(minor)
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// Functions to access/create device major and minor numbers matching the
|
|
||||||
// encoding used in FreeBSD's sys/types.h header.
|
|
||||||
//
|
|
||||||
// The information below is extracted and adapted from sys/types.h:
|
|
||||||
//
|
|
||||||
// Minor gives a cookie instead of an index since in order to avoid changing the
|
|
||||||
// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for
|
|
||||||
// devices that don't use them.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Major returns the major component of a FreeBSD device number.
|
|
||||||
func Major(dev uint64) uint32 {
|
|
||||||
return uint32((dev >> 8) & 0xff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor component of a FreeBSD device number.
|
|
||||||
func Minor(dev uint64) uint32 {
|
|
||||||
return uint32(dev & 0xffff00ff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdev returns a FreeBSD device number generated from the given major and
|
|
||||||
// minor components.
|
|
||||||
func Mkdev(major, minor uint32) uint64 {
|
|
||||||
return (uint64(major) << 8) | uint64(minor)
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// Functions to access/create device major and minor numbers matching the
|
|
||||||
// encoding used by the Linux kernel and glibc.
|
|
||||||
//
|
|
||||||
// The information below is extracted and adapted from bits/sysmacros.h in the
|
|
||||||
// glibc sources:
|
|
||||||
//
|
|
||||||
// dev_t in glibc is 64-bit, with 32-bit major and minor numbers. glibc's
|
|
||||||
// default encoding is MMMM Mmmm mmmM MMmm, where M is a hex digit of the major
|
|
||||||
// number and m is a hex digit of the minor number. This is backward compatible
|
|
||||||
// with legacy systems where dev_t is 16 bits wide, encoded as MMmm. It is also
|
|
||||||
// backward compatible with the Linux kernel, which for some architectures uses
|
|
||||||
// 32-bit dev_t, encoded as mmmM MMmm.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Major returns the major component of a Linux device number.
|
|
||||||
func Major(dev uint64) uint32 {
|
|
||||||
major := uint32((dev & 0x00000000000fff00) >> 8)
|
|
||||||
major |= uint32((dev & 0xfffff00000000000) >> 32)
|
|
||||||
return major
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor component of a Linux device number.
|
|
||||||
func Minor(dev uint64) uint32 {
|
|
||||||
minor := uint32((dev & 0x00000000000000ff) >> 0)
|
|
||||||
minor |= uint32((dev & 0x00000ffffff00000) >> 12)
|
|
||||||
return minor
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdev returns a Linux device number generated from the given major and minor
|
|
||||||
// components.
|
|
||||||
func Mkdev(major, minor uint32) uint64 {
|
|
||||||
dev := (uint64(major) & 0x00000fff) << 8
|
|
||||||
dev |= (uint64(major) & 0xfffff000) << 32
|
|
||||||
dev |= (uint64(minor) & 0x000000ff) << 0
|
|
||||||
dev |= (uint64(minor) & 0xffffff00) << 12
|
|
||||||
return dev
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// Functions to access/create device major and minor numbers matching the
|
|
||||||
// encoding used in NetBSD's sys/types.h header.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Major returns the major component of a NetBSD device number.
|
|
||||||
func Major(dev uint64) uint32 {
|
|
||||||
return uint32((dev & 0x000fff00) >> 8)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor component of a NetBSD device number.
|
|
||||||
func Minor(dev uint64) uint32 {
|
|
||||||
minor := uint32((dev & 0x000000ff) >> 0)
|
|
||||||
minor |= uint32((dev & 0xfff00000) >> 12)
|
|
||||||
return minor
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdev returns a NetBSD device number generated from the given major and minor
|
|
||||||
// components.
|
|
||||||
func Mkdev(major, minor uint32) uint64 {
|
|
||||||
dev := (uint64(major) << 8) & 0x000fff00
|
|
||||||
dev |= (uint64(minor) << 12) & 0xfff00000
|
|
||||||
dev |= (uint64(minor) << 0) & 0x000000ff
|
|
||||||
return dev
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// Functions to access/create device major and minor numbers matching the
|
|
||||||
// encoding used in OpenBSD's sys/types.h header.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Major returns the major component of an OpenBSD device number.
|
|
||||||
func Major(dev uint64) uint32 {
|
|
||||||
return uint32((dev & 0x0000ff00) >> 8)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor returns the minor component of an OpenBSD device number.
|
|
||||||
func Minor(dev uint64) uint32 {
|
|
||||||
minor := uint32((dev & 0x000000ff) >> 0)
|
|
||||||
minor |= uint32((dev & 0xffff0000) >> 8)
|
|
||||||
return minor
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdev returns an OpenBSD device number generated from the given major and minor
|
|
||||||
// components.
|
|
||||||
func Mkdev(major, minor uint32) uint64 {
|
|
||||||
dev := (uint64(major) << 8) & 0x0000ff00
|
|
||||||
dev |= (uint64(minor) << 8) & 0xffff0000
|
|
||||||
dev |= (uint64(minor) << 0) & 0x000000ff
|
|
||||||
return dev
|
|
||||||
}
|
|
@ -1,102 +0,0 @@
|
|||||||
// Copyright 2009 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.
|
|
||||||
|
|
||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
// readInt returns the size-bytes unsigned integer in native byte order at offset off.
|
|
||||||
func readInt(b []byte, off, size uintptr) (u uint64, ok bool) {
|
|
||||||
if len(b) < int(off+size) {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
if isBigEndian {
|
|
||||||
return readIntBE(b[off:], size), true
|
|
||||||
}
|
|
||||||
return readIntLE(b[off:], size), true
|
|
||||||
}
|
|
||||||
|
|
||||||
func readIntBE(b []byte, size uintptr) uint64 {
|
|
||||||
switch size {
|
|
||||||
case 1:
|
|
||||||
return uint64(b[0])
|
|
||||||
case 2:
|
|
||||||
_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
|
|
||||||
return uint64(b[1]) | uint64(b[0])<<8
|
|
||||||
case 4:
|
|
||||||
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
|
|
||||||
return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24
|
|
||||||
case 8:
|
|
||||||
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
|
|
||||||
return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
|
|
||||||
uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
|
|
||||||
default:
|
|
||||||
panic("syscall: readInt with unsupported size")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func readIntLE(b []byte, size uintptr) uint64 {
|
|
||||||
switch size {
|
|
||||||
case 1:
|
|
||||||
return uint64(b[0])
|
|
||||||
case 2:
|
|
||||||
_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
|
|
||||||
return uint64(b[0]) | uint64(b[1])<<8
|
|
||||||
case 4:
|
|
||||||
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
|
|
||||||
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24
|
|
||||||
case 8:
|
|
||||||
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
|
|
||||||
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
|
|
||||||
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
|
|
||||||
default:
|
|
||||||
panic("syscall: readInt with unsupported size")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseDirent parses up to max directory entries in buf,
|
|
||||||
// appending the names to names. It returns the number of
|
|
||||||
// bytes consumed from buf, the number of entries added
|
|
||||||
// to names, and the new names slice.
|
|
||||||
func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
|
|
||||||
origlen := len(buf)
|
|
||||||
count = 0
|
|
||||||
for max != 0 && len(buf) > 0 {
|
|
||||||
reclen, ok := direntReclen(buf)
|
|
||||||
if !ok || reclen > uint64(len(buf)) {
|
|
||||||
return origlen, count, names
|
|
||||||
}
|
|
||||||
rec := buf[:reclen]
|
|
||||||
buf = buf[reclen:]
|
|
||||||
ino, ok := direntIno(rec)
|
|
||||||
if !ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if ino == 0 { // File absent in directory.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
const namoff = uint64(unsafe.Offsetof(Dirent{}.Name))
|
|
||||||
namlen, ok := direntNamlen(rec)
|
|
||||||
if !ok || namoff+namlen > uint64(len(rec)) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
name := rec[namoff : namoff+namlen]
|
|
||||||
for i, c := range name {
|
|
||||||
if c == 0 {
|
|
||||||
name = name[:i]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Check for useless names before allocating a string.
|
|
||||||
if string(name) == "." || string(name) == ".." {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
max--
|
|
||||||
count++
|
|
||||||
names = append(names, string(name))
|
|
||||||
}
|
|
||||||
return origlen - len(buf), count, names
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
// Copyright 2016 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.
|
|
||||||
//
|
|
||||||
// +build ppc64 s390x mips mips64
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
const isBigEndian = true
|
|
@ -1,9 +0,0 @@
|
|||||||
// Copyright 2016 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.
|
|
||||||
//
|
|
||||||
// +build 386 amd64 amd64p32 arm arm64 ppc64le mipsle mips64le riscv64
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
const isBigEndian = false
|
|
@ -1,31 +0,0 @@
|
|||||||
// Copyright 2010 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.
|
|
||||||
|
|
||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
|
||||||
|
|
||||||
// Unix environment variables.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
func Getenv(key string) (value string, found bool) {
|
|
||||||
return syscall.Getenv(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Setenv(key, value string) error {
|
|
||||||
return syscall.Setenv(key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Clearenv() {
|
|
||||||
syscall.Clearenv()
|
|
||||||
}
|
|
||||||
|
|
||||||
func Environ() []string {
|
|
||||||
return syscall.Environ()
|
|
||||||
}
|
|
||||||
|
|
||||||
func Unsetenv(key string) error {
|
|
||||||
return syscall.Unsetenv(key)
|
|
||||||
}
|
|
@ -1,233 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
|
|
||||||
// them here for backwards compatibility.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
const (
|
|
||||||
DLT_HHDLC = 0x79
|
|
||||||
IFF_SMART = 0x20
|
|
||||||
IFT_1822 = 0x2
|
|
||||||
IFT_A12MPPSWITCH = 0x82
|
|
||||||
IFT_AAL2 = 0xbb
|
|
||||||
IFT_AAL5 = 0x31
|
|
||||||
IFT_ADSL = 0x5e
|
|
||||||
IFT_AFLANE8023 = 0x3b
|
|
||||||
IFT_AFLANE8025 = 0x3c
|
|
||||||
IFT_ARAP = 0x58
|
|
||||||
IFT_ARCNET = 0x23
|
|
||||||
IFT_ARCNETPLUS = 0x24
|
|
||||||
IFT_ASYNC = 0x54
|
|
||||||
IFT_ATM = 0x25
|
|
||||||
IFT_ATMDXI = 0x69
|
|
||||||
IFT_ATMFUNI = 0x6a
|
|
||||||
IFT_ATMIMA = 0x6b
|
|
||||||
IFT_ATMLOGICAL = 0x50
|
|
||||||
IFT_ATMRADIO = 0xbd
|
|
||||||
IFT_ATMSUBINTERFACE = 0x86
|
|
||||||
IFT_ATMVCIENDPT = 0xc2
|
|
||||||
IFT_ATMVIRTUAL = 0x95
|
|
||||||
IFT_BGPPOLICYACCOUNTING = 0xa2
|
|
||||||
IFT_BSC = 0x53
|
|
||||||
IFT_CCTEMUL = 0x3d
|
|
||||||
IFT_CEPT = 0x13
|
|
||||||
IFT_CES = 0x85
|
|
||||||
IFT_CHANNEL = 0x46
|
|
||||||
IFT_CNR = 0x55
|
|
||||||
IFT_COFFEE = 0x84
|
|
||||||
IFT_COMPOSITELINK = 0x9b
|
|
||||||
IFT_DCN = 0x8d
|
|
||||||
IFT_DIGITALPOWERLINE = 0x8a
|
|
||||||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
|
|
||||||
IFT_DLSW = 0x4a
|
|
||||||
IFT_DOCSCABLEDOWNSTREAM = 0x80
|
|
||||||
IFT_DOCSCABLEMACLAYER = 0x7f
|
|
||||||
IFT_DOCSCABLEUPSTREAM = 0x81
|
|
||||||
IFT_DS0 = 0x51
|
|
||||||
IFT_DS0BUNDLE = 0x52
|
|
||||||
IFT_DS1FDL = 0xaa
|
|
||||||
IFT_DS3 = 0x1e
|
|
||||||
IFT_DTM = 0x8c
|
|
||||||
IFT_DVBASILN = 0xac
|
|
||||||
IFT_DVBASIOUT = 0xad
|
|
||||||
IFT_DVBRCCDOWNSTREAM = 0x93
|
|
||||||
IFT_DVBRCCMACLAYER = 0x92
|
|
||||||
IFT_DVBRCCUPSTREAM = 0x94
|
|
||||||
IFT_ENC = 0xf4
|
|
||||||
IFT_EON = 0x19
|
|
||||||
IFT_EPLRS = 0x57
|
|
||||||
IFT_ESCON = 0x49
|
|
||||||
IFT_ETHER = 0x6
|
|
||||||
IFT_FAITH = 0xf2
|
|
||||||
IFT_FAST = 0x7d
|
|
||||||
IFT_FASTETHER = 0x3e
|
|
||||||
IFT_FASTETHERFX = 0x45
|
|
||||||
IFT_FDDI = 0xf
|
|
||||||
IFT_FIBRECHANNEL = 0x38
|
|
||||||
IFT_FRAMERELAYINTERCONNECT = 0x3a
|
|
||||||
IFT_FRAMERELAYMPI = 0x5c
|
|
||||||
IFT_FRDLCIENDPT = 0xc1
|
|
||||||
IFT_FRELAY = 0x20
|
|
||||||
IFT_FRELAYDCE = 0x2c
|
|
||||||
IFT_FRF16MFRBUNDLE = 0xa3
|
|
||||||
IFT_FRFORWARD = 0x9e
|
|
||||||
IFT_G703AT2MB = 0x43
|
|
||||||
IFT_G703AT64K = 0x42
|
|
||||||
IFT_GIF = 0xf0
|
|
||||||
IFT_GIGABITETHERNET = 0x75
|
|
||||||
IFT_GR303IDT = 0xb2
|
|
||||||
IFT_GR303RDT = 0xb1
|
|
||||||
IFT_H323GATEKEEPER = 0xa4
|
|
||||||
IFT_H323PROXY = 0xa5
|
|
||||||
IFT_HDH1822 = 0x3
|
|
||||||
IFT_HDLC = 0x76
|
|
||||||
IFT_HDSL2 = 0xa8
|
|
||||||
IFT_HIPERLAN2 = 0xb7
|
|
||||||
IFT_HIPPI = 0x2f
|
|
||||||
IFT_HIPPIINTERFACE = 0x39
|
|
||||||
IFT_HOSTPAD = 0x5a
|
|
||||||
IFT_HSSI = 0x2e
|
|
||||||
IFT_HY = 0xe
|
|
||||||
IFT_IBM370PARCHAN = 0x48
|
|
||||||
IFT_IDSL = 0x9a
|
|
||||||
IFT_IEEE80211 = 0x47
|
|
||||||
IFT_IEEE80212 = 0x37
|
|
||||||
IFT_IEEE8023ADLAG = 0xa1
|
|
||||||
IFT_IFGSN = 0x91
|
|
||||||
IFT_IMT = 0xbe
|
|
||||||
IFT_INTERLEAVE = 0x7c
|
|
||||||
IFT_IP = 0x7e
|
|
||||||
IFT_IPFORWARD = 0x8e
|
|
||||||
IFT_IPOVERATM = 0x72
|
|
||||||
IFT_IPOVERCDLC = 0x6d
|
|
||||||
IFT_IPOVERCLAW = 0x6e
|
|
||||||
IFT_IPSWITCH = 0x4e
|
|
||||||
IFT_IPXIP = 0xf9
|
|
||||||
IFT_ISDN = 0x3f
|
|
||||||
IFT_ISDNBASIC = 0x14
|
|
||||||
IFT_ISDNPRIMARY = 0x15
|
|
||||||
IFT_ISDNS = 0x4b
|
|
||||||
IFT_ISDNU = 0x4c
|
|
||||||
IFT_ISO88022LLC = 0x29
|
|
||||||
IFT_ISO88023 = 0x7
|
|
||||||
IFT_ISO88024 = 0x8
|
|
||||||
IFT_ISO88025 = 0x9
|
|
||||||
IFT_ISO88025CRFPINT = 0x62
|
|
||||||
IFT_ISO88025DTR = 0x56
|
|
||||||
IFT_ISO88025FIBER = 0x73
|
|
||||||
IFT_ISO88026 = 0xa
|
|
||||||
IFT_ISUP = 0xb3
|
|
||||||
IFT_L3IPXVLAN = 0x89
|
|
||||||
IFT_LAPB = 0x10
|
|
||||||
IFT_LAPD = 0x4d
|
|
||||||
IFT_LAPF = 0x77
|
|
||||||
IFT_LOCALTALK = 0x2a
|
|
||||||
IFT_LOOP = 0x18
|
|
||||||
IFT_MEDIAMAILOVERIP = 0x8b
|
|
||||||
IFT_MFSIGLINK = 0xa7
|
|
||||||
IFT_MIOX25 = 0x26
|
|
||||||
IFT_MODEM = 0x30
|
|
||||||
IFT_MPC = 0x71
|
|
||||||
IFT_MPLS = 0xa6
|
|
||||||
IFT_MPLSTUNNEL = 0x96
|
|
||||||
IFT_MSDSL = 0x8f
|
|
||||||
IFT_MVL = 0xbf
|
|
||||||
IFT_MYRINET = 0x63
|
|
||||||
IFT_NFAS = 0xaf
|
|
||||||
IFT_NSIP = 0x1b
|
|
||||||
IFT_OPTICALCHANNEL = 0xc3
|
|
||||||
IFT_OPTICALTRANSPORT = 0xc4
|
|
||||||
IFT_OTHER = 0x1
|
|
||||||
IFT_P10 = 0xc
|
|
||||||
IFT_P80 = 0xd
|
|
||||||
IFT_PARA = 0x22
|
|
||||||
IFT_PFLOG = 0xf6
|
|
||||||
IFT_PFSYNC = 0xf7
|
|
||||||
IFT_PLC = 0xae
|
|
||||||
IFT_POS = 0xab
|
|
||||||
IFT_PPPMULTILINKBUNDLE = 0x6c
|
|
||||||
IFT_PROPBWAP2MP = 0xb8
|
|
||||||
IFT_PROPCNLS = 0x59
|
|
||||||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
|
|
||||||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
|
|
||||||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
|
|
||||||
IFT_PROPMUX = 0x36
|
|
||||||
IFT_PROPWIRELESSP2P = 0x9d
|
|
||||||
IFT_PTPSERIAL = 0x16
|
|
||||||
IFT_PVC = 0xf1
|
|
||||||
IFT_QLLC = 0x44
|
|
||||||
IFT_RADIOMAC = 0xbc
|
|
||||||
IFT_RADSL = 0x5f
|
|
||||||
IFT_REACHDSL = 0xc0
|
|
||||||
IFT_RFC1483 = 0x9f
|
|
||||||
IFT_RS232 = 0x21
|
|
||||||
IFT_RSRB = 0x4f
|
|
||||||
IFT_SDLC = 0x11
|
|
||||||
IFT_SDSL = 0x60
|
|
||||||
IFT_SHDSL = 0xa9
|
|
||||||
IFT_SIP = 0x1f
|
|
||||||
IFT_SLIP = 0x1c
|
|
||||||
IFT_SMDSDXI = 0x2b
|
|
||||||
IFT_SMDSICIP = 0x34
|
|
||||||
IFT_SONET = 0x27
|
|
||||||
IFT_SONETOVERHEADCHANNEL = 0xb9
|
|
||||||
IFT_SONETPATH = 0x32
|
|
||||||
IFT_SONETVT = 0x33
|
|
||||||
IFT_SRP = 0x97
|
|
||||||
IFT_SS7SIGLINK = 0x9c
|
|
||||||
IFT_STACKTOSTACK = 0x6f
|
|
||||||
IFT_STARLAN = 0xb
|
|
||||||
IFT_STF = 0xd7
|
|
||||||
IFT_T1 = 0x12
|
|
||||||
IFT_TDLC = 0x74
|
|
||||||
IFT_TERMPAD = 0x5b
|
|
||||||
IFT_TR008 = 0xb0
|
|
||||||
IFT_TRANSPHDLC = 0x7b
|
|
||||||
IFT_TUNNEL = 0x83
|
|
||||||
IFT_ULTRA = 0x1d
|
|
||||||
IFT_USB = 0xa0
|
|
||||||
IFT_V11 = 0x40
|
|
||||||
IFT_V35 = 0x2d
|
|
||||||
IFT_V36 = 0x41
|
|
||||||
IFT_V37 = 0x78
|
|
||||||
IFT_VDSL = 0x61
|
|
||||||
IFT_VIRTUALIPADDRESS = 0x70
|
|
||||||
IFT_VOICEEM = 0x64
|
|
||||||
IFT_VOICEENCAP = 0x67
|
|
||||||
IFT_VOICEFXO = 0x65
|
|
||||||
IFT_VOICEFXS = 0x66
|
|
||||||
IFT_VOICEOVERATM = 0x98
|
|
||||||
IFT_VOICEOVERFRAMERELAY = 0x99
|
|
||||||
IFT_VOICEOVERIP = 0x68
|
|
||||||
IFT_X213 = 0x5d
|
|
||||||
IFT_X25 = 0x5
|
|
||||||
IFT_X25DDN = 0x4
|
|
||||||
IFT_X25HUNTGROUP = 0x7a
|
|
||||||
IFT_X25MLP = 0x79
|
|
||||||
IFT_X25PLE = 0x28
|
|
||||||
IFT_XETHER = 0x1a
|
|
||||||
IPPROTO_MAXID = 0x34
|
|
||||||
IPV6_FAITH = 0x1d
|
|
||||||
IPV6_MIN_MEMBERSHIPS = 0x1f
|
|
||||||
IP_FAITH = 0x16
|
|
||||||
IP_MAX_SOURCE_FILTER = 0x400
|
|
||||||
IP_MIN_MEMBERSHIPS = 0x1f
|
|
||||||
MAP_NORESERVE = 0x40
|
|
||||||
MAP_RENAME = 0x20
|
|
||||||
NET_RT_MAXID = 0x6
|
|
||||||
RTF_PRCLONING = 0x10000
|
|
||||||
RTM_OLDADD = 0x9
|
|
||||||
RTM_OLDDEL = 0xa
|
|
||||||
RT_CACHING_CONTEXT = 0x1
|
|
||||||
RT_NORTREF = 0x2
|
|
||||||
SIOCADDRT = 0x8030720a
|
|
||||||
SIOCALIFADDR = 0x8118691b
|
|
||||||
SIOCDELRT = 0x8030720b
|
|
||||||
SIOCDLIFADDR = 0x8118691d
|
|
||||||
SIOCGLIFADDR = 0xc118691c
|
|
||||||
SIOCGLIFPHYADDR = 0xc118694b
|
|
||||||
SIOCSLIFPHYADDR = 0x8118694a
|
|
||||||
)
|
|
@ -1,233 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
|
|
||||||
// them here for backwards compatibility.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
const (
|
|
||||||
DLT_HHDLC = 0x79
|
|
||||||
IFF_SMART = 0x20
|
|
||||||
IFT_1822 = 0x2
|
|
||||||
IFT_A12MPPSWITCH = 0x82
|
|
||||||
IFT_AAL2 = 0xbb
|
|
||||||
IFT_AAL5 = 0x31
|
|
||||||
IFT_ADSL = 0x5e
|
|
||||||
IFT_AFLANE8023 = 0x3b
|
|
||||||
IFT_AFLANE8025 = 0x3c
|
|
||||||
IFT_ARAP = 0x58
|
|
||||||
IFT_ARCNET = 0x23
|
|
||||||
IFT_ARCNETPLUS = 0x24
|
|
||||||
IFT_ASYNC = 0x54
|
|
||||||
IFT_ATM = 0x25
|
|
||||||
IFT_ATMDXI = 0x69
|
|
||||||
IFT_ATMFUNI = 0x6a
|
|
||||||
IFT_ATMIMA = 0x6b
|
|
||||||
IFT_ATMLOGICAL = 0x50
|
|
||||||
IFT_ATMRADIO = 0xbd
|
|
||||||
IFT_ATMSUBINTERFACE = 0x86
|
|
||||||
IFT_ATMVCIENDPT = 0xc2
|
|
||||||
IFT_ATMVIRTUAL = 0x95
|
|
||||||
IFT_BGPPOLICYACCOUNTING = 0xa2
|
|
||||||
IFT_BSC = 0x53
|
|
||||||
IFT_CCTEMUL = 0x3d
|
|
||||||
IFT_CEPT = 0x13
|
|
||||||
IFT_CES = 0x85
|
|
||||||
IFT_CHANNEL = 0x46
|
|
||||||
IFT_CNR = 0x55
|
|
||||||
IFT_COFFEE = 0x84
|
|
||||||
IFT_COMPOSITELINK = 0x9b
|
|
||||||
IFT_DCN = 0x8d
|
|
||||||
IFT_DIGITALPOWERLINE = 0x8a
|
|
||||||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
|
|
||||||
IFT_DLSW = 0x4a
|
|
||||||
IFT_DOCSCABLEDOWNSTREAM = 0x80
|
|
||||||
IFT_DOCSCABLEMACLAYER = 0x7f
|
|
||||||
IFT_DOCSCABLEUPSTREAM = 0x81
|
|
||||||
IFT_DS0 = 0x51
|
|
||||||
IFT_DS0BUNDLE = 0x52
|
|
||||||
IFT_DS1FDL = 0xaa
|
|
||||||
IFT_DS3 = 0x1e
|
|
||||||
IFT_DTM = 0x8c
|
|
||||||
IFT_DVBASILN = 0xac
|
|
||||||
IFT_DVBASIOUT = 0xad
|
|
||||||
IFT_DVBRCCDOWNSTREAM = 0x93
|
|
||||||
IFT_DVBRCCMACLAYER = 0x92
|
|
||||||
IFT_DVBRCCUPSTREAM = 0x94
|
|
||||||
IFT_ENC = 0xf4
|
|
||||||
IFT_EON = 0x19
|
|
||||||
IFT_EPLRS = 0x57
|
|
||||||
IFT_ESCON = 0x49
|
|
||||||
IFT_ETHER = 0x6
|
|
||||||
IFT_FAITH = 0xf2
|
|
||||||
IFT_FAST = 0x7d
|
|
||||||
IFT_FASTETHER = 0x3e
|
|
||||||
IFT_FASTETHERFX = 0x45
|
|
||||||
IFT_FDDI = 0xf
|
|
||||||
IFT_FIBRECHANNEL = 0x38
|
|
||||||
IFT_FRAMERELAYINTERCONNECT = 0x3a
|
|
||||||
IFT_FRAMERELAYMPI = 0x5c
|
|
||||||
IFT_FRDLCIENDPT = 0xc1
|
|
||||||
IFT_FRELAY = 0x20
|
|
||||||
IFT_FRELAYDCE = 0x2c
|
|
||||||
IFT_FRF16MFRBUNDLE = 0xa3
|
|
||||||
IFT_FRFORWARD = 0x9e
|
|
||||||
IFT_G703AT2MB = 0x43
|
|
||||||
IFT_G703AT64K = 0x42
|
|
||||||
IFT_GIF = 0xf0
|
|
||||||
IFT_GIGABITETHERNET = 0x75
|
|
||||||
IFT_GR303IDT = 0xb2
|
|
||||||
IFT_GR303RDT = 0xb1
|
|
||||||
IFT_H323GATEKEEPER = 0xa4
|
|
||||||
IFT_H323PROXY = 0xa5
|
|
||||||
IFT_HDH1822 = 0x3
|
|
||||||
IFT_HDLC = 0x76
|
|
||||||
IFT_HDSL2 = 0xa8
|
|
||||||
IFT_HIPERLAN2 = 0xb7
|
|
||||||
IFT_HIPPI = 0x2f
|
|
||||||
IFT_HIPPIINTERFACE = 0x39
|
|
||||||
IFT_HOSTPAD = 0x5a
|
|
||||||
IFT_HSSI = 0x2e
|
|
||||||
IFT_HY = 0xe
|
|
||||||
IFT_IBM370PARCHAN = 0x48
|
|
||||||
IFT_IDSL = 0x9a
|
|
||||||
IFT_IEEE80211 = 0x47
|
|
||||||
IFT_IEEE80212 = 0x37
|
|
||||||
IFT_IEEE8023ADLAG = 0xa1
|
|
||||||
IFT_IFGSN = 0x91
|
|
||||||
IFT_IMT = 0xbe
|
|
||||||
IFT_INTERLEAVE = 0x7c
|
|
||||||
IFT_IP = 0x7e
|
|
||||||
IFT_IPFORWARD = 0x8e
|
|
||||||
IFT_IPOVERATM = 0x72
|
|
||||||
IFT_IPOVERCDLC = 0x6d
|
|
||||||
IFT_IPOVERCLAW = 0x6e
|
|
||||||
IFT_IPSWITCH = 0x4e
|
|
||||||
IFT_IPXIP = 0xf9
|
|
||||||
IFT_ISDN = 0x3f
|
|
||||||
IFT_ISDNBASIC = 0x14
|
|
||||||
IFT_ISDNPRIMARY = 0x15
|
|
||||||
IFT_ISDNS = 0x4b
|
|
||||||
IFT_ISDNU = 0x4c
|
|
||||||
IFT_ISO88022LLC = 0x29
|
|
||||||
IFT_ISO88023 = 0x7
|
|
||||||
IFT_ISO88024 = 0x8
|
|
||||||
IFT_ISO88025 = 0x9
|
|
||||||
IFT_ISO88025CRFPINT = 0x62
|
|
||||||
IFT_ISO88025DTR = 0x56
|
|
||||||
IFT_ISO88025FIBER = 0x73
|
|
||||||
IFT_ISO88026 = 0xa
|
|
||||||
IFT_ISUP = 0xb3
|
|
||||||
IFT_L3IPXVLAN = 0x89
|
|
||||||
IFT_LAPB = 0x10
|
|
||||||
IFT_LAPD = 0x4d
|
|
||||||
IFT_LAPF = 0x77
|
|
||||||
IFT_LOCALTALK = 0x2a
|
|
||||||
IFT_LOOP = 0x18
|
|
||||||
IFT_MEDIAMAILOVERIP = 0x8b
|
|
||||||
IFT_MFSIGLINK = 0xa7
|
|
||||||
IFT_MIOX25 = 0x26
|
|
||||||
IFT_MODEM = 0x30
|
|
||||||
IFT_MPC = 0x71
|
|
||||||
IFT_MPLS = 0xa6
|
|
||||||
IFT_MPLSTUNNEL = 0x96
|
|
||||||
IFT_MSDSL = 0x8f
|
|
||||||
IFT_MVL = 0xbf
|
|
||||||
IFT_MYRINET = 0x63
|
|
||||||
IFT_NFAS = 0xaf
|
|
||||||
IFT_NSIP = 0x1b
|
|
||||||
IFT_OPTICALCHANNEL = 0xc3
|
|
||||||
IFT_OPTICALTRANSPORT = 0xc4
|
|
||||||
IFT_OTHER = 0x1
|
|
||||||
IFT_P10 = 0xc
|
|
||||||
IFT_P80 = 0xd
|
|
||||||
IFT_PARA = 0x22
|
|
||||||
IFT_PFLOG = 0xf6
|
|
||||||
IFT_PFSYNC = 0xf7
|
|
||||||
IFT_PLC = 0xae
|
|
||||||
IFT_POS = 0xab
|
|
||||||
IFT_PPPMULTILINKBUNDLE = 0x6c
|
|
||||||
IFT_PROPBWAP2MP = 0xb8
|
|
||||||
IFT_PROPCNLS = 0x59
|
|
||||||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
|
|
||||||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
|
|
||||||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
|
|
||||||
IFT_PROPMUX = 0x36
|
|
||||||
IFT_PROPWIRELESSP2P = 0x9d
|
|
||||||
IFT_PTPSERIAL = 0x16
|
|
||||||
IFT_PVC = 0xf1
|
|
||||||
IFT_QLLC = 0x44
|
|
||||||
IFT_RADIOMAC = 0xbc
|
|
||||||
IFT_RADSL = 0x5f
|
|
||||||
IFT_REACHDSL = 0xc0
|
|
||||||
IFT_RFC1483 = 0x9f
|
|
||||||
IFT_RS232 = 0x21
|
|
||||||
IFT_RSRB = 0x4f
|
|
||||||
IFT_SDLC = 0x11
|
|
||||||
IFT_SDSL = 0x60
|
|
||||||
IFT_SHDSL = 0xa9
|
|
||||||
IFT_SIP = 0x1f
|
|
||||||
IFT_SLIP = 0x1c
|
|
||||||
IFT_SMDSDXI = 0x2b
|
|
||||||
IFT_SMDSICIP = 0x34
|
|
||||||
IFT_SONET = 0x27
|
|
||||||
IFT_SONETOVERHEADCHANNEL = 0xb9
|
|
||||||
IFT_SONETPATH = 0x32
|
|
||||||
IFT_SONETVT = 0x33
|
|
||||||
IFT_SRP = 0x97
|
|
||||||
IFT_SS7SIGLINK = 0x9c
|
|
||||||
IFT_STACKTOSTACK = 0x6f
|
|
||||||
IFT_STARLAN = 0xb
|
|
||||||
IFT_STF = 0xd7
|
|
||||||
IFT_T1 = 0x12
|
|
||||||
IFT_TDLC = 0x74
|
|
||||||
IFT_TERMPAD = 0x5b
|
|
||||||
IFT_TR008 = 0xb0
|
|
||||||
IFT_TRANSPHDLC = 0x7b
|
|
||||||
IFT_TUNNEL = 0x83
|
|
||||||
IFT_ULTRA = 0x1d
|
|
||||||
IFT_USB = 0xa0
|
|
||||||
IFT_V11 = 0x40
|
|
||||||
IFT_V35 = 0x2d
|
|
||||||
IFT_V36 = 0x41
|
|
||||||
IFT_V37 = 0x78
|
|
||||||
IFT_VDSL = 0x61
|
|
||||||
IFT_VIRTUALIPADDRESS = 0x70
|
|
||||||
IFT_VOICEEM = 0x64
|
|
||||||
IFT_VOICEENCAP = 0x67
|
|
||||||
IFT_VOICEFXO = 0x65
|
|
||||||
IFT_VOICEFXS = 0x66
|
|
||||||
IFT_VOICEOVERATM = 0x98
|
|
||||||
IFT_VOICEOVERFRAMERELAY = 0x99
|
|
||||||
IFT_VOICEOVERIP = 0x68
|
|
||||||
IFT_X213 = 0x5d
|
|
||||||
IFT_X25 = 0x5
|
|
||||||
IFT_X25DDN = 0x4
|
|
||||||
IFT_X25HUNTGROUP = 0x7a
|
|
||||||
IFT_X25MLP = 0x79
|
|
||||||
IFT_X25PLE = 0x28
|
|
||||||
IFT_XETHER = 0x1a
|
|
||||||
IPPROTO_MAXID = 0x34
|
|
||||||
IPV6_FAITH = 0x1d
|
|
||||||
IPV6_MIN_MEMBERSHIPS = 0x1f
|
|
||||||
IP_FAITH = 0x16
|
|
||||||
IP_MAX_SOURCE_FILTER = 0x400
|
|
||||||
IP_MIN_MEMBERSHIPS = 0x1f
|
|
||||||
MAP_NORESERVE = 0x40
|
|
||||||
MAP_RENAME = 0x20
|
|
||||||
NET_RT_MAXID = 0x6
|
|
||||||
RTF_PRCLONING = 0x10000
|
|
||||||
RTM_OLDADD = 0x9
|
|
||||||
RTM_OLDDEL = 0xa
|
|
||||||
RT_CACHING_CONTEXT = 0x1
|
|
||||||
RT_NORTREF = 0x2
|
|
||||||
SIOCADDRT = 0x8040720a
|
|
||||||
SIOCALIFADDR = 0x8118691b
|
|
||||||
SIOCDELRT = 0x8040720b
|
|
||||||
SIOCDLIFADDR = 0x8118691d
|
|
||||||
SIOCGLIFADDR = 0xc118691c
|
|
||||||
SIOCGLIFPHYADDR = 0xc118694b
|
|
||||||
SIOCSLIFPHYADDR = 0x8118694a
|
|
||||||
)
|
|
@ -1,226 +0,0 @@
|
|||||||
// Copyright 2017 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 unix
|
|
||||||
|
|
||||||
const (
|
|
||||||
IFT_1822 = 0x2
|
|
||||||
IFT_A12MPPSWITCH = 0x82
|
|
||||||
IFT_AAL2 = 0xbb
|
|
||||||
IFT_AAL5 = 0x31
|
|
||||||
IFT_ADSL = 0x5e
|
|
||||||
IFT_AFLANE8023 = 0x3b
|
|
||||||
IFT_AFLANE8025 = 0x3c
|
|
||||||
IFT_ARAP = 0x58
|
|
||||||
IFT_ARCNET = 0x23
|
|
||||||
IFT_ARCNETPLUS = 0x24
|
|
||||||
IFT_ASYNC = 0x54
|
|
||||||
IFT_ATM = 0x25
|
|
||||||
IFT_ATMDXI = 0x69
|
|
||||||
IFT_ATMFUNI = 0x6a
|
|
||||||
IFT_ATMIMA = 0x6b
|
|
||||||
IFT_ATMLOGICAL = 0x50
|
|
||||||
IFT_ATMRADIO = 0xbd
|
|
||||||
IFT_ATMSUBINTERFACE = 0x86
|
|
||||||
IFT_ATMVCIENDPT = 0xc2
|
|
||||||
IFT_ATMVIRTUAL = 0x95
|
|
||||||
IFT_BGPPOLICYACCOUNTING = 0xa2
|
|
||||||
IFT_BSC = 0x53
|
|
||||||
IFT_CCTEMUL = 0x3d
|
|
||||||
IFT_CEPT = 0x13
|
|
||||||
IFT_CES = 0x85
|
|
||||||
IFT_CHANNEL = 0x46
|
|
||||||
IFT_CNR = 0x55
|
|
||||||
IFT_COFFEE = 0x84
|
|
||||||
IFT_COMPOSITELINK = 0x9b
|
|
||||||
IFT_DCN = 0x8d
|
|
||||||
IFT_DIGITALPOWERLINE = 0x8a
|
|
||||||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
|
|
||||||
IFT_DLSW = 0x4a
|
|
||||||
IFT_DOCSCABLEDOWNSTREAM = 0x80
|
|
||||||
IFT_DOCSCABLEMACLAYER = 0x7f
|
|
||||||
IFT_DOCSCABLEUPSTREAM = 0x81
|
|
||||||
IFT_DS0 = 0x51
|
|
||||||
IFT_DS0BUNDLE = 0x52
|
|
||||||
IFT_DS1FDL = 0xaa
|
|
||||||
IFT_DS3 = 0x1e
|
|
||||||
IFT_DTM = 0x8c
|
|
||||||
IFT_DVBASILN = 0xac
|
|
||||||
IFT_DVBASIOUT = 0xad
|
|
||||||
IFT_DVBRCCDOWNSTREAM = 0x93
|
|
||||||
IFT_DVBRCCMACLAYER = 0x92
|
|
||||||
IFT_DVBRCCUPSTREAM = 0x94
|
|
||||||
IFT_ENC = 0xf4
|
|
||||||
IFT_EON = 0x19
|
|
||||||
IFT_EPLRS = 0x57
|
|
||||||
IFT_ESCON = 0x49
|
|
||||||
IFT_ETHER = 0x6
|
|
||||||
IFT_FAST = 0x7d
|
|
||||||
IFT_FASTETHER = 0x3e
|
|
||||||
IFT_FASTETHERFX = 0x45
|
|
||||||
IFT_FDDI = 0xf
|
|
||||||
IFT_FIBRECHANNEL = 0x38
|
|
||||||
IFT_FRAMERELAYINTERCONNECT = 0x3a
|
|
||||||
IFT_FRAMERELAYMPI = 0x5c
|
|
||||||
IFT_FRDLCIENDPT = 0xc1
|
|
||||||
IFT_FRELAY = 0x20
|
|
||||||
IFT_FRELAYDCE = 0x2c
|
|
||||||
IFT_FRF16MFRBUNDLE = 0xa3
|
|
||||||
IFT_FRFORWARD = 0x9e
|
|
||||||
IFT_G703AT2MB = 0x43
|
|
||||||
IFT_G703AT64K = 0x42
|
|
||||||
IFT_GIF = 0xf0
|
|
||||||
IFT_GIGABITETHERNET = 0x75
|
|
||||||
IFT_GR303IDT = 0xb2
|
|
||||||
IFT_GR303RDT = 0xb1
|
|
||||||
IFT_H323GATEKEEPER = 0xa4
|
|
||||||
IFT_H323PROXY = 0xa5
|
|
||||||
IFT_HDH1822 = 0x3
|
|
||||||
IFT_HDLC = 0x76
|
|
||||||
IFT_HDSL2 = 0xa8
|
|
||||||
IFT_HIPERLAN2 = 0xb7
|
|
||||||
IFT_HIPPI = 0x2f
|
|
||||||
IFT_HIPPIINTERFACE = 0x39
|
|
||||||
IFT_HOSTPAD = 0x5a
|
|
||||||
IFT_HSSI = 0x2e
|
|
||||||
IFT_HY = 0xe
|
|
||||||
IFT_IBM370PARCHAN = 0x48
|
|
||||||
IFT_IDSL = 0x9a
|
|
||||||
IFT_IEEE80211 = 0x47
|
|
||||||
IFT_IEEE80212 = 0x37
|
|
||||||
IFT_IEEE8023ADLAG = 0xa1
|
|
||||||
IFT_IFGSN = 0x91
|
|
||||||
IFT_IMT = 0xbe
|
|
||||||
IFT_INTERLEAVE = 0x7c
|
|
||||||
IFT_IP = 0x7e
|
|
||||||
IFT_IPFORWARD = 0x8e
|
|
||||||
IFT_IPOVERATM = 0x72
|
|
||||||
IFT_IPOVERCDLC = 0x6d
|
|
||||||
IFT_IPOVERCLAW = 0x6e
|
|
||||||
IFT_IPSWITCH = 0x4e
|
|
||||||
IFT_ISDN = 0x3f
|
|
||||||
IFT_ISDNBASIC = 0x14
|
|
||||||
IFT_ISDNPRIMARY = 0x15
|
|
||||||
IFT_ISDNS = 0x4b
|
|
||||||
IFT_ISDNU = 0x4c
|
|
||||||
IFT_ISO88022LLC = 0x29
|
|
||||||
IFT_ISO88023 = 0x7
|
|
||||||
IFT_ISO88024 = 0x8
|
|
||||||
IFT_ISO88025 = 0x9
|
|
||||||
IFT_ISO88025CRFPINT = 0x62
|
|
||||||
IFT_ISO88025DTR = 0x56
|
|
||||||
IFT_ISO88025FIBER = 0x73
|
|
||||||
IFT_ISO88026 = 0xa
|
|
||||||
IFT_ISUP = 0xb3
|
|
||||||
IFT_L3IPXVLAN = 0x89
|
|
||||||
IFT_LAPB = 0x10
|
|
||||||
IFT_LAPD = 0x4d
|
|
||||||
IFT_LAPF = 0x77
|
|
||||||
IFT_LOCALTALK = 0x2a
|
|
||||||
IFT_LOOP = 0x18
|
|
||||||
IFT_MEDIAMAILOVERIP = 0x8b
|
|
||||||
IFT_MFSIGLINK = 0xa7
|
|
||||||
IFT_MIOX25 = 0x26
|
|
||||||
IFT_MODEM = 0x30
|
|
||||||
IFT_MPC = 0x71
|
|
||||||
IFT_MPLS = 0xa6
|
|
||||||
IFT_MPLSTUNNEL = 0x96
|
|
||||||
IFT_MSDSL = 0x8f
|
|
||||||
IFT_MVL = 0xbf
|
|
||||||
IFT_MYRINET = 0x63
|
|
||||||
IFT_NFAS = 0xaf
|
|
||||||
IFT_NSIP = 0x1b
|
|
||||||
IFT_OPTICALCHANNEL = 0xc3
|
|
||||||
IFT_OPTICALTRANSPORT = 0xc4
|
|
||||||
IFT_OTHER = 0x1
|
|
||||||
IFT_P10 = 0xc
|
|
||||||
IFT_P80 = 0xd
|
|
||||||
IFT_PARA = 0x22
|
|
||||||
IFT_PFLOG = 0xf6
|
|
||||||
IFT_PFSYNC = 0xf7
|
|
||||||
IFT_PLC = 0xae
|
|
||||||
IFT_POS = 0xab
|
|
||||||
IFT_PPPMULTILINKBUNDLE = 0x6c
|
|
||||||
IFT_PROPBWAP2MP = 0xb8
|
|
||||||
IFT_PROPCNLS = 0x59
|
|
||||||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
|
|
||||||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
|
|
||||||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
|
|
||||||
IFT_PROPMUX = 0x36
|
|
||||||
IFT_PROPWIRELESSP2P = 0x9d
|
|
||||||
IFT_PTPSERIAL = 0x16
|
|
||||||
IFT_PVC = 0xf1
|
|
||||||
IFT_QLLC = 0x44
|
|
||||||
IFT_RADIOMAC = 0xbc
|
|
||||||
IFT_RADSL = 0x5f
|
|
||||||
IFT_REACHDSL = 0xc0
|
|
||||||
IFT_RFC1483 = 0x9f
|
|
||||||
IFT_RS232 = 0x21
|
|
||||||
IFT_RSRB = 0x4f
|
|
||||||
IFT_SDLC = 0x11
|
|
||||||
IFT_SDSL = 0x60
|
|
||||||
IFT_SHDSL = 0xa9
|
|
||||||
IFT_SIP = 0x1f
|
|
||||||
IFT_SLIP = 0x1c
|
|
||||||
IFT_SMDSDXI = 0x2b
|
|
||||||
IFT_SMDSICIP = 0x34
|
|
||||||
IFT_SONET = 0x27
|
|
||||||
IFT_SONETOVERHEADCHANNEL = 0xb9
|
|
||||||
IFT_SONETPATH = 0x32
|
|
||||||
IFT_SONETVT = 0x33
|
|
||||||
IFT_SRP = 0x97
|
|
||||||
IFT_SS7SIGLINK = 0x9c
|
|
||||||
IFT_STACKTOSTACK = 0x6f
|
|
||||||
IFT_STARLAN = 0xb
|
|
||||||
IFT_STF = 0xd7
|
|
||||||
IFT_T1 = 0x12
|
|
||||||
IFT_TDLC = 0x74
|
|
||||||
IFT_TERMPAD = 0x5b
|
|
||||||
IFT_TR008 = 0xb0
|
|
||||||
IFT_TRANSPHDLC = 0x7b
|
|
||||||
IFT_TUNNEL = 0x83
|
|
||||||
IFT_ULTRA = 0x1d
|
|
||||||
IFT_USB = 0xa0
|
|
||||||
IFT_V11 = 0x40
|
|
||||||
IFT_V35 = 0x2d
|
|
||||||
IFT_V36 = 0x41
|
|
||||||
IFT_V37 = 0x78
|
|
||||||
IFT_VDSL = 0x61
|
|
||||||
IFT_VIRTUALIPADDRESS = 0x70
|
|
||||||
IFT_VOICEEM = 0x64
|
|
||||||
IFT_VOICEENCAP = 0x67
|
|
||||||
IFT_VOICEFXO = 0x65
|
|
||||||
IFT_VOICEFXS = 0x66
|
|
||||||
IFT_VOICEOVERATM = 0x98
|
|
||||||
IFT_VOICEOVERFRAMERELAY = 0x99
|
|
||||||
IFT_VOICEOVERIP = 0x68
|
|
||||||
IFT_X213 = 0x5d
|
|
||||||
IFT_X25 = 0x5
|
|
||||||
IFT_X25DDN = 0x4
|
|
||||||
IFT_X25HUNTGROUP = 0x7a
|
|
||||||
IFT_X25MLP = 0x79
|
|
||||||
IFT_X25PLE = 0x28
|
|
||||||
IFT_XETHER = 0x1a
|
|
||||||
|
|
||||||
// missing constants on FreeBSD-11.1-RELEASE, copied from old values in ztypes_freebsd_arm.go
|
|
||||||
IFF_SMART = 0x20
|
|
||||||
IFT_FAITH = 0xf2
|
|
||||||
IFT_IPXIP = 0xf9
|
|
||||||
IPPROTO_MAXID = 0x34
|
|
||||||
IPV6_FAITH = 0x1d
|
|
||||||
IP_FAITH = 0x16
|
|
||||||
MAP_NORESERVE = 0x40
|
|
||||||
MAP_RENAME = 0x20
|
|
||||||
NET_RT_MAXID = 0x6
|
|
||||||
RTF_PRCLONING = 0x10000
|
|
||||||
RTM_OLDADD = 0x9
|
|
||||||
RTM_OLDDEL = 0xa
|
|
||||||
SIOCADDRT = 0x8030720a
|
|
||||||
SIOCALIFADDR = 0x8118691b
|
|
||||||
SIOCDELRT = 0x8030720b
|
|
||||||
SIOCDLIFADDR = 0x8118691d
|
|
||||||
SIOCGLIFADDR = 0xc118691c
|
|
||||||
SIOCGLIFPHYADDR = 0xc118694b
|
|
||||||
SIOCSLIFPHYADDR = 0x8118694a
|
|
||||||
)
|
|
@ -1,17 +0,0 @@
|
|||||||
// Copyright 2020 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.
|
|
||||||
|
|
||||||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
|
|
||||||
// them here for backwards compatibility.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
const (
|
|
||||||
DLT_HHDLC = 0x79
|
|
||||||
IPV6_MIN_MEMBERSHIPS = 0x1f
|
|
||||||
IP_MAX_SOURCE_FILTER = 0x400
|
|
||||||
IP_MIN_MEMBERSHIPS = 0x1f
|
|
||||||
RT_CACHING_CONTEXT = 0x1
|
|
||||||
RT_NORTREF = 0x2
|
|
||||||
)
|
|
@ -1,36 +0,0 @@
|
|||||||
// Copyright 2014 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.
|
|
||||||
|
|
||||||
// +build dragonfly freebsd linux netbsd openbsd
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
// fcntl64Syscall is usually SYS_FCNTL, but is overridden on 32-bit Linux
|
|
||||||
// systems by fcntl_linux_32bit.go to be SYS_FCNTL64.
|
|
||||||
var fcntl64Syscall uintptr = SYS_FCNTL
|
|
||||||
|
|
||||||
func fcntl(fd int, cmd, arg int) (int, error) {
|
|
||||||
valptr, _, errno := Syscall(fcntl64Syscall, uintptr(fd), uintptr(cmd), uintptr(arg))
|
|
||||||
var err error
|
|
||||||
if errno != 0 {
|
|
||||||
err = errno
|
|
||||||
}
|
|
||||||
return int(valptr), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
|
|
||||||
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
|
||||||
return fcntl(int(fd), cmd, arg)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
|
|
||||||
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
|
|
||||||
_, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk)))
|
|
||||||
if errno == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return errno
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
// Copyright 2019 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 unix
|
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
|
|
||||||
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
|
||||||
return fcntl(int(fd), cmd, arg)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
|
|
||||||
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
|
|
||||||
_, err := fcntl(int(fd), cmd, int(uintptr(unsafe.Pointer(lk))))
|
|
||||||
return err
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
// +build linux,386 linux,arm linux,mips linux,mipsle
|
|
||||||
|
|
||||||
// Copyright 2014 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 unix
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// On 32-bit Linux systems, the fcntl syscall that matches Go's
|
|
||||||
// Flock_t type is SYS_FCNTL64, not SYS_FCNTL.
|
|
||||||
fcntl64Syscall = SYS_FCNTL64
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2019 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.
|
|
||||||
|
|
||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
// Set adds fd to the set fds.
|
|
||||||
func (fds *FdSet) Set(fd int) {
|
|
||||||
fds.Bits[fd/NFDBITS] |= (1 << (uintptr(fd) % NFDBITS))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear removes fd from the set fds.
|
|
||||||
func (fds *FdSet) Clear(fd int) {
|
|
||||||
fds.Bits[fd/NFDBITS] &^= (1 << (uintptr(fd) % NFDBITS))
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsSet returns whether fd is in the set fds.
|
|
||||||
func (fds *FdSet) IsSet(fd int) bool {
|
|
||||||
return fds.Bits[fd/NFDBITS]&(1<<(uintptr(fd)%NFDBITS)) != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zero clears the set fds.
|
|
||||||
func (fds *FdSet) Zero() {
|
|
||||||
for i := range fds.Bits {
|
|
||||||
fds.Bits[i] = 0
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
// Copyright 2015 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.
|
|
||||||
|
|
||||||
// +build gccgo
|
|
||||||
// +build !aix
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
// We can't use the gc-syntax .s files for gccgo. On the plus side
|
|
||||||
// much of the functionality can be written directly in Go.
|
|
||||||
|
|
||||||
//extern gccgoRealSyscallNoError
|
|
||||||
func realSyscallNoError(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r uintptr)
|
|
||||||
|
|
||||||
//extern gccgoRealSyscall
|
|
||||||
func realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r, errno uintptr)
|
|
||||||
|
|
||||||
func SyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) {
|
|
||||||
syscall.Entersyscall()
|
|
||||||
r := realSyscallNoError(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
|
|
||||||
syscall.Exitsyscall()
|
|
||||||
return r, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
|
||||||
syscall.Entersyscall()
|
|
||||||
r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
|
|
||||||
syscall.Exitsyscall()
|
|
||||||
return r, 0, syscall.Errno(errno)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
|
||||||
syscall.Entersyscall()
|
|
||||||
r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)
|
|
||||||
syscall.Exitsyscall()
|
|
||||||
return r, 0, syscall.Errno(errno)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
|
||||||
syscall.Entersyscall()
|
|
||||||
r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
|
||||||
syscall.Exitsyscall()
|
|
||||||
return r, 0, syscall.Errno(errno)
|
|
||||||
}
|
|
||||||
|
|
||||||
func RawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) {
|
|
||||||
r := realSyscallNoError(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
|
|
||||||
return r, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
|
||||||
r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
|
|
||||||
return r, 0, syscall.Errno(errno)
|
|
||||||
}
|
|
||||||
|
|
||||||
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
|
||||||
r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)
|
|
||||||
return r, 0, syscall.Errno(errno)
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
// Copyright 2015 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.
|
|
||||||
|
|
||||||
// +build gccgo
|
|
||||||
// +build !aix
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#define _STRINGIFY2_(x) #x
|
|
||||||
#define _STRINGIFY_(x) _STRINGIFY2_(x)
|
|
||||||
#define GOSYM_PREFIX _STRINGIFY_(__USER_LABEL_PREFIX__)
|
|
||||||
|
|
||||||
// Call syscall from C code because the gccgo support for calling from
|
|
||||||
// Go to C does not support varargs functions.
|
|
||||||
|
|
||||||
struct ret {
|
|
||||||
uintptr_t r;
|
|
||||||
uintptr_t err;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ret
|
|
||||||
gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9)
|
|
||||||
{
|
|
||||||
struct ret r;
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
r.r = syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
||||||
r.err = errno;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
uintptr_t
|
|
||||||
gccgoRealSyscallNoError(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9)
|
|
||||||
{
|
|
||||||
return syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
// Copyright 2015 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.
|
|
||||||
|
|
||||||
// +build gccgo,linux,amd64
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
//extern gettimeofday
|
|
||||||
func realGettimeofday(*Timeval, *byte) int32
|
|
||||||
|
|
||||||
func gettimeofday(tv *Timeval) (err syscall.Errno) {
|
|
||||||
r := realGettimeofday(tv, nil)
|
|
||||||
if r < 0 {
|
|
||||||
return syscall.GetErrno()
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
// Copyright 2018 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.
|
|
||||||
|
|
||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ioctl itself should not be exposed directly, but additional get/set
|
|
||||||
// functions for specific types are permissible.
|
|
||||||
|
|
||||||
// IoctlSetInt performs an ioctl operation which sets an integer value
|
|
||||||
// on fd, using the specified request number.
|
|
||||||
func IoctlSetInt(fd int, req uint, value int) error {
|
|
||||||
return ioctl(fd, req, uintptr(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
|
|
||||||
//
|
|
||||||
// To change fd's window size, the req argument should be TIOCSWINSZ.
|
|
||||||
func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
|
|
||||||
// TODO: if we get the chance, remove the req parameter and
|
|
||||||
// hardcode TIOCSWINSZ.
|
|
||||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(value)))
|
|
||||||
runtime.KeepAlive(value)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// IoctlSetTermios performs an ioctl on fd with a *Termios.
|
|
||||||
//
|
|
||||||
// The req value will usually be TCSETA or TIOCSETA.
|
|
||||||
func IoctlSetTermios(fd int, req uint, value *Termios) error {
|
|
||||||
// TODO: if we get the chance, remove the req parameter.
|
|
||||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(value)))
|
|
||||||
runtime.KeepAlive(value)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// IoctlGetInt performs an ioctl operation which gets an integer value
|
|
||||||
// from fd, using the specified request number.
|
|
||||||
//
|
|
||||||
// A few ioctl requests use the return value as an output parameter;
|
|
||||||
// for those, IoctlRetInt should be used instead of this function.
|
|
||||||
func IoctlGetInt(fd int, req uint) (int, error) {
|
|
||||||
var value int
|
|
||||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
|
|
||||||
return value, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
|
|
||||||
var value Winsize
|
|
||||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
|
|
||||||
return &value, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
|
|
||||||
var value Termios
|
|
||||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
|
|
||||||
return &value, err
|
|
||||||
}
|
|
@ -1,240 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Copyright 2009 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.
|
|
||||||
|
|
||||||
# This script runs or (given -n) prints suggested commands to generate files for
|
|
||||||
# the Architecture/OS specified by the GOARCH and GOOS environment variables.
|
|
||||||
# See README.md for more information about how the build system works.
|
|
||||||
|
|
||||||
GOOSARCH="${GOOS}_${GOARCH}"
|
|
||||||
|
|
||||||
# defaults
|
|
||||||
mksyscall="go run mksyscall.go"
|
|
||||||
mkerrors="./mkerrors.sh"
|
|
||||||
zerrors="zerrors_$GOOSARCH.go"
|
|
||||||
mksysctl=""
|
|
||||||
zsysctl="zsysctl_$GOOSARCH.go"
|
|
||||||
mksysnum=
|
|
||||||
mktypes=
|
|
||||||
mkasm=
|
|
||||||
run="sh"
|
|
||||||
cmd=""
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
-syscalls)
|
|
||||||
for i in zsyscall*go
|
|
||||||
do
|
|
||||||
# Run the command line that appears in the first line
|
|
||||||
# of the generated file to regenerate it.
|
|
||||||
sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i
|
|
||||||
rm _$i
|
|
||||||
done
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
-n)
|
|
||||||
run="cat"
|
|
||||||
cmd="echo"
|
|
||||||
shift
|
|
||||||
esac
|
|
||||||
|
|
||||||
case "$#" in
|
|
||||||
0)
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo 'usage: mkall.sh [-n]' 1>&2
|
|
||||||
exit 2
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [[ "$GOOS" = "linux" ]]; then
|
|
||||||
# Use the Docker-based build system
|
|
||||||
# Files generated through docker (use $cmd so you can Ctl-C the build or run)
|
|
||||||
$cmd docker build --tag generate:$GOOS $GOOS
|
|
||||||
$cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")" && /bin/pwd):/build generate:$GOOS
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
GOOSARCH_in=syscall_$GOOSARCH.go
|
|
||||||
case "$GOOSARCH" in
|
|
||||||
_* | *_ | _)
|
|
||||||
echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
aix_ppc)
|
|
||||||
mkerrors="$mkerrors -maix32"
|
|
||||||
mksyscall="go run mksyscall_aix_ppc.go -aix"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
|
||||||
;;
|
|
||||||
aix_ppc64)
|
|
||||||
mkerrors="$mkerrors -maix64"
|
|
||||||
mksyscall="go run mksyscall_aix_ppc64.go -aix"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
|
||||||
;;
|
|
||||||
darwin_386)
|
|
||||||
mkerrors="$mkerrors -m32"
|
|
||||||
mksyscall="go run mksyscall.go -l32"
|
|
||||||
mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
|
||||||
mkasm="go run mkasm_darwin.go"
|
|
||||||
;;
|
|
||||||
darwin_amd64)
|
|
||||||
mkerrors="$mkerrors -m64"
|
|
||||||
mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
|
||||||
mkasm="go run mkasm_darwin.go"
|
|
||||||
;;
|
|
||||||
darwin_arm)
|
|
||||||
mkerrors="$mkerrors"
|
|
||||||
mksyscall="go run mksyscall.go -l32"
|
|
||||||
mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
|
||||||
mkasm="go run mkasm_darwin.go"
|
|
||||||
;;
|
|
||||||
darwin_arm64)
|
|
||||||
mkerrors="$mkerrors -m64"
|
|
||||||
mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
|
||||||
mkasm="go run mkasm_darwin.go"
|
|
||||||
;;
|
|
||||||
dragonfly_amd64)
|
|
||||||
mkerrors="$mkerrors -m64"
|
|
||||||
mksyscall="go run mksyscall.go -dragonfly"
|
|
||||||
mksysnum="go run mksysnum.go 'https://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master'"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
|
||||||
;;
|
|
||||||
freebsd_386)
|
|
||||||
mkerrors="$mkerrors -m32"
|
|
||||||
mksyscall="go run mksyscall.go -l32"
|
|
||||||
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
|
||||||
;;
|
|
||||||
freebsd_amd64)
|
|
||||||
mkerrors="$mkerrors -m64"
|
|
||||||
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
|
||||||
;;
|
|
||||||
freebsd_arm)
|
|
||||||
mkerrors="$mkerrors"
|
|
||||||
mksyscall="go run mksyscall.go -l32 -arm"
|
|
||||||
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
|
|
||||||
# Let the type of C char be signed for making the bare syscall
|
|
||||||
# API consistent across platforms.
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
|
||||||
;;
|
|
||||||
freebsd_arm64)
|
|
||||||
mkerrors="$mkerrors -m64"
|
|
||||||
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
|
||||||
;;
|
|
||||||
netbsd_386)
|
|
||||||
mkerrors="$mkerrors -m32"
|
|
||||||
mksyscall="go run mksyscall.go -l32 -netbsd"
|
|
||||||
mksysnum="go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
|
||||||
;;
|
|
||||||
netbsd_amd64)
|
|
||||||
mkerrors="$mkerrors -m64"
|
|
||||||
mksyscall="go run mksyscall.go -netbsd"
|
|
||||||
mksysnum="go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
|
||||||
;;
|
|
||||||
netbsd_arm)
|
|
||||||
mkerrors="$mkerrors"
|
|
||||||
mksyscall="go run mksyscall.go -l32 -netbsd -arm"
|
|
||||||
mksysnum="go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'"
|
|
||||||
# Let the type of C char be signed for making the bare syscall
|
|
||||||
# API consistent across platforms.
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
|
||||||
;;
|
|
||||||
netbsd_arm64)
|
|
||||||
mkerrors="$mkerrors -m64"
|
|
||||||
mksyscall="go run mksyscall.go -netbsd"
|
|
||||||
mksysnum="go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
|
||||||
;;
|
|
||||||
openbsd_386)
|
|
||||||
mkerrors="$mkerrors -m32"
|
|
||||||
mksyscall="go run mksyscall.go -l32 -openbsd"
|
|
||||||
mksysctl="go run mksysctl_openbsd.go"
|
|
||||||
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
|
||||||
;;
|
|
||||||
openbsd_amd64)
|
|
||||||
mkerrors="$mkerrors -m64"
|
|
||||||
mksyscall="go run mksyscall.go -openbsd"
|
|
||||||
mksysctl="go run mksysctl_openbsd.go"
|
|
||||||
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
|
||||||
;;
|
|
||||||
openbsd_arm)
|
|
||||||
mkerrors="$mkerrors"
|
|
||||||
mksyscall="go run mksyscall.go -l32 -openbsd -arm"
|
|
||||||
mksysctl="go run mksysctl_openbsd.go"
|
|
||||||
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
|
|
||||||
# Let the type of C char be signed for making the bare syscall
|
|
||||||
# API consistent across platforms.
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
|
||||||
;;
|
|
||||||
openbsd_arm64)
|
|
||||||
mkerrors="$mkerrors -m64"
|
|
||||||
mksyscall="go run mksyscall.go -openbsd"
|
|
||||||
mksysctl="go run mksysctl_openbsd.go"
|
|
||||||
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
|
|
||||||
# Let the type of C char be signed for making the bare syscall
|
|
||||||
# API consistent across platforms.
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
|
||||||
;;
|
|
||||||
solaris_amd64)
|
|
||||||
mksyscall="go run mksyscall_solaris.go"
|
|
||||||
mkerrors="$mkerrors -m64"
|
|
||||||
mksysnum=
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
|
||||||
;;
|
|
||||||
illumos_amd64)
|
|
||||||
mksyscall="go run mksyscall_solaris.go"
|
|
||||||
mkerrors=
|
|
||||||
mksysnum=
|
|
||||||
mktypes=
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
(
|
|
||||||
if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
|
|
||||||
case "$GOOS" in
|
|
||||||
*)
|
|
||||||
syscall_goos="syscall_$GOOS.go"
|
|
||||||
case "$GOOS" in
|
|
||||||
darwin | dragonfly | freebsd | netbsd | openbsd)
|
|
||||||
syscall_goos="syscall_bsd.go $syscall_goos"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
if [ -n "$mksyscall" ]; then
|
|
||||||
if [ "$GOOSARCH" == "aix_ppc64" ]; then
|
|
||||||
# aix/ppc64 script generates files instead of writing to stdin.
|
|
||||||
echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ;
|
|
||||||
elif [ "$GOOS" == "darwin" ]; then
|
|
||||||
# pre-1.12, direct syscalls
|
|
||||||
echo "$mksyscall -tags $GOOS,$GOARCH,!go1.12 $syscall_goos syscall_darwin_${GOARCH}.1_11.go $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.1_11.go";
|
|
||||||
# 1.12 and later, syscalls via libSystem
|
|
||||||
echo "$mksyscall -tags $GOOS,$GOARCH,go1.12 $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go";
|
|
||||||
# 1.13 and later, syscalls via libSystem (including syscallPtr)
|
|
||||||
echo "$mksyscall -tags $GOOS,$GOARCH,go1.13 syscall_darwin.1_13.go |gofmt >zsyscall_$GOOSARCH.1_13.go";
|
|
||||||
elif [ "$GOOS" == "illumos" ]; then
|
|
||||||
# illumos code generation requires a --illumos switch
|
|
||||||
echo "$mksyscall -illumos -tags illumos,$GOARCH syscall_illumos.go |gofmt > zsyscall_illumos_$GOARCH.go";
|
|
||||||
# illumos implies solaris, so solaris code generation is also required
|
|
||||||
echo "$mksyscall -tags solaris,$GOARCH syscall_solaris.go syscall_solaris_$GOARCH.go |gofmt >zsyscall_solaris_$GOARCH.go";
|
|
||||||
else
|
|
||||||
echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go";
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
esac
|
|
||||||
if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
|
|
||||||
if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
|
|
||||||
if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go"; fi
|
|
||||||
if [ -n "$mkasm" ]; then echo "$mkasm $GOARCH"; fi
|
|
||||||
) | $run
|
|
@ -1,78 +0,0 @@
|
|||||||
// Copyright 2018 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.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// mkasm_darwin.go generates assembly trampolines to call libSystem routines from Go.
|
|
||||||
//This program must be run after mksyscall.go.
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func writeASMFile(in string, fileName string, buildTags string) {
|
|
||||||
trampolines := map[string]bool{}
|
|
||||||
|
|
||||||
var out bytes.Buffer
|
|
||||||
|
|
||||||
fmt.Fprintf(&out, "// go run mkasm_darwin.go %s\n", strings.Join(os.Args[1:], " "))
|
|
||||||
fmt.Fprintf(&out, "// Code generated by the command above; DO NOT EDIT.\n")
|
|
||||||
fmt.Fprintf(&out, "\n")
|
|
||||||
fmt.Fprintf(&out, "// +build %s\n", buildTags)
|
|
||||||
fmt.Fprintf(&out, "\n")
|
|
||||||
fmt.Fprintf(&out, "#include \"textflag.h\"\n")
|
|
||||||
for _, line := range strings.Split(in, "\n") {
|
|
||||||
if !strings.HasPrefix(line, "func ") || !strings.HasSuffix(line, "_trampoline()") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fn := line[5 : len(line)-13]
|
|
||||||
if !trampolines[fn] {
|
|
||||||
trampolines[fn] = true
|
|
||||||
fmt.Fprintf(&out, "TEXT ·%s_trampoline(SB),NOSPLIT,$0-0\n", fn)
|
|
||||||
fmt.Fprintf(&out, "\tJMP\t%s(SB)\n", fn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := ioutil.WriteFile(fileName, out.Bytes(), 0644)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("can't write %s: %s", fileName, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
in1, err := ioutil.ReadFile("syscall_darwin.go")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("can't open syscall_darwin.go: %s", err)
|
|
||||||
}
|
|
||||||
arch := os.Args[1]
|
|
||||||
in2, err := ioutil.ReadFile(fmt.Sprintf("syscall_darwin_%s.go", arch))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("can't open syscall_darwin_%s.go: %s", arch, err)
|
|
||||||
}
|
|
||||||
in3, err := ioutil.ReadFile(fmt.Sprintf("zsyscall_darwin_%s.go", arch))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("can't open zsyscall_darwin_%s.go: %s", arch, err)
|
|
||||||
}
|
|
||||||
in := string(in1) + string(in2) + string(in3)
|
|
||||||
|
|
||||||
writeASMFile(in, fmt.Sprintf("zsyscall_darwin_%s.s", arch), "go1.12")
|
|
||||||
|
|
||||||
in1, err = ioutil.ReadFile("syscall_darwin.1_13.go")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("can't open syscall_darwin.1_13.go: %s", err)
|
|
||||||
}
|
|
||||||
in2, err = ioutil.ReadFile(fmt.Sprintf("zsyscall_darwin_%s.1_13.go", arch))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("can't open zsyscall_darwin_%s.1_13.go: %s", arch, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
in = string(in1) + string(in2)
|
|
||||||
|
|
||||||
writeASMFile(in, fmt.Sprintf("zsyscall_darwin_%s.1_13.s", arch), "go1.13")
|
|
||||||
}
|
|
@ -1,703 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Copyright 2009 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.
|
|
||||||
|
|
||||||
# Generate Go code listing errors and other #defined constant
|
|
||||||
# values (ENAMETOOLONG etc.), by asking the preprocessor
|
|
||||||
# about the definitions.
|
|
||||||
|
|
||||||
unset LANG
|
|
||||||
export LC_ALL=C
|
|
||||||
export LC_CTYPE=C
|
|
||||||
|
|
||||||
if test -z "$GOARCH" -o -z "$GOOS"; then
|
|
||||||
echo 1>&2 "GOARCH or GOOS not defined in environment"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check that we are using the new build system if we should
|
|
||||||
if [[ "$GOOS" = "linux" ]] && [[ "$GOLANG_SYS_BUILD" != "docker" ]]; then
|
|
||||||
echo 1>&2 "In the Docker based build system, mkerrors should not be called directly."
|
|
||||||
echo 1>&2 "See README.md"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$GOOS" = "aix" ]]; then
|
|
||||||
CC=${CC:-gcc}
|
|
||||||
else
|
|
||||||
CC=${CC:-cc}
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$GOOS" = "solaris" ]]; then
|
|
||||||
# Assumes GNU versions of utilities in PATH.
|
|
||||||
export PATH=/usr/gnu/bin:$PATH
|
|
||||||
fi
|
|
||||||
|
|
||||||
uname=$(uname)
|
|
||||||
|
|
||||||
includes_AIX='
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <net/netopt.h>
|
|
||||||
#include <netinet/ip_mroute.h>
|
|
||||||
#include <sys/protosw.h>
|
|
||||||
#include <sys/stropts.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/poll.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <sys/termio.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#define AF_LOCAL AF_UNIX
|
|
||||||
'
|
|
||||||
|
|
||||||
includes_Darwin='
|
|
||||||
#define _DARWIN_C_SOURCE
|
|
||||||
#define KERNEL
|
|
||||||
#define _DARWIN_USE_64_BIT_INODE
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <sys/attr.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/event.h>
|
|
||||||
#include <sys/ptrace.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/sockio.h>
|
|
||||||
#include <sys/sysctl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/mount.h>
|
|
||||||
#include <sys/utsname.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/xattr.h>
|
|
||||||
#include <net/bpf.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <net/if_types.h>
|
|
||||||
#include <net/route.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netinet/ip.h>
|
|
||||||
#include <termios.h>
|
|
||||||
'
|
|
||||||
|
|
||||||
includes_DragonFly='
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/event.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/sockio.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/sysctl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/mount.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <net/bpf.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <net/if_types.h>
|
|
||||||
#include <net/route.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <netinet/ip.h>
|
|
||||||
#include <net/ip_mroute/ip_mroute.h>
|
|
||||||
'
|
|
||||||
|
|
||||||
includes_FreeBSD='
|
|
||||||
#include <sys/capsicum.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/disk.h>
|
|
||||||
#include <sys/event.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/sockio.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/sysctl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/mount.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <net/bpf.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <net/if_types.h>
|
|
||||||
#include <net/route.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <netinet/ip.h>
|
|
||||||
#include <netinet/ip_mroute.h>
|
|
||||||
#include <sys/extattr.h>
|
|
||||||
|
|
||||||
#if __FreeBSD__ >= 10
|
|
||||||
#define IFT_CARP 0xf8 // IFT_CARP is deprecated in FreeBSD 10
|
|
||||||
#undef SIOCAIFADDR
|
|
||||||
#define SIOCAIFADDR _IOW(105, 26, struct oifaliasreq) // ifaliasreq contains if_data
|
|
||||||
#undef SIOCSIFPHYADDR
|
|
||||||
#define SIOCSIFPHYADDR _IOW(105, 70, struct oifaliasreq) // ifaliasreq contains if_data
|
|
||||||
#endif
|
|
||||||
'
|
|
||||||
|
|
||||||
includes_Linux='
|
|
||||||
#define _LARGEFILE_SOURCE
|
|
||||||
#define _LARGEFILE64_SOURCE
|
|
||||||
#ifndef __LP64__
|
|
||||||
#define _FILE_OFFSET_BITS 64
|
|
||||||
#endif
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
|
|
||||||
// <sys/ioctl.h> is broken on powerpc64, as it fails to include definitions of
|
|
||||||
// these structures. We just include them copied from <bits/termios.h>.
|
|
||||||
#if defined(__powerpc__)
|
|
||||||
struct sgttyb {
|
|
||||||
char sg_ispeed;
|
|
||||||
char sg_ospeed;
|
|
||||||
char sg_erase;
|
|
||||||
char sg_kill;
|
|
||||||
short sg_flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tchars {
|
|
||||||
char t_intrc;
|
|
||||||
char t_quitc;
|
|
||||||
char t_startc;
|
|
||||||
char t_stopc;
|
|
||||||
char t_eofc;
|
|
||||||
char t_brkc;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ltchars {
|
|
||||||
char t_suspc;
|
|
||||||
char t_dsuspc;
|
|
||||||
char t_rprntc;
|
|
||||||
char t_flushc;
|
|
||||||
char t_werasc;
|
|
||||||
char t_lnextc;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <bits/sockaddr.h>
|
|
||||||
#include <sys/epoll.h>
|
|
||||||
#include <sys/eventfd.h>
|
|
||||||
#include <sys/inotify.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/mount.h>
|
|
||||||
#include <sys/prctl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <sys/signalfd.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/timerfd.h>
|
|
||||||
#include <sys/uio.h>
|
|
||||||
#include <sys/xattr.h>
|
|
||||||
#include <linux/bpf.h>
|
|
||||||
#include <linux/can.h>
|
|
||||||
#include <linux/capability.h>
|
|
||||||
#include <linux/cryptouser.h>
|
|
||||||
#include <linux/devlink.h>
|
|
||||||
#include <linux/errqueue.h>
|
|
||||||
#include <linux/falloc.h>
|
|
||||||
#include <linux/fanotify.h>
|
|
||||||
#include <linux/filter.h>
|
|
||||||
#include <linux/fs.h>
|
|
||||||
#include <linux/fscrypt.h>
|
|
||||||
#include <linux/fsverity.h>
|
|
||||||
#include <linux/genetlink.h>
|
|
||||||
#include <linux/hdreg.h>
|
|
||||||
#include <linux/icmpv6.h>
|
|
||||||
#include <linux/if.h>
|
|
||||||
#include <linux/if_addr.h>
|
|
||||||
#include <linux/if_alg.h>
|
|
||||||
#include <linux/if_arp.h>
|
|
||||||
#include <linux/if_ether.h>
|
|
||||||
#include <linux/if_ppp.h>
|
|
||||||
#include <linux/if_tun.h>
|
|
||||||
#include <linux/if_packet.h>
|
|
||||||
#include <linux/if_xdp.h>
|
|
||||||
#include <linux/kexec.h>
|
|
||||||
#include <linux/keyctl.h>
|
|
||||||
#include <linux/loop.h>
|
|
||||||
#include <linux/magic.h>
|
|
||||||
#include <linux/memfd.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/netfilter/nfnetlink.h>
|
|
||||||
#include <linux/netlink.h>
|
|
||||||
#include <linux/net_namespace.h>
|
|
||||||
#include <linux/nsfs.h>
|
|
||||||
#include <linux/perf_event.h>
|
|
||||||
#include <linux/ptrace.h>
|
|
||||||
#include <linux/random.h>
|
|
||||||
#include <linux/reboot.h>
|
|
||||||
#include <linux/rtc.h>
|
|
||||||
#include <linux/rtnetlink.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/seccomp.h>
|
|
||||||
#include <linux/serial.h>
|
|
||||||
#include <linux/sockios.h>
|
|
||||||
#include <linux/taskstats.h>
|
|
||||||
#include <linux/tipc.h>
|
|
||||||
#include <linux/vm_sockets.h>
|
|
||||||
#include <linux/wait.h>
|
|
||||||
#include <linux/watchdog.h>
|
|
||||||
|
|
||||||
#include <mtd/ubi-user.h>
|
|
||||||
#include <net/route.h>
|
|
||||||
|
|
||||||
#if defined(__sparc__)
|
|
||||||
// On sparc{,64}, the kernel defines struct termios2 itself which clashes with the
|
|
||||||
// definition in glibc. As only the error constants are needed here, include the
|
|
||||||
// generic termibits.h (which is included by termbits.h on sparc).
|
|
||||||
#include <asm-generic/termbits.h>
|
|
||||||
#else
|
|
||||||
#include <asm/termbits.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MSG_FASTOPEN
|
|
||||||
#define MSG_FASTOPEN 0x20000000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PTRACE_GETREGS
|
|
||||||
#define PTRACE_GETREGS 0xc
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PTRACE_SETREGS
|
|
||||||
#define PTRACE_SETREGS 0xd
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SOL_NETLINK
|
|
||||||
#define SOL_NETLINK 270
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SOL_BLUETOOTH
|
|
||||||
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
|
|
||||||
// but it is already in bluetooth_linux.go
|
|
||||||
#undef SOL_BLUETOOTH
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Certain constants are missing from the fs/crypto UAPI
|
|
||||||
#define FS_KEY_DESC_PREFIX "fscrypt:"
|
|
||||||
#define FS_KEY_DESC_PREFIX_SIZE 8
|
|
||||||
#define FS_MAX_KEY_SIZE 64
|
|
||||||
|
|
||||||
// The code generator produces -0x1 for (~0), but an unsigned value is necessary
|
|
||||||
// for the tipc_subscr timeout __u32 field.
|
|
||||||
#undef TIPC_WAIT_FOREVER
|
|
||||||
#define TIPC_WAIT_FOREVER 0xffffffff
|
|
||||||
|
|
||||||
// Copied from linux/l2tp.h
|
|
||||||
// Including linux/l2tp.h here causes conflicts between linux/in.h
|
|
||||||
// and netinet/in.h included via net/route.h above.
|
|
||||||
#define IPPROTO_L2TP 115
|
|
||||||
'
|
|
||||||
|
|
||||||
includes_NetBSD='
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/event.h>
|
|
||||||
#include <sys/extattr.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/mount.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/sockio.h>
|
|
||||||
#include <sys/sysctl.h>
|
|
||||||
#include <sys/termios.h>
|
|
||||||
#include <sys/ttycom.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <net/bpf.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <net/if_types.h>
|
|
||||||
#include <net/route.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netinet/in_systm.h>
|
|
||||||
#include <netinet/ip.h>
|
|
||||||
#include <netinet/ip_mroute.h>
|
|
||||||
#include <netinet/if_ether.h>
|
|
||||||
|
|
||||||
// Needed since <sys/param.h> refers to it...
|
|
||||||
#define schedppq 1
|
|
||||||
'
|
|
||||||
|
|
||||||
includes_OpenBSD='
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/event.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/mount.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/sockio.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/sysctl.h>
|
|
||||||
#include <sys/termios.h>
|
|
||||||
#include <sys/ttycom.h>
|
|
||||||
#include <sys/unistd.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <net/bpf.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <net/if_types.h>
|
|
||||||
#include <net/if_var.h>
|
|
||||||
#include <net/route.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netinet/in_systm.h>
|
|
||||||
#include <netinet/ip.h>
|
|
||||||
#include <netinet/ip_mroute.h>
|
|
||||||
#include <netinet/if_ether.h>
|
|
||||||
#include <net/if_bridge.h>
|
|
||||||
|
|
||||||
// We keep some constants not supported in OpenBSD 5.5 and beyond for
|
|
||||||
// the promise of compatibility.
|
|
||||||
#define EMUL_ENABLED 0x1
|
|
||||||
#define EMUL_NATIVE 0x2
|
|
||||||
#define IPV6_FAITH 0x1d
|
|
||||||
#define IPV6_OPTIONS 0x1
|
|
||||||
#define IPV6_RTHDR_STRICT 0x1
|
|
||||||
#define IPV6_SOCKOPT_RESERVED1 0x3
|
|
||||||
#define SIOCGIFGENERIC 0xc020693a
|
|
||||||
#define SIOCSIFGENERIC 0x80206939
|
|
||||||
#define WALTSIG 0x4
|
|
||||||
'
|
|
||||||
|
|
||||||
includes_SunOS='
|
|
||||||
#include <limits.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/sockio.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/mkdev.h>
|
|
||||||
#include <net/bpf.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <net/if_arp.h>
|
|
||||||
#include <net/if_types.h>
|
|
||||||
#include <net/route.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <netinet/ip.h>
|
|
||||||
#include <netinet/ip_mroute.h>
|
|
||||||
'
|
|
||||||
|
|
||||||
|
|
||||||
includes='
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/file.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netinet/ip.h>
|
|
||||||
#include <netinet/ip6.h>
|
|
||||||
#include <netinet/tcp.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/signal.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#include <time.h>
|
|
||||||
'
|
|
||||||
ccflags="$@"
|
|
||||||
|
|
||||||
# Write go tool cgo -godefs input.
|
|
||||||
(
|
|
||||||
echo package unix
|
|
||||||
echo
|
|
||||||
echo '/*'
|
|
||||||
indirect="includes_$(uname)"
|
|
||||||
echo "${!indirect} $includes"
|
|
||||||
echo '*/'
|
|
||||||
echo 'import "C"'
|
|
||||||
echo 'import "syscall"'
|
|
||||||
echo
|
|
||||||
echo 'const ('
|
|
||||||
|
|
||||||
# The gcc command line prints all the #defines
|
|
||||||
# it encounters while processing the input
|
|
||||||
echo "${!indirect} $includes" | $CC -x c - -E -dM $ccflags |
|
|
||||||
awk '
|
|
||||||
$1 != "#define" || $2 ~ /\(/ || $3 == "" {next}
|
|
||||||
|
|
||||||
$2 ~ /^E([ABCD]X|[BIS]P|[SD]I|S|FL)$/ {next} # 386 registers
|
|
||||||
$2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next}
|
|
||||||
$2 ~ /^(SCM_SRCRT)$/ {next}
|
|
||||||
$2 ~ /^(MAP_FAILED)$/ {next}
|
|
||||||
$2 ~ /^ELF_.*$/ {next}# <asm/elf.h> contains ELF_ARCH, etc.
|
|
||||||
|
|
||||||
$2 ~ /^EXTATTR_NAMESPACE_NAMES/ ||
|
|
||||||
$2 ~ /^EXTATTR_NAMESPACE_[A-Z]+_STRING/ {next}
|
|
||||||
|
|
||||||
$2 !~ /^ECCAPBITS/ &&
|
|
||||||
$2 !~ /^ETH_/ &&
|
|
||||||
$2 !~ /^EPROC_/ &&
|
|
||||||
$2 !~ /^EQUIV_/ &&
|
|
||||||
$2 !~ /^EXPR_/ &&
|
|
||||||
$2 ~ /^E[A-Z0-9_]+$/ ||
|
|
||||||
$2 ~ /^B[0-9_]+$/ ||
|
|
||||||
$2 ~ /^(OLD|NEW)DEV$/ ||
|
|
||||||
$2 == "BOTHER" ||
|
|
||||||
$2 ~ /^CI?BAUD(EX)?$/ ||
|
|
||||||
$2 == "IBSHIFT" ||
|
|
||||||
$2 ~ /^V[A-Z0-9]+$/ ||
|
|
||||||
$2 ~ /^CS[A-Z0-9]/ ||
|
|
||||||
$2 ~ /^I(SIG|CANON|CRNL|UCLC|EXTEN|MAXBEL|STRIP|UTF8)$/ ||
|
|
||||||
$2 ~ /^IGN/ ||
|
|
||||||
$2 ~ /^IX(ON|ANY|OFF)$/ ||
|
|
||||||
$2 ~ /^IN(LCR|PCK)$/ ||
|
|
||||||
$2 !~ "X86_CR3_PCID_NOFLUSH" &&
|
|
||||||
$2 ~ /(^FLU?SH)|(FLU?SH$)/ ||
|
|
||||||
$2 ~ /^C(LOCAL|READ|MSPAR|RTSCTS)$/ ||
|
|
||||||
$2 == "BRKINT" ||
|
|
||||||
$2 == "HUPCL" ||
|
|
||||||
$2 == "PENDIN" ||
|
|
||||||
$2 == "TOSTOP" ||
|
|
||||||
$2 == "XCASE" ||
|
|
||||||
$2 == "ALTWERASE" ||
|
|
||||||
$2 == "NOKERNINFO" ||
|
|
||||||
$2 == "NFDBITS" ||
|
|
||||||
$2 ~ /^PAR/ ||
|
|
||||||
$2 ~ /^SIG[^_]/ ||
|
|
||||||
$2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ ||
|
|
||||||
$2 ~ /^(NL|CR|TAB|BS|VT|FF)DLY$/ ||
|
|
||||||
$2 ~ /^(NL|CR|TAB|BS|VT|FF)[0-9]$/ ||
|
|
||||||
$2 ~ /^O?XTABS$/ ||
|
|
||||||
$2 ~ /^TC[IO](ON|OFF)$/ ||
|
|
||||||
$2 ~ /^IN_/ ||
|
|
||||||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
|
|
||||||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
|
|
||||||
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
|
|
||||||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|MCAST|EVFILT|NOTE|EV|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
|
|
||||||
$2 ~ /^TP_STATUS_/ ||
|
|
||||||
$2 ~ /^FALLOC_/ ||
|
|
||||||
$2 == "ICMPV6_FILTER" ||
|
|
||||||
$2 == "SOMAXCONN" ||
|
|
||||||
$2 == "NAME_MAX" ||
|
|
||||||
$2 == "IFNAMSIZ" ||
|
|
||||||
$2 ~ /^CTL_(HW|KERN|MAXNAME|NET|QUERY)$/ ||
|
|
||||||
$2 ~ /^KERN_(HOSTNAME|OS(RELEASE|TYPE)|VERSION)$/ ||
|
|
||||||
$2 ~ /^HW_MACHINE$/ ||
|
|
||||||
$2 ~ /^SYSCTL_VERS/ ||
|
|
||||||
$2 !~ "MNT_BITS" &&
|
|
||||||
$2 ~ /^(MS|MNT|UMOUNT)_/ ||
|
|
||||||
$2 ~ /^NS_GET_/ ||
|
|
||||||
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
|
|
||||||
$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|TFD)_/ ||
|
|
||||||
$2 ~ /^KEXEC_/ ||
|
|
||||||
$2 ~ /^LINUX_REBOOT_CMD_/ ||
|
|
||||||
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
|
|
||||||
$2 ~ /^MODULE_INIT_/ ||
|
|
||||||
$2 !~ "NLA_TYPE_MASK" &&
|
|
||||||
$2 !~ /^RTC_VL_(ACCURACY|BACKUP|DATA)/ &&
|
|
||||||
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ ||
|
|
||||||
$2 ~ /^SIOC/ ||
|
|
||||||
$2 ~ /^TIOC/ ||
|
|
||||||
$2 ~ /^TCGET/ ||
|
|
||||||
$2 ~ /^TCSET/ ||
|
|
||||||
$2 ~ /^TC(FLSH|SBRKP?|XONC)$/ ||
|
|
||||||
$2 !~ "RTF_BITS" &&
|
|
||||||
$2 ~ /^(IFF|IFT|NET_RT|RTM(GRP)?|RTF|RTV|RTA|RTAX)_/ ||
|
|
||||||
$2 ~ /^BIOC/ ||
|
|
||||||
$2 ~ /^DIOC/ ||
|
|
||||||
$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||
|
|
||||||
$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|LOCKS|MEMLOCK|MSGQUEUE|NICE|NOFILE|NPROC|RSS|RTPRIO|RTTIME|SIGPENDING|STACK)|RLIM_INFINITY/ ||
|
|
||||||
$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
|
|
||||||
$2 ~ /^CLONE_[A-Z_]+/ ||
|
|
||||||
$2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+)$/ &&
|
|
||||||
$2 ~ /^(BPF|DLT)_/ ||
|
|
||||||
$2 ~ /^(CLOCK|TIMER)_/ ||
|
|
||||||
$2 ~ /^CAN_/ ||
|
|
||||||
$2 ~ /^CAP_/ ||
|
|
||||||
$2 ~ /^ALG_/ ||
|
|
||||||
$2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE)/ ||
|
|
||||||
$2 ~ /^FS_IOC_.*(ENCRYPTION|VERITY|GETFLAGS)/ ||
|
|
||||||
$2 ~ /^FS_VERITY_/ ||
|
|
||||||
$2 ~ /^FSCRYPT_/ ||
|
|
||||||
$2 ~ /^GRND_/ ||
|
|
||||||
$2 ~ /^RND/ ||
|
|
||||||
$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||
|
|
||||||
$2 ~ /^KEYCTL_/ ||
|
|
||||||
$2 ~ /^PERF_EVENT_IOC_/ ||
|
|
||||||
$2 ~ /^SECCOMP_MODE_/ ||
|
|
||||||
$2 ~ /^SPLICE_/ ||
|
|
||||||
$2 ~ /^SYNC_FILE_RANGE_/ ||
|
|
||||||
$2 !~ /^AUDIT_RECORD_MAGIC/ &&
|
|
||||||
$2 !~ /IOC_MAGIC/ &&
|
|
||||||
$2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ ||
|
|
||||||
$2 ~ /^(VM|VMADDR)_/ ||
|
|
||||||
$2 ~ /^IOCTL_VM_SOCKETS_/ ||
|
|
||||||
$2 ~ /^(TASKSTATS|TS)_/ ||
|
|
||||||
$2 ~ /^CGROUPSTATS_/ ||
|
|
||||||
$2 ~ /^GENL_/ ||
|
|
||||||
$2 ~ /^STATX_/ ||
|
|
||||||
$2 ~ /^RENAME/ ||
|
|
||||||
$2 ~ /^UBI_IOC[A-Z]/ ||
|
|
||||||
$2 ~ /^UTIME_/ ||
|
|
||||||
$2 ~ /^XATTR_(CREATE|REPLACE|NO(DEFAULT|FOLLOW|SECURITY)|SHOWCOMPRESSION)/ ||
|
|
||||||
$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||
|
|
||||||
$2 ~ /^FSOPT_/ ||
|
|
||||||
$2 ~ /^WDIOC_/ ||
|
|
||||||
$2 ~ /^NFN/ ||
|
|
||||||
$2 ~ /^XDP_/ ||
|
|
||||||
$2 ~ /^RWF_/ ||
|
|
||||||
$2 ~ /^(HDIO|WIN|SMART)_/ ||
|
|
||||||
$2 ~ /^CRYPTO_/ ||
|
|
||||||
$2 ~ /^TIPC_/ ||
|
|
||||||
$2 ~ /^DEVLINK_/ ||
|
|
||||||
$2 !~ "WMESGLEN" &&
|
|
||||||
$2 ~ /^W[A-Z0-9]+$/ ||
|
|
||||||
$2 ~/^PPPIOC/ ||
|
|
||||||
$2 ~ /^FAN_|FANOTIFY_/ ||
|
|
||||||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
|
|
||||||
$2 ~ /^__WCOREFLAG$/ {next}
|
|
||||||
$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
|
|
||||||
|
|
||||||
{next}
|
|
||||||
' | sort
|
|
||||||
|
|
||||||
echo ')'
|
|
||||||
) >_const.go
|
|
||||||
|
|
||||||
# Pull out the error names for later.
|
|
||||||
errors=$(
|
|
||||||
echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
|
|
||||||
awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' |
|
|
||||||
sort
|
|
||||||
)
|
|
||||||
|
|
||||||
# Pull out the signal names for later.
|
|
||||||
signals=$(
|
|
||||||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
|
||||||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
|
|
||||||
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
|
|
||||||
sort
|
|
||||||
)
|
|
||||||
|
|
||||||
# Again, writing regexps to a file.
|
|
||||||
echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
|
|
||||||
awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print "^\t" $2 "[ \t]*=" }' |
|
|
||||||
sort >_error.grep
|
|
||||||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
|
||||||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
|
|
||||||
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
|
|
||||||
sort >_signal.grep
|
|
||||||
|
|
||||||
echo '// mkerrors.sh' "$@"
|
|
||||||
echo '// Code generated by the command above; see README.md. DO NOT EDIT.'
|
|
||||||
echo
|
|
||||||
echo "// +build ${GOARCH},${GOOS}"
|
|
||||||
echo
|
|
||||||
go tool cgo -godefs -- "$@" _const.go >_error.out
|
|
||||||
cat _error.out | grep -vf _error.grep | grep -vf _signal.grep
|
|
||||||
echo
|
|
||||||
echo '// Errors'
|
|
||||||
echo 'const ('
|
|
||||||
cat _error.out | grep -f _error.grep | sed 's/=\(.*\)/= syscall.Errno(\1)/'
|
|
||||||
echo ')'
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo '// Signals'
|
|
||||||
echo 'const ('
|
|
||||||
cat _error.out | grep -f _signal.grep | sed 's/=\(.*\)/= syscall.Signal(\1)/'
|
|
||||||
echo ')'
|
|
||||||
|
|
||||||
# Run C program to print error and syscall strings.
|
|
||||||
(
|
|
||||||
echo -E "
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
|
|
||||||
|
|
||||||
enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below
|
|
||||||
|
|
||||||
struct tuple {
|
|
||||||
int num;
|
|
||||||
const char *name;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tuple errors[] = {
|
|
||||||
"
|
|
||||||
for i in $errors
|
|
||||||
do
|
|
||||||
echo -E ' {'$i', "'$i'" },'
|
|
||||||
done
|
|
||||||
|
|
||||||
echo -E "
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tuple signals[] = {
|
|
||||||
"
|
|
||||||
for i in $signals
|
|
||||||
do
|
|
||||||
echo -E ' {'$i', "'$i'" },'
|
|
||||||
done
|
|
||||||
|
|
||||||
# Use -E because on some systems bash builtin interprets \n itself.
|
|
||||||
echo -E '
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
tuplecmp(const void *a, const void *b)
|
|
||||||
{
|
|
||||||
return ((struct tuple *)a)->num - ((struct tuple *)b)->num;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(void)
|
|
||||||
{
|
|
||||||
int i, e;
|
|
||||||
char buf[1024], *p;
|
|
||||||
|
|
||||||
printf("\n\n// Error table\n");
|
|
||||||
printf("var errorList = [...]struct {\n");
|
|
||||||
printf("\tnum syscall.Errno\n");
|
|
||||||
printf("\tname string\n");
|
|
||||||
printf("\tdesc string\n");
|
|
||||||
printf("} {\n");
|
|
||||||
qsort(errors, nelem(errors), sizeof errors[0], tuplecmp);
|
|
||||||
for(i=0; i<nelem(errors); i++) {
|
|
||||||
e = errors[i].num;
|
|
||||||
if(i > 0 && errors[i-1].num == e)
|
|
||||||
continue;
|
|
||||||
strcpy(buf, strerror(e));
|
|
||||||
// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
|
|
||||||
if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
|
|
||||||
buf[0] += a - A;
|
|
||||||
printf("\t{ %d, \"%s\", \"%s\" },\n", e, errors[i].name, buf);
|
|
||||||
}
|
|
||||||
printf("}\n\n");
|
|
||||||
|
|
||||||
printf("\n\n// Signal table\n");
|
|
||||||
printf("var signalList = [...]struct {\n");
|
|
||||||
printf("\tnum syscall.Signal\n");
|
|
||||||
printf("\tname string\n");
|
|
||||||
printf("\tdesc string\n");
|
|
||||||
printf("} {\n");
|
|
||||||
qsort(signals, nelem(signals), sizeof signals[0], tuplecmp);
|
|
||||||
for(i=0; i<nelem(signals); i++) {
|
|
||||||
e = signals[i].num;
|
|
||||||
if(i > 0 && signals[i-1].num == e)
|
|
||||||
continue;
|
|
||||||
strcpy(buf, strsignal(e));
|
|
||||||
// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
|
|
||||||
if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
|
|
||||||
buf[0] += a - A;
|
|
||||||
// cut trailing : number.
|
|
||||||
p = strrchr(buf, ":"[0]);
|
|
||||||
if(p)
|
|
||||||
*p = '\0';
|
|
||||||
printf("\t{ %d, \"%s\", \"%s\" },\n", e, signals[i].name, buf);
|
|
||||||
}
|
|
||||||
printf("}\n\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
'
|
|
||||||
) >_errors.c
|
|
||||||
|
|
||||||
$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out
|
|
@ -1,521 +0,0 @@
|
|||||||
// Copyright 2020 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.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// mkmerge.go parses generated source files and merges common
|
|
||||||
// consts, funcs, and types into a common source file, per GOOS.
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
// $ go run mkmerge.go -out MERGED FILE [FILE ...]
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// # Remove all common consts, funcs, and types from zerrors_linux_*.go
|
|
||||||
// # and write the common code into zerrors_linux.go
|
|
||||||
// $ go run mkmerge.go -out zerrors_linux.go zerrors_linux_*.go
|
|
||||||
//
|
|
||||||
// mkmerge.go performs the merge in the following steps:
|
|
||||||
// 1. Construct the set of common code that is idential in all
|
|
||||||
// architecture-specific files.
|
|
||||||
// 2. Write this common code to the merged file.
|
|
||||||
// 3. Remove the common code from all architecture-specific files.
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
|
||||||
"go/format"
|
|
||||||
"go/parser"
|
|
||||||
"go/token"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const validGOOS = "aix|darwin|dragonfly|freebsd|linux|netbsd|openbsd|solaris"
|
|
||||||
|
|
||||||
// getValidGOOS returns GOOS, true if filename ends with a valid "_GOOS.go"
|
|
||||||
func getValidGOOS(filename string) (string, bool) {
|
|
||||||
matches := regexp.MustCompile(`_(` + validGOOS + `)\.go$`).FindStringSubmatch(filename)
|
|
||||||
if len(matches) != 2 {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
return matches[1], true
|
|
||||||
}
|
|
||||||
|
|
||||||
// codeElem represents an ast.Decl in a comparable way.
|
|
||||||
type codeElem struct {
|
|
||||||
tok token.Token // e.g. token.CONST, token.TYPE, or token.FUNC
|
|
||||||
src string // the declaration formatted as source code
|
|
||||||
}
|
|
||||||
|
|
||||||
// newCodeElem returns a codeElem based on tok and node, or an error is returned.
|
|
||||||
func newCodeElem(tok token.Token, node ast.Node) (codeElem, error) {
|
|
||||||
var b strings.Builder
|
|
||||||
err := format.Node(&b, token.NewFileSet(), node)
|
|
||||||
if err != nil {
|
|
||||||
return codeElem{}, err
|
|
||||||
}
|
|
||||||
return codeElem{tok, b.String()}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// codeSet is a set of codeElems
|
|
||||||
type codeSet struct {
|
|
||||||
set map[codeElem]bool // true for all codeElems in the set
|
|
||||||
}
|
|
||||||
|
|
||||||
// newCodeSet returns a new codeSet
|
|
||||||
func newCodeSet() *codeSet { return &codeSet{make(map[codeElem]bool)} }
|
|
||||||
|
|
||||||
// add adds elem to c
|
|
||||||
func (c *codeSet) add(elem codeElem) { c.set[elem] = true }
|
|
||||||
|
|
||||||
// has returns true if elem is in c
|
|
||||||
func (c *codeSet) has(elem codeElem) bool { return c.set[elem] }
|
|
||||||
|
|
||||||
// isEmpty returns true if the set is empty
|
|
||||||
func (c *codeSet) isEmpty() bool { return len(c.set) == 0 }
|
|
||||||
|
|
||||||
// intersection returns a new set which is the intersection of c and a
|
|
||||||
func (c *codeSet) intersection(a *codeSet) *codeSet {
|
|
||||||
res := newCodeSet()
|
|
||||||
|
|
||||||
for elem := range c.set {
|
|
||||||
if a.has(elem) {
|
|
||||||
res.add(elem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// keepCommon is a filterFn for filtering the merged file with common declarations.
|
|
||||||
func (c *codeSet) keepCommon(elem codeElem) bool {
|
|
||||||
switch elem.tok {
|
|
||||||
case token.VAR:
|
|
||||||
// Remove all vars from the merged file
|
|
||||||
return false
|
|
||||||
case token.CONST, token.TYPE, token.FUNC, token.COMMENT:
|
|
||||||
// Remove arch-specific consts, types, functions, and file-level comments from the merged file
|
|
||||||
return c.has(elem)
|
|
||||||
case token.IMPORT:
|
|
||||||
// Keep imports, they are handled by filterImports
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Fatalf("keepCommon: invalid elem %v", elem)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// keepArchSpecific is a filterFn for filtering the GOARC-specific files.
|
|
||||||
func (c *codeSet) keepArchSpecific(elem codeElem) bool {
|
|
||||||
switch elem.tok {
|
|
||||||
case token.CONST, token.TYPE, token.FUNC:
|
|
||||||
// Remove common consts, types, or functions from the arch-specific file
|
|
||||||
return !c.has(elem)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// srcFile represents a source file
|
|
||||||
type srcFile struct {
|
|
||||||
name string
|
|
||||||
src []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// filterFn is a helper for filter
|
|
||||||
type filterFn func(codeElem) bool
|
|
||||||
|
|
||||||
// filter parses and filters Go source code from src, removing top
|
|
||||||
// level declarations using keep as predicate.
|
|
||||||
// For src parameter, please see docs for parser.ParseFile.
|
|
||||||
func filter(src interface{}, keep filterFn) ([]byte, error) {
|
|
||||||
// Parse the src into an ast
|
|
||||||
fset := token.NewFileSet()
|
|
||||||
f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
cmap := ast.NewCommentMap(fset, f, f.Comments)
|
|
||||||
|
|
||||||
// Group const/type specs on adjacent lines
|
|
||||||
var groups specGroups = make(map[string]int)
|
|
||||||
var groupID int
|
|
||||||
|
|
||||||
decls := f.Decls
|
|
||||||
f.Decls = f.Decls[:0]
|
|
||||||
for _, decl := range decls {
|
|
||||||
switch decl := decl.(type) {
|
|
||||||
case *ast.GenDecl:
|
|
||||||
// Filter imports, consts, types, vars
|
|
||||||
specs := decl.Specs
|
|
||||||
decl.Specs = decl.Specs[:0]
|
|
||||||
for i, spec := range specs {
|
|
||||||
elem, err := newCodeElem(decl.Tok, spec)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create new group if there are empty lines between this and the previous spec
|
|
||||||
if i > 0 && fset.Position(specs[i-1].End()).Line < fset.Position(spec.Pos()).Line-1 {
|
|
||||||
groupID++
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we should keep this spec
|
|
||||||
if keep(elem) {
|
|
||||||
decl.Specs = append(decl.Specs, spec)
|
|
||||||
groups.add(elem.src, groupID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Check if we should keep this decl
|
|
||||||
if len(decl.Specs) > 0 {
|
|
||||||
f.Decls = append(f.Decls, decl)
|
|
||||||
}
|
|
||||||
case *ast.FuncDecl:
|
|
||||||
// Filter funcs
|
|
||||||
elem, err := newCodeElem(token.FUNC, decl)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if keep(elem) {
|
|
||||||
f.Decls = append(f.Decls, decl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter file level comments
|
|
||||||
if cmap[f] != nil {
|
|
||||||
commentGroups := cmap[f]
|
|
||||||
cmap[f] = cmap[f][:0]
|
|
||||||
for _, cGrp := range commentGroups {
|
|
||||||
if keep(codeElem{token.COMMENT, cGrp.Text()}) {
|
|
||||||
cmap[f] = append(cmap[f], cGrp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f.Comments = cmap.Filter(f).Comments()
|
|
||||||
|
|
||||||
// Generate code for the filtered ast
|
|
||||||
var buf bytes.Buffer
|
|
||||||
if err = format.Node(&buf, fset, f); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
groupedSrc, err := groups.filterEmptyLines(&buf)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return filterImports(groupedSrc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// getCommonSet returns the set of consts, types, and funcs that are present in every file.
|
|
||||||
func getCommonSet(files []srcFile) (*codeSet, error) {
|
|
||||||
if len(files) == 0 {
|
|
||||||
return nil, fmt.Errorf("no files provided")
|
|
||||||
}
|
|
||||||
// Use the first architecture file as the baseline
|
|
||||||
baseSet, err := getCodeSet(files[0].src)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare baseline set with other architecture files: discard any element,
|
|
||||||
// that doesn't exist in other architecture files.
|
|
||||||
for _, f := range files[1:] {
|
|
||||||
set, err := getCodeSet(f.src)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
baseSet = baseSet.intersection(set)
|
|
||||||
}
|
|
||||||
return baseSet, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getCodeSet returns the set of all top-level consts, types, and funcs from src.
|
|
||||||
// src must be string, []byte, or io.Reader (see go/parser.ParseFile docs)
|
|
||||||
func getCodeSet(src interface{}) (*codeSet, error) {
|
|
||||||
set := newCodeSet()
|
|
||||||
|
|
||||||
fset := token.NewFileSet()
|
|
||||||
f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, decl := range f.Decls {
|
|
||||||
switch decl := decl.(type) {
|
|
||||||
case *ast.GenDecl:
|
|
||||||
// Add const, and type declarations
|
|
||||||
if !(decl.Tok == token.CONST || decl.Tok == token.TYPE) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, spec := range decl.Specs {
|
|
||||||
elem, err := newCodeElem(decl.Tok, spec)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
set.add(elem)
|
|
||||||
}
|
|
||||||
case *ast.FuncDecl:
|
|
||||||
// Add func declarations
|
|
||||||
elem, err := newCodeElem(token.FUNC, decl)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
set.add(elem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add file level comments
|
|
||||||
cmap := ast.NewCommentMap(fset, f, f.Comments)
|
|
||||||
for _, cGrp := range cmap[f] {
|
|
||||||
set.add(codeElem{token.COMMENT, cGrp.Text()})
|
|
||||||
}
|
|
||||||
|
|
||||||
return set, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// importName returns the identifier (PackageName) for an imported package
|
|
||||||
func importName(iSpec *ast.ImportSpec) (string, error) {
|
|
||||||
if iSpec.Name == nil {
|
|
||||||
name, err := strconv.Unquote(iSpec.Path.Value)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return path.Base(name), nil
|
|
||||||
}
|
|
||||||
return iSpec.Name.Name, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// specGroups tracks grouped const/type specs with a map of line: groupID pairs
|
|
||||||
type specGroups map[string]int
|
|
||||||
|
|
||||||
// add spec source to group
|
|
||||||
func (s specGroups) add(src string, groupID int) error {
|
|
||||||
srcBytes, err := format.Source(bytes.TrimSpace([]byte(src)))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
s[string(srcBytes)] = groupID
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// filterEmptyLines removes empty lines within groups of const/type specs.
|
|
||||||
// Returns the filtered source.
|
|
||||||
func (s specGroups) filterEmptyLines(src io.Reader) ([]byte, error) {
|
|
||||||
scanner := bufio.NewScanner(src)
|
|
||||||
var out bytes.Buffer
|
|
||||||
|
|
||||||
var emptyLines bytes.Buffer
|
|
||||||
prevGroupID := -1 // Initialize to invalid group
|
|
||||||
for scanner.Scan() {
|
|
||||||
line := bytes.TrimSpace(scanner.Bytes())
|
|
||||||
|
|
||||||
if len(line) == 0 {
|
|
||||||
fmt.Fprintf(&emptyLines, "%s\n", scanner.Bytes())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Discard emptyLines if previous non-empty line belonged to the same
|
|
||||||
// group as this line
|
|
||||||
if src, err := format.Source(line); err == nil {
|
|
||||||
groupID, ok := s[string(src)]
|
|
||||||
if ok && groupID == prevGroupID {
|
|
||||||
emptyLines.Reset()
|
|
||||||
}
|
|
||||||
prevGroupID = groupID
|
|
||||||
}
|
|
||||||
|
|
||||||
emptyLines.WriteTo(&out)
|
|
||||||
fmt.Fprintf(&out, "%s\n", scanner.Bytes())
|
|
||||||
}
|
|
||||||
if err := scanner.Err(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// filterImports removes unused imports from fileSrc, and returns a formatted src.
|
|
||||||
func filterImports(fileSrc []byte) ([]byte, error) {
|
|
||||||
fset := token.NewFileSet()
|
|
||||||
file, err := parser.ParseFile(fset, "", fileSrc, parser.ParseComments)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
cmap := ast.NewCommentMap(fset, file, file.Comments)
|
|
||||||
|
|
||||||
// create set of references to imported identifiers
|
|
||||||
keepImport := make(map[string]bool)
|
|
||||||
for _, u := range file.Unresolved {
|
|
||||||
keepImport[u.Name] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// filter import declarations
|
|
||||||
decls := file.Decls
|
|
||||||
file.Decls = file.Decls[:0]
|
|
||||||
for _, decl := range decls {
|
|
||||||
importDecl, ok := decl.(*ast.GenDecl)
|
|
||||||
|
|
||||||
// Keep non-import declarations
|
|
||||||
if !ok || importDecl.Tok != token.IMPORT {
|
|
||||||
file.Decls = append(file.Decls, decl)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter the import specs
|
|
||||||
specs := importDecl.Specs
|
|
||||||
importDecl.Specs = importDecl.Specs[:0]
|
|
||||||
for _, spec := range specs {
|
|
||||||
iSpec := spec.(*ast.ImportSpec)
|
|
||||||
name, err := importName(iSpec)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if keepImport[name] {
|
|
||||||
importDecl.Specs = append(importDecl.Specs, iSpec)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(importDecl.Specs) > 0 {
|
|
||||||
file.Decls = append(file.Decls, importDecl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// filter file.Imports
|
|
||||||
imports := file.Imports
|
|
||||||
file.Imports = file.Imports[:0]
|
|
||||||
for _, spec := range imports {
|
|
||||||
name, err := importName(spec)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if keepImport[name] {
|
|
||||||
file.Imports = append(file.Imports, spec)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file.Comments = cmap.Filter(file).Comments()
|
|
||||||
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err = format.Node(&buf, fset, file)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// merge extracts duplicate code from archFiles and merges it to mergeFile.
|
|
||||||
// 1. Construct commonSet: the set of code that is idential in all archFiles.
|
|
||||||
// 2. Write the code in commonSet to mergedFile.
|
|
||||||
// 3. Remove the commonSet code from all archFiles.
|
|
||||||
func merge(mergedFile string, archFiles ...string) error {
|
|
||||||
// extract and validate the GOOS part of the merged filename
|
|
||||||
goos, ok := getValidGOOS(mergedFile)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("invalid GOOS in merged file name %s", mergedFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read architecture files
|
|
||||||
var inSrc []srcFile
|
|
||||||
for _, file := range archFiles {
|
|
||||||
src, err := ioutil.ReadFile(file)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot read archfile %s: %w", file, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
inSrc = append(inSrc, srcFile{file, src})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. Construct the set of top-level declarations common for all files
|
|
||||||
commonSet, err := getCommonSet(inSrc)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if commonSet.isEmpty() {
|
|
||||||
// No common code => do not modify any files
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Write the merged file
|
|
||||||
mergedSrc, err := filter(inSrc[0].src, commonSet.keepCommon)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := os.Create(mergedFile)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
buf := bufio.NewWriter(f)
|
|
||||||
fmt.Fprintln(buf, "// Code generated by mkmerge.go; DO NOT EDIT.")
|
|
||||||
fmt.Fprintln(buf)
|
|
||||||
fmt.Fprintf(buf, "// +build %s\n", goos)
|
|
||||||
fmt.Fprintln(buf)
|
|
||||||
buf.Write(mergedSrc)
|
|
||||||
|
|
||||||
err = buf.Flush()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = f.Close()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Remove duplicate declarations from the architecture files
|
|
||||||
for _, inFile := range inSrc {
|
|
||||||
src, err := filter(inFile.src, commonSet.keepArchSpecific)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = ioutil.WriteFile(inFile.name, src, 0644)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
var mergedFile string
|
|
||||||
flag.StringVar(&mergedFile, "out", "", "Write merged code to `FILE`")
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
// Expand wildcards
|
|
||||||
var filenames []string
|
|
||||||
for _, arg := range flag.Args() {
|
|
||||||
matches, err := filepath.Glob(arg)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "Invalid command line argument %q: %v\n", arg, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
filenames = append(filenames, matches...)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(filenames) < 2 {
|
|
||||||
// No need to merge
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err := merge(mergedFile, filenames...)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "Merge failed with error: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,505 +0,0 @@
|
|||||||
// Copyright 2020 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.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// Test cases for mkmerge.go.
|
|
||||||
// Usage:
|
|
||||||
// $ go test mkmerge.go mkmerge_test.go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"go/parser"
|
|
||||||
"go/token"
|
|
||||||
"html/template"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestImports(t *testing.T) {
|
|
||||||
t.Run("importName", func(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
src string
|
|
||||||
ident string
|
|
||||||
}{
|
|
||||||
{`"syscall"`, "syscall"},
|
|
||||||
{`. "foobar"`, "."},
|
|
||||||
{`"go/ast"`, "ast"},
|
|
||||||
{`moo "go/format"`, "moo"},
|
|
||||||
{`. "go/token"`, "."},
|
|
||||||
{`"golang.org/x/sys/unix"`, "unix"},
|
|
||||||
{`nix "golang.org/x/sys/unix"`, "nix"},
|
|
||||||
{`_ "golang.org/x/sys/unix"`, "_"},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range cases {
|
|
||||||
pkgSrc := fmt.Sprintf("package main\nimport %s", c.src)
|
|
||||||
|
|
||||||
f, err := parser.ParseFile(token.NewFileSet(), "", pkgSrc, parser.ImportsOnly)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if len(f.Imports) != 1 {
|
|
||||||
t.Errorf("Got %d imports, expected 1", len(f.Imports))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
got, err := importName(f.Imports[0])
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if got != c.ident {
|
|
||||||
t.Errorf("Got %q, expected %q", got, c.ident)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("filterImports", func(t *testing.T) {
|
|
||||||
cases := []struct{ before, after string }{
|
|
||||||
{`package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"foo"
|
|
||||||
"bar"
|
|
||||||
)`,
|
|
||||||
"package test\n"},
|
|
||||||
{`package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"foo"
|
|
||||||
"bar"
|
|
||||||
)
|
|
||||||
|
|
||||||
func useFoo() { foo.Usage() }`,
|
|
||||||
`package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"foo"
|
|
||||||
)
|
|
||||||
|
|
||||||
func useFoo() { foo.Usage() }
|
|
||||||
`},
|
|
||||||
}
|
|
||||||
for _, c := range cases {
|
|
||||||
got, err := filterImports([]byte(c.before))
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if string(got) != c.after {
|
|
||||||
t.Errorf("Got:\n%s\nExpected:\n%s\n", got, c.after)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMerge(t *testing.T) {
|
|
||||||
// Input architecture files
|
|
||||||
inTmpl := template.Must(template.New("input").Parse(`
|
|
||||||
// Package comments
|
|
||||||
|
|
||||||
// build directives for arch{{.}}
|
|
||||||
|
|
||||||
// +build goos,arch{{.}}
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
int utimes(uintptr_t, uintptr_t);
|
|
||||||
int utimensat(int, uintptr_t, uintptr_t, int);
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
// The imports
|
|
||||||
import (
|
|
||||||
"commonDep"
|
|
||||||
"uniqueDep{{.}}"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Vars
|
|
||||||
var (
|
|
||||||
commonVar = commonDep.Use("common")
|
|
||||||
|
|
||||||
uniqueVar{{.}} = "unique{{.}}"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Common free standing comment
|
|
||||||
|
|
||||||
// Common comment
|
|
||||||
const COMMON_INDEPENDENT = 1234
|
|
||||||
const UNIQUE_INDEPENDENT_{{.}} = "UNIQUE_INDEPENDENT_{{.}}"
|
|
||||||
|
|
||||||
// Group comment
|
|
||||||
const (
|
|
||||||
COMMON_GROUP = "COMMON_GROUP"
|
|
||||||
UNIQUE_GROUP_{{.}} = "UNIQUE_GROUP_{{.}}"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Group2 comment
|
|
||||||
const (
|
|
||||||
UNIQUE_GROUP21_{{.}} = "UNIQUE_GROUP21_{{.}}"
|
|
||||||
UNIQUE_GROUP22_{{.}} = "UNIQUE_GROUP22_{{.}}"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Group3 comment
|
|
||||||
const (
|
|
||||||
sub1Common1 = 11
|
|
||||||
sub1Unique2{{.}} = 12
|
|
||||||
sub1Common3_LONG = 13
|
|
||||||
|
|
||||||
sub2Unique1{{.}} = 21
|
|
||||||
sub2Common2 = 22
|
|
||||||
sub2Common3 = 23
|
|
||||||
sub2Unique4{{.}} = 24
|
|
||||||
)
|
|
||||||
|
|
||||||
type commonInt int
|
|
||||||
|
|
||||||
type uniqueInt{{.}} int
|
|
||||||
|
|
||||||
func commonF() string {
|
|
||||||
return commonDep.Use("common")
|
|
||||||
}
|
|
||||||
|
|
||||||
func uniqueF() string {
|
|
||||||
C.utimes(0, 0)
|
|
||||||
return uniqueDep{{.}}.Use("{{.}}")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Group4 comment
|
|
||||||
const (
|
|
||||||
sub3Common1 = 31
|
|
||||||
sub3Unique2{{.}} = 32
|
|
||||||
sub3Unique3{{.}} = 33
|
|
||||||
sub3Common4 = 34
|
|
||||||
|
|
||||||
sub4Common1, sub4Unique2{{.}} = 41, 42
|
|
||||||
sub4Unique3{{.}}, sub4Common4 = 43, 44
|
|
||||||
)
|
|
||||||
`))
|
|
||||||
|
|
||||||
// Filtered architecture files
|
|
||||||
outTmpl := template.Must(template.New("output").Parse(`// Package comments
|
|
||||||
|
|
||||||
// build directives for arch{{.}}
|
|
||||||
|
|
||||||
// +build goos,arch{{.}}
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
int utimes(uintptr_t, uintptr_t);
|
|
||||||
int utimensat(int, uintptr_t, uintptr_t, int);
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
// The imports
|
|
||||||
import (
|
|
||||||
"commonDep"
|
|
||||||
"uniqueDep{{.}}"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Vars
|
|
||||||
var (
|
|
||||||
commonVar = commonDep.Use("common")
|
|
||||||
|
|
||||||
uniqueVar{{.}} = "unique{{.}}"
|
|
||||||
)
|
|
||||||
|
|
||||||
const UNIQUE_INDEPENDENT_{{.}} = "UNIQUE_INDEPENDENT_{{.}}"
|
|
||||||
|
|
||||||
// Group comment
|
|
||||||
const (
|
|
||||||
UNIQUE_GROUP_{{.}} = "UNIQUE_GROUP_{{.}}"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Group2 comment
|
|
||||||
const (
|
|
||||||
UNIQUE_GROUP21_{{.}} = "UNIQUE_GROUP21_{{.}}"
|
|
||||||
UNIQUE_GROUP22_{{.}} = "UNIQUE_GROUP22_{{.}}"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Group3 comment
|
|
||||||
const (
|
|
||||||
sub1Unique2{{.}} = 12
|
|
||||||
|
|
||||||
sub2Unique1{{.}} = 21
|
|
||||||
sub2Unique4{{.}} = 24
|
|
||||||
)
|
|
||||||
|
|
||||||
type uniqueInt{{.}} int
|
|
||||||
|
|
||||||
func uniqueF() string {
|
|
||||||
C.utimes(0, 0)
|
|
||||||
return uniqueDep{{.}}.Use("{{.}}")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Group4 comment
|
|
||||||
const (
|
|
||||||
sub3Unique2{{.}} = 32
|
|
||||||
sub3Unique3{{.}} = 33
|
|
||||||
|
|
||||||
sub4Common1, sub4Unique2{{.}} = 41, 42
|
|
||||||
sub4Unique3{{.}}, sub4Common4 = 43, 44
|
|
||||||
)
|
|
||||||
`))
|
|
||||||
|
|
||||||
const mergedFile = `// Package comments
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
// The imports
|
|
||||||
import (
|
|
||||||
"commonDep"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Common free standing comment
|
|
||||||
|
|
||||||
// Common comment
|
|
||||||
const COMMON_INDEPENDENT = 1234
|
|
||||||
|
|
||||||
// Group comment
|
|
||||||
const (
|
|
||||||
COMMON_GROUP = "COMMON_GROUP"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Group3 comment
|
|
||||||
const (
|
|
||||||
sub1Common1 = 11
|
|
||||||
sub1Common3_LONG = 13
|
|
||||||
|
|
||||||
sub2Common2 = 22
|
|
||||||
sub2Common3 = 23
|
|
||||||
)
|
|
||||||
|
|
||||||
type commonInt int
|
|
||||||
|
|
||||||
func commonF() string {
|
|
||||||
return commonDep.Use("common")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Group4 comment
|
|
||||||
const (
|
|
||||||
sub3Common1 = 31
|
|
||||||
sub3Common4 = 34
|
|
||||||
)
|
|
||||||
`
|
|
||||||
|
|
||||||
// Generate source code for different "architectures"
|
|
||||||
var inFiles, outFiles []srcFile
|
|
||||||
for _, arch := range strings.Fields("A B C D") {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
err := inTmpl.Execute(buf, arch)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
inFiles = append(inFiles, srcFile{"file" + arch, buf.Bytes()})
|
|
||||||
|
|
||||||
buf = new(bytes.Buffer)
|
|
||||||
err = outTmpl.Execute(buf, arch)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
outFiles = append(outFiles, srcFile{"file" + arch, buf.Bytes()})
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("getCodeSet", func(t *testing.T) {
|
|
||||||
got, err := getCodeSet(inFiles[0].src)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
expectedElems := []codeElem{
|
|
||||||
{token.COMMENT, "Package comments\n"},
|
|
||||||
{token.COMMENT, "build directives for archA\n"},
|
|
||||||
{token.COMMENT, "+build goos,archA\n"},
|
|
||||||
{token.CONST, `COMMON_INDEPENDENT = 1234`},
|
|
||||||
{token.CONST, `UNIQUE_INDEPENDENT_A = "UNIQUE_INDEPENDENT_A"`},
|
|
||||||
{token.CONST, `COMMON_GROUP = "COMMON_GROUP"`},
|
|
||||||
{token.CONST, `UNIQUE_GROUP_A = "UNIQUE_GROUP_A"`},
|
|
||||||
{token.CONST, `UNIQUE_GROUP21_A = "UNIQUE_GROUP21_A"`},
|
|
||||||
{token.CONST, `UNIQUE_GROUP22_A = "UNIQUE_GROUP22_A"`},
|
|
||||||
{token.CONST, `sub1Common1 = 11`},
|
|
||||||
{token.CONST, `sub1Unique2A = 12`},
|
|
||||||
{token.CONST, `sub1Common3_LONG = 13`},
|
|
||||||
{token.CONST, `sub2Unique1A = 21`},
|
|
||||||
{token.CONST, `sub2Common2 = 22`},
|
|
||||||
{token.CONST, `sub2Common3 = 23`},
|
|
||||||
{token.CONST, `sub2Unique4A = 24`},
|
|
||||||
{token.CONST, `sub3Common1 = 31`},
|
|
||||||
{token.CONST, `sub3Unique2A = 32`},
|
|
||||||
{token.CONST, `sub3Unique3A = 33`},
|
|
||||||
{token.CONST, `sub3Common4 = 34`},
|
|
||||||
{token.CONST, `sub4Common1, sub4Unique2A = 41, 42`},
|
|
||||||
{token.CONST, `sub4Unique3A, sub4Common4 = 43, 44`},
|
|
||||||
{token.TYPE, `commonInt int`},
|
|
||||||
{token.TYPE, `uniqueIntA int`},
|
|
||||||
{token.FUNC, `func commonF() string {
|
|
||||||
return commonDep.Use("common")
|
|
||||||
}`},
|
|
||||||
{token.FUNC, `func uniqueF() string {
|
|
||||||
C.utimes(0, 0)
|
|
||||||
return uniqueDepA.Use("A")
|
|
||||||
}`},
|
|
||||||
}
|
|
||||||
expected := newCodeSet()
|
|
||||||
for _, d := range expectedElems {
|
|
||||||
expected.add(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(got.set) != len(expected.set) {
|
|
||||||
t.Errorf("Got %d codeElems, expected %d", len(got.set), len(expected.set))
|
|
||||||
}
|
|
||||||
for expElem := range expected.set {
|
|
||||||
if !got.has(expElem) {
|
|
||||||
t.Errorf("Didn't get expected codeElem %#v", expElem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for gotElem := range got.set {
|
|
||||||
if !expected.has(gotElem) {
|
|
||||||
t.Errorf("Got unexpected codeElem %#v", gotElem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("getCommonSet", func(t *testing.T) {
|
|
||||||
got, err := getCommonSet(inFiles)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := newCodeSet()
|
|
||||||
expected.add(codeElem{token.COMMENT, "Package comments\n"})
|
|
||||||
expected.add(codeElem{token.CONST, `COMMON_INDEPENDENT = 1234`})
|
|
||||||
expected.add(codeElem{token.CONST, `COMMON_GROUP = "COMMON_GROUP"`})
|
|
||||||
expected.add(codeElem{token.CONST, `sub1Common1 = 11`})
|
|
||||||
expected.add(codeElem{token.CONST, `sub1Common3_LONG = 13`})
|
|
||||||
expected.add(codeElem{token.CONST, `sub2Common2 = 22`})
|
|
||||||
expected.add(codeElem{token.CONST, `sub2Common3 = 23`})
|
|
||||||
expected.add(codeElem{token.CONST, `sub3Common1 = 31`})
|
|
||||||
expected.add(codeElem{token.CONST, `sub3Common4 = 34`})
|
|
||||||
expected.add(codeElem{token.TYPE, `commonInt int`})
|
|
||||||
expected.add(codeElem{token.FUNC, `func commonF() string {
|
|
||||||
return commonDep.Use("common")
|
|
||||||
}`})
|
|
||||||
|
|
||||||
if len(got.set) != len(expected.set) {
|
|
||||||
t.Errorf("Got %d codeElems, expected %d", len(got.set), len(expected.set))
|
|
||||||
}
|
|
||||||
for expElem := range expected.set {
|
|
||||||
if !got.has(expElem) {
|
|
||||||
t.Errorf("Didn't get expected codeElem %#v", expElem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for gotElem := range got.set {
|
|
||||||
if !expected.has(gotElem) {
|
|
||||||
t.Errorf("Got unexpected codeElem %#v", gotElem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("filter(keepCommon)", func(t *testing.T) {
|
|
||||||
commonSet, err := getCommonSet(inFiles)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
got, err := filter(inFiles[0].src, commonSet.keepCommon)
|
|
||||||
expected := []byte(mergedFile)
|
|
||||||
|
|
||||||
if !bytes.Equal(got, expected) {
|
|
||||||
t.Errorf("Got:\n%s\nExpected:\n%s", addLineNr(got), addLineNr(expected))
|
|
||||||
diffLines(t, got, expected)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("filter(keepArchSpecific)", func(t *testing.T) {
|
|
||||||
commonSet, err := getCommonSet(inFiles)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range inFiles {
|
|
||||||
got, err := filter(inFiles[i].src, commonSet.keepArchSpecific)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := outFiles[i].src
|
|
||||||
|
|
||||||
if !bytes.Equal(got, expected) {
|
|
||||||
t.Errorf("Got:\n%s\nExpected:\n%s", addLineNr(got), addLineNr(expected))
|
|
||||||
diffLines(t, got, expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMergedName(t *testing.T) {
|
|
||||||
t.Run("getValidGOOS", func(t *testing.T) {
|
|
||||||
testcases := []struct {
|
|
||||||
filename, goos string
|
|
||||||
ok bool
|
|
||||||
}{
|
|
||||||
{"zerrors_aix.go", "aix", true},
|
|
||||||
{"zerrors_darwin.go", "darwin", true},
|
|
||||||
{"zerrors_dragonfly.go", "dragonfly", true},
|
|
||||||
{"zerrors_freebsd.go", "freebsd", true},
|
|
||||||
{"zerrors_linux.go", "linux", true},
|
|
||||||
{"zerrors_netbsd.go", "netbsd", true},
|
|
||||||
{"zerrors_openbsd.go", "openbsd", true},
|
|
||||||
{"zerrors_solaris.go", "solaris", true},
|
|
||||||
{"zerrors_multics.go", "", false},
|
|
||||||
}
|
|
||||||
for _, tc := range testcases {
|
|
||||||
goos, ok := getValidGOOS(tc.filename)
|
|
||||||
if goos != tc.goos {
|
|
||||||
t.Errorf("got GOOS %q, expected %q", goos, tc.goos)
|
|
||||||
}
|
|
||||||
if ok != tc.ok {
|
|
||||||
t.Errorf("got ok %v, expected %v", ok, tc.ok)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper functions to diff test sources
|
|
||||||
|
|
||||||
func diffLines(t *testing.T, got, expected []byte) {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
gotLines := bytes.Split(got, []byte{'\n'})
|
|
||||||
expLines := bytes.Split(expected, []byte{'\n'})
|
|
||||||
|
|
||||||
i := 0
|
|
||||||
for i < len(gotLines) && i < len(expLines) {
|
|
||||||
if !bytes.Equal(gotLines[i], expLines[i]) {
|
|
||||||
t.Errorf("Line %d: Got:\n%q\nExpected:\n%q", i+1, gotLines[i], expLines[i])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
|
|
||||||
if i < len(gotLines) && i >= len(expLines) {
|
|
||||||
t.Errorf("Line %d: got %q, expected EOF", i+1, gotLines[i])
|
|
||||||
}
|
|
||||||
if i >= len(gotLines) && i < len(expLines) {
|
|
||||||
t.Errorf("Line %d: got EOF, expected %q", i+1, gotLines[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func addLineNr(src []byte) []byte {
|
|
||||||
lines := bytes.Split(src, []byte("\n"))
|
|
||||||
for i, line := range lines {
|
|
||||||
lines[i] = []byte(fmt.Sprintf("%d: %s", i+1, line))
|
|
||||||
}
|
|
||||||
return bytes.Join(lines, []byte("\n"))
|
|
||||||
}
|
|
@ -1,127 +0,0 @@
|
|||||||
// Copyright 2016 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.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// mkpost processes the output of cgo -godefs to
|
|
||||||
// modify the generated types. It is used to clean up
|
|
||||||
// the sys API in an architecture specific manner.
|
|
||||||
//
|
|
||||||
// mkpost is run after cgo -godefs; see README.md.
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"go/format"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Get the OS and architecture (using GOARCH_TARGET if it exists)
|
|
||||||
goos := os.Getenv("GOOS")
|
|
||||||
goarch := os.Getenv("GOARCH_TARGET")
|
|
||||||
if goarch == "" {
|
|
||||||
goarch = os.Getenv("GOARCH")
|
|
||||||
}
|
|
||||||
// Check that we are using the Docker-based build system if we should be.
|
|
||||||
if goos == "linux" {
|
|
||||||
if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
|
|
||||||
os.Stderr.WriteString("In the Docker-based build system, mkpost should not be called directly.\n")
|
|
||||||
os.Stderr.WriteString("See README.md\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := ioutil.ReadAll(os.Stdin)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if goos == "aix" {
|
|
||||||
// Replace type of Atim, Mtim and Ctim by Timespec in Stat_t
|
|
||||||
// to avoid having both StTimespec and Timespec.
|
|
||||||
sttimespec := regexp.MustCompile(`_Ctype_struct_st_timespec`)
|
|
||||||
b = sttimespec.ReplaceAll(b, []byte("Timespec"))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Intentionally export __val fields in Fsid and Sigset_t
|
|
||||||
valRegex := regexp.MustCompile(`type (Fsid|Sigset_t) struct {(\s+)X__(bits|val)(\s+\S+\s+)}`)
|
|
||||||
b = valRegex.ReplaceAll(b, []byte("type $1 struct {${2}Val$4}"))
|
|
||||||
|
|
||||||
// Intentionally export __fds_bits field in FdSet
|
|
||||||
fdSetRegex := regexp.MustCompile(`type (FdSet) struct {(\s+)X__fds_bits(\s+\S+\s+)}`)
|
|
||||||
b = fdSetRegex.ReplaceAll(b, []byte("type $1 struct {${2}Bits$3}"))
|
|
||||||
|
|
||||||
// If we have empty Ptrace structs, we should delete them. Only s390x emits
|
|
||||||
// nonempty Ptrace structs.
|
|
||||||
ptraceRexexp := regexp.MustCompile(`type Ptrace((Psw|Fpregs|Per) struct {\s*})`)
|
|
||||||
b = ptraceRexexp.ReplaceAll(b, nil)
|
|
||||||
|
|
||||||
// Replace the control_regs union with a blank identifier for now.
|
|
||||||
controlRegsRegex := regexp.MustCompile(`(Control_regs)\s+\[0\]uint64`)
|
|
||||||
b = controlRegsRegex.ReplaceAll(b, []byte("_ [0]uint64"))
|
|
||||||
|
|
||||||
// Remove fields that are added by glibc
|
|
||||||
// Note that this is unstable as the identifers are private.
|
|
||||||
removeFieldsRegex := regexp.MustCompile(`X__glibc\S*`)
|
|
||||||
b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
|
|
||||||
|
|
||||||
// Convert [65]int8 to [65]byte in Utsname members to simplify
|
|
||||||
// conversion to string; see golang.org/issue/20753
|
|
||||||
convertUtsnameRegex := regexp.MustCompile(`((Sys|Node|Domain)name|Release|Version|Machine)(\s+)\[(\d+)\]u?int8`)
|
|
||||||
b = convertUtsnameRegex.ReplaceAll(b, []byte("$1$3[$4]byte"))
|
|
||||||
|
|
||||||
// Convert [n]int8 to [n]byte in Statvfs_t members to simplify
|
|
||||||
// conversion to string.
|
|
||||||
convertStatvfsRegex := regexp.MustCompile(`((Fstype|Mnton|Mntfrom)name)(\s+)\[(\d+)\]int8`)
|
|
||||||
b = convertStatvfsRegex.ReplaceAll(b, []byte("$1$3[$4]byte"))
|
|
||||||
|
|
||||||
// Convert [1024]int8 to [1024]byte in Ptmget members
|
|
||||||
convertPtmget := regexp.MustCompile(`([SC]n)(\s+)\[(\d+)\]u?int8`)
|
|
||||||
b = convertPtmget.ReplaceAll(b, []byte("$1[$3]byte"))
|
|
||||||
|
|
||||||
// Remove spare fields (e.g. in Statx_t)
|
|
||||||
spareFieldsRegex := regexp.MustCompile(`X__spare\S*`)
|
|
||||||
b = spareFieldsRegex.ReplaceAll(b, []byte("_"))
|
|
||||||
|
|
||||||
// Remove cgo padding fields
|
|
||||||
removePaddingFieldsRegex := regexp.MustCompile(`Pad_cgo_\d+`)
|
|
||||||
b = removePaddingFieldsRegex.ReplaceAll(b, []byte("_"))
|
|
||||||
|
|
||||||
// Remove padding, hidden, or unused fields
|
|
||||||
removeFieldsRegex = regexp.MustCompile(`\b(X_\S+|Padding)`)
|
|
||||||
b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
|
|
||||||
|
|
||||||
// Remove the first line of warning from cgo
|
|
||||||
b = b[bytes.IndexByte(b, '\n')+1:]
|
|
||||||
// Modify the command in the header to include:
|
|
||||||
// mkpost, our own warning, and a build tag.
|
|
||||||
replacement := fmt.Sprintf(`$1 | go run mkpost.go
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s,%s`, goarch, goos)
|
|
||||||
cgoCommandRegex := regexp.MustCompile(`(cgo -godefs .*)`)
|
|
||||||
b = cgoCommandRegex.ReplaceAll(b, []byte(replacement))
|
|
||||||
|
|
||||||
// Rename Stat_t time fields
|
|
||||||
if goos == "freebsd" && goarch == "386" {
|
|
||||||
// Hide Stat_t.[AMCB]tim_ext fields
|
|
||||||
renameStatTimeExtFieldsRegex := regexp.MustCompile(`[AMCB]tim_ext`)
|
|
||||||
b = renameStatTimeExtFieldsRegex.ReplaceAll(b, []byte("_"))
|
|
||||||
}
|
|
||||||
renameStatTimeFieldsRegex := regexp.MustCompile(`([AMCB])(?:irth)?time?(?:spec)?\s+(Timespec|StTimespec)`)
|
|
||||||
b = renameStatTimeFieldsRegex.ReplaceAll(b, []byte("${1}tim ${2}"))
|
|
||||||
|
|
||||||
// gofmt
|
|
||||||
b, err = format.Source(b)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
os.Stdout.Write(b)
|
|
||||||
}
|
|
@ -1,402 +0,0 @@
|
|||||||
// Copyright 2018 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.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
/*
|
|
||||||
This program reads a file containing function prototypes
|
|
||||||
(like syscall_darwin.go) and generates system call bodies.
|
|
||||||
The prototypes are marked by lines beginning with "//sys"
|
|
||||||
and read like func declarations if //sys is replaced by func, but:
|
|
||||||
* The parameter lists must give a name for each argument.
|
|
||||||
This includes return parameters.
|
|
||||||
* The parameter lists must give a type for each argument:
|
|
||||||
the (x, y, z int) shorthand is not allowed.
|
|
||||||
* If the return parameter is an error number, it must be named errno.
|
|
||||||
|
|
||||||
A line beginning with //sysnb is like //sys, except that the
|
|
||||||
goroutine will not be suspended during the execution of the system
|
|
||||||
call. This must only be used for system calls which can never
|
|
||||||
block, as otherwise the system call could cause all goroutines to
|
|
||||||
hang.
|
|
||||||
*/
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
b32 = flag.Bool("b32", false, "32bit big-endian")
|
|
||||||
l32 = flag.Bool("l32", false, "32bit little-endian")
|
|
||||||
plan9 = flag.Bool("plan9", false, "plan9")
|
|
||||||
openbsd = flag.Bool("openbsd", false, "openbsd")
|
|
||||||
netbsd = flag.Bool("netbsd", false, "netbsd")
|
|
||||||
dragonfly = flag.Bool("dragonfly", false, "dragonfly")
|
|
||||||
arm = flag.Bool("arm", false, "arm") // 64-bit value should use (even, odd)-pair
|
|
||||||
tags = flag.String("tags", "", "build tags")
|
|
||||||
filename = flag.String("output", "", "output file name (standard output if omitted)")
|
|
||||||
)
|
|
||||||
|
|
||||||
// cmdLine returns this programs's commandline arguments
|
|
||||||
func cmdLine() string {
|
|
||||||
return "go run mksyscall.go " + strings.Join(os.Args[1:], " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildTags returns build tags
|
|
||||||
func buildTags() string {
|
|
||||||
return *tags
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is function parameter
|
|
||||||
type Param struct {
|
|
||||||
Name string
|
|
||||||
Type string
|
|
||||||
}
|
|
||||||
|
|
||||||
// usage prints the program usage
|
|
||||||
func usage() {
|
|
||||||
fmt.Fprintf(os.Stderr, "usage: go run mksyscall.go [-b32 | -l32] [-tags x,y] [file ...]\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseParamList parses parameter list and returns a slice of parameters
|
|
||||||
func parseParamList(list string) []string {
|
|
||||||
list = strings.TrimSpace(list)
|
|
||||||
if list == "" {
|
|
||||||
return []string{}
|
|
||||||
}
|
|
||||||
return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseParam splits a parameter into name and type
|
|
||||||
func parseParam(p string) Param {
|
|
||||||
ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
|
|
||||||
if ps == nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
return Param{ps[1], ps[2]}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Get the OS and architecture (using GOARCH_TARGET if it exists)
|
|
||||||
goos := os.Getenv("GOOS")
|
|
||||||
if goos == "" {
|
|
||||||
fmt.Fprintln(os.Stderr, "GOOS not defined in environment")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
goarch := os.Getenv("GOARCH_TARGET")
|
|
||||||
if goarch == "" {
|
|
||||||
goarch = os.Getenv("GOARCH")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that we are using the Docker-based build system if we should
|
|
||||||
if goos == "linux" {
|
|
||||||
if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
|
|
||||||
fmt.Fprintf(os.Stderr, "In the Docker-based build system, mksyscall should not be called directly.\n")
|
|
||||||
fmt.Fprintf(os.Stderr, "See README.md\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
flag.Usage = usage
|
|
||||||
flag.Parse()
|
|
||||||
if len(flag.Args()) <= 0 {
|
|
||||||
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
|
|
||||||
usage()
|
|
||||||
}
|
|
||||||
|
|
||||||
endianness := ""
|
|
||||||
if *b32 {
|
|
||||||
endianness = "big-endian"
|
|
||||||
} else if *l32 {
|
|
||||||
endianness = "little-endian"
|
|
||||||
}
|
|
||||||
|
|
||||||
libc := false
|
|
||||||
if goos == "darwin" && (strings.Contains(buildTags(), ",go1.12") || strings.Contains(buildTags(), ",go1.13")) {
|
|
||||||
libc = true
|
|
||||||
}
|
|
||||||
trampolines := map[string]bool{}
|
|
||||||
|
|
||||||
text := ""
|
|
||||||
for _, path := range flag.Args() {
|
|
||||||
file, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
s := bufio.NewScanner(file)
|
|
||||||
for s.Scan() {
|
|
||||||
t := s.Text()
|
|
||||||
t = strings.TrimSpace(t)
|
|
||||||
t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
|
|
||||||
nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
|
|
||||||
if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Line must be of the form
|
|
||||||
// func Open(path string, mode int, perm int) (fd int, errno error)
|
|
||||||
// Split into name, in params, out params.
|
|
||||||
f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*((?i)SYS_[A-Z0-9_]+))?$`).FindStringSubmatch(t)
|
|
||||||
if f == nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
funct, inps, outps, sysname := f[2], f[3], f[4], f[5]
|
|
||||||
|
|
||||||
// ClockGettime doesn't have a syscall number on Darwin, only generate libc wrappers.
|
|
||||||
if goos == "darwin" && !libc && funct == "ClockGettime" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Split argument lists on comma.
|
|
||||||
in := parseParamList(inps)
|
|
||||||
out := parseParamList(outps)
|
|
||||||
|
|
||||||
// Try in vain to keep people from editing this file.
|
|
||||||
// The theory is that they jump into the middle of the file
|
|
||||||
// without reading the header.
|
|
||||||
text += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
|
|
||||||
|
|
||||||
// Go function header.
|
|
||||||
outDecl := ""
|
|
||||||
if len(out) > 0 {
|
|
||||||
outDecl = fmt.Sprintf(" (%s)", strings.Join(out, ", "))
|
|
||||||
}
|
|
||||||
text += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outDecl)
|
|
||||||
|
|
||||||
// Check if err return available
|
|
||||||
errvar := ""
|
|
||||||
for _, param := range out {
|
|
||||||
p := parseParam(param)
|
|
||||||
if p.Type == "error" {
|
|
||||||
errvar = p.Name
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare arguments to Syscall.
|
|
||||||
var args []string
|
|
||||||
n := 0
|
|
||||||
for _, param := range in {
|
|
||||||
p := parseParam(param)
|
|
||||||
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
args = append(args, "uintptr(unsafe.Pointer("+p.Name+"))")
|
|
||||||
} else if p.Type == "string" && errvar != "" {
|
|
||||||
text += fmt.Sprintf("\tvar _p%d *byte\n", n)
|
|
||||||
text += fmt.Sprintf("\t_p%d, %s = BytePtrFromString(%s)\n", n, errvar, p.Name)
|
|
||||||
text += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
|
|
||||||
n++
|
|
||||||
} else if p.Type == "string" {
|
|
||||||
fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
|
|
||||||
text += fmt.Sprintf("\tvar _p%d *byte\n", n)
|
|
||||||
text += fmt.Sprintf("\t_p%d, _ = BytePtrFromString(%s)\n", n, p.Name)
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
|
|
||||||
n++
|
|
||||||
} else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
// Convert slice into pointer, length.
|
|
||||||
// Have to be careful not to take address of &a[0] if len == 0:
|
|
||||||
// pass dummy pointer in that case.
|
|
||||||
// Used to pass nil, but some OSes or simulators reject write(fd, nil, 0).
|
|
||||||
text += fmt.Sprintf("\tvar _p%d unsafe.Pointer\n", n)
|
|
||||||
text += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = unsafe.Pointer(&%s[0])\n\t}", p.Name, n, p.Name)
|
|
||||||
text += fmt.Sprintf(" else {\n\t\t_p%d = unsafe.Pointer(&_zero)\n\t}\n", n)
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(_p%d)", n), fmt.Sprintf("uintptr(len(%s))", p.Name))
|
|
||||||
n++
|
|
||||||
} else if p.Type == "int64" && (*openbsd || *netbsd) {
|
|
||||||
args = append(args, "0")
|
|
||||||
if endianness == "big-endian" {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
} else if endianness == "little-endian" {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
}
|
|
||||||
} else if p.Type == "int64" && *dragonfly {
|
|
||||||
if regexp.MustCompile(`^(?i)extp(read|write)`).FindStringSubmatch(funct) == nil {
|
|
||||||
args = append(args, "0")
|
|
||||||
}
|
|
||||||
if endianness == "big-endian" {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
} else if endianness == "little-endian" {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
}
|
|
||||||
} else if (p.Type == "int64" || p.Type == "uint64") && endianness != "" {
|
|
||||||
if len(args)%2 == 1 && *arm {
|
|
||||||
// arm abi specifies 64-bit argument uses
|
|
||||||
// (even, odd) pair
|
|
||||||
args = append(args, "0")
|
|
||||||
}
|
|
||||||
if endianness == "big-endian" {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine which form to use; pad args with zeros.
|
|
||||||
asm := "Syscall"
|
|
||||||
if nonblock != nil {
|
|
||||||
if errvar == "" && goos == "linux" {
|
|
||||||
asm = "RawSyscallNoError"
|
|
||||||
} else {
|
|
||||||
asm = "RawSyscall"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if errvar == "" && goos == "linux" {
|
|
||||||
asm = "SyscallNoError"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(args) <= 3 {
|
|
||||||
for len(args) < 3 {
|
|
||||||
args = append(args, "0")
|
|
||||||
}
|
|
||||||
} else if len(args) <= 6 {
|
|
||||||
asm += "6"
|
|
||||||
for len(args) < 6 {
|
|
||||||
args = append(args, "0")
|
|
||||||
}
|
|
||||||
} else if len(args) <= 9 {
|
|
||||||
asm += "9"
|
|
||||||
for len(args) < 9 {
|
|
||||||
args = append(args, "0")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s:%s too many arguments to system call\n", path, funct)
|
|
||||||
}
|
|
||||||
|
|
||||||
// System call number.
|
|
||||||
if sysname == "" {
|
|
||||||
sysname = "SYS_" + funct
|
|
||||||
sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`)
|
|
||||||
sysname = strings.ToUpper(sysname)
|
|
||||||
}
|
|
||||||
|
|
||||||
var libcFn string
|
|
||||||
if libc {
|
|
||||||
asm = "syscall_" + strings.ToLower(asm[:1]) + asm[1:] // internal syscall call
|
|
||||||
sysname = strings.TrimPrefix(sysname, "SYS_") // remove SYS_
|
|
||||||
sysname = strings.ToLower(sysname) // lowercase
|
|
||||||
libcFn = sysname
|
|
||||||
sysname = "funcPC(libc_" + sysname + "_trampoline)"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actual call.
|
|
||||||
arglist := strings.Join(args, ", ")
|
|
||||||
call := fmt.Sprintf("%s(%s, %s)", asm, sysname, arglist)
|
|
||||||
|
|
||||||
// Assign return values.
|
|
||||||
body := ""
|
|
||||||
ret := []string{"_", "_", "_"}
|
|
||||||
doErrno := false
|
|
||||||
for i := 0; i < len(out); i++ {
|
|
||||||
p := parseParam(out[i])
|
|
||||||
reg := ""
|
|
||||||
if p.Name == "err" && !*plan9 {
|
|
||||||
reg = "e1"
|
|
||||||
ret[2] = reg
|
|
||||||
doErrno = true
|
|
||||||
} else if p.Name == "err" && *plan9 {
|
|
||||||
ret[0] = "r0"
|
|
||||||
ret[2] = "e1"
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
reg = fmt.Sprintf("r%d", i)
|
|
||||||
ret[i] = reg
|
|
||||||
}
|
|
||||||
if p.Type == "bool" {
|
|
||||||
reg = fmt.Sprintf("%s != 0", reg)
|
|
||||||
}
|
|
||||||
if p.Type == "int64" && endianness != "" {
|
|
||||||
// 64-bit number in r1:r0 or r0:r1.
|
|
||||||
if i+2 > len(out) {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s:%s not enough registers for int64 return\n", path, funct)
|
|
||||||
}
|
|
||||||
if endianness == "big-endian" {
|
|
||||||
reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i, i+1)
|
|
||||||
} else {
|
|
||||||
reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i+1, i)
|
|
||||||
}
|
|
||||||
ret[i] = fmt.Sprintf("r%d", i)
|
|
||||||
ret[i+1] = fmt.Sprintf("r%d", i+1)
|
|
||||||
}
|
|
||||||
if reg != "e1" || *plan9 {
|
|
||||||
body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ret[0] == "_" && ret[1] == "_" && ret[2] == "_" {
|
|
||||||
text += fmt.Sprintf("\t%s\n", call)
|
|
||||||
} else {
|
|
||||||
if errvar == "" && goos == "linux" {
|
|
||||||
// raw syscall without error on Linux, see golang.org/issue/22924
|
|
||||||
text += fmt.Sprintf("\t%s, %s := %s\n", ret[0], ret[1], call)
|
|
||||||
} else {
|
|
||||||
text += fmt.Sprintf("\t%s, %s, %s := %s\n", ret[0], ret[1], ret[2], call)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
text += body
|
|
||||||
|
|
||||||
if *plan9 && ret[2] == "e1" {
|
|
||||||
text += "\tif int32(r0) == -1 {\n"
|
|
||||||
text += "\t\terr = e1\n"
|
|
||||||
text += "\t}\n"
|
|
||||||
} else if doErrno {
|
|
||||||
text += "\tif e1 != 0 {\n"
|
|
||||||
text += "\t\terr = errnoErr(e1)\n"
|
|
||||||
text += "\t}\n"
|
|
||||||
}
|
|
||||||
text += "\treturn\n"
|
|
||||||
text += "}\n\n"
|
|
||||||
|
|
||||||
if libc && !trampolines[libcFn] {
|
|
||||||
// some system calls share a trampoline, like read and readlen.
|
|
||||||
trampolines[libcFn] = true
|
|
||||||
// Declare assembly trampoline.
|
|
||||||
text += fmt.Sprintf("func libc_%s_trampoline()\n", libcFn)
|
|
||||||
// Assembly trampoline calls the libc_* function, which this magic
|
|
||||||
// redirects to use the function from libSystem.
|
|
||||||
text += fmt.Sprintf("//go:linkname libc_%s libc_%s\n", libcFn, libcFn)
|
|
||||||
text += fmt.Sprintf("//go:cgo_import_dynamic libc_%s %s \"/usr/lib/libSystem.B.dylib\"\n", libcFn, libcFn)
|
|
||||||
text += "\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := s.Err(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
file.Close()
|
|
||||||
}
|
|
||||||
fmt.Printf(srcTemplate, cmdLine(), buildTags(), text)
|
|
||||||
}
|
|
||||||
|
|
||||||
const srcTemplate = `// %s
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ syscall.Errno
|
|
||||||
|
|
||||||
%s
|
|
||||||
`
|
|
@ -1,415 +0,0 @@
|
|||||||
// Copyright 2019 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.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
/*
|
|
||||||
This program reads a file containing function prototypes
|
|
||||||
(like syscall_aix.go) and generates system call bodies.
|
|
||||||
The prototypes are marked by lines beginning with "//sys"
|
|
||||||
and read like func declarations if //sys is replaced by func, but:
|
|
||||||
* The parameter lists must give a name for each argument.
|
|
||||||
This includes return parameters.
|
|
||||||
* The parameter lists must give a type for each argument:
|
|
||||||
the (x, y, z int) shorthand is not allowed.
|
|
||||||
* If the return parameter is an error number, it must be named err.
|
|
||||||
* If go func name needs to be different than its libc name,
|
|
||||||
* or the function is not in libc, name could be specified
|
|
||||||
* at the end, after "=" sign, like
|
|
||||||
//sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
|
|
||||||
*/
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
b32 = flag.Bool("b32", false, "32bit big-endian")
|
|
||||||
l32 = flag.Bool("l32", false, "32bit little-endian")
|
|
||||||
aix = flag.Bool("aix", false, "aix")
|
|
||||||
tags = flag.String("tags", "", "build tags")
|
|
||||||
)
|
|
||||||
|
|
||||||
// cmdLine returns this programs's commandline arguments
|
|
||||||
func cmdLine() string {
|
|
||||||
return "go run mksyscall_aix_ppc.go " + strings.Join(os.Args[1:], " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildTags returns build tags
|
|
||||||
func buildTags() string {
|
|
||||||
return *tags
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is function parameter
|
|
||||||
type Param struct {
|
|
||||||
Name string
|
|
||||||
Type string
|
|
||||||
}
|
|
||||||
|
|
||||||
// usage prints the program usage
|
|
||||||
func usage() {
|
|
||||||
fmt.Fprintf(os.Stderr, "usage: go run mksyscall_aix_ppc.go [-b32 | -l32] [-tags x,y] [file ...]\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseParamList parses parameter list and returns a slice of parameters
|
|
||||||
func parseParamList(list string) []string {
|
|
||||||
list = strings.TrimSpace(list)
|
|
||||||
if list == "" {
|
|
||||||
return []string{}
|
|
||||||
}
|
|
||||||
return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseParam splits a parameter into name and type
|
|
||||||
func parseParam(p string) Param {
|
|
||||||
ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
|
|
||||||
if ps == nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
return Param{ps[1], ps[2]}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Usage = usage
|
|
||||||
flag.Parse()
|
|
||||||
if len(flag.Args()) <= 0 {
|
|
||||||
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
|
|
||||||
usage()
|
|
||||||
}
|
|
||||||
|
|
||||||
endianness := ""
|
|
||||||
if *b32 {
|
|
||||||
endianness = "big-endian"
|
|
||||||
} else if *l32 {
|
|
||||||
endianness = "little-endian"
|
|
||||||
}
|
|
||||||
|
|
||||||
pack := ""
|
|
||||||
text := ""
|
|
||||||
cExtern := "/*\n#include <stdint.h>\n#include <stddef.h>\n"
|
|
||||||
for _, path := range flag.Args() {
|
|
||||||
file, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
s := bufio.NewScanner(file)
|
|
||||||
for s.Scan() {
|
|
||||||
t := s.Text()
|
|
||||||
t = strings.TrimSpace(t)
|
|
||||||
t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
|
|
||||||
if p := regexp.MustCompile(`^package (\S+)$`).FindStringSubmatch(t); p != nil && pack == "" {
|
|
||||||
pack = p[1]
|
|
||||||
}
|
|
||||||
nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
|
|
||||||
if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Line must be of the form
|
|
||||||
// func Open(path string, mode int, perm int) (fd int, err error)
|
|
||||||
// Split into name, in params, out params.
|
|
||||||
f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$`).FindStringSubmatch(t)
|
|
||||||
if f == nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
funct, inps, outps, modname, sysname := f[2], f[3], f[4], f[5], f[6]
|
|
||||||
|
|
||||||
// Split argument lists on comma.
|
|
||||||
in := parseParamList(inps)
|
|
||||||
out := parseParamList(outps)
|
|
||||||
|
|
||||||
inps = strings.Join(in, ", ")
|
|
||||||
outps = strings.Join(out, ", ")
|
|
||||||
|
|
||||||
// Try in vain to keep people from editing this file.
|
|
||||||
// The theory is that they jump into the middle of the file
|
|
||||||
// without reading the header.
|
|
||||||
text += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
|
|
||||||
|
|
||||||
// Check if value return, err return available
|
|
||||||
errvar := ""
|
|
||||||
retvar := ""
|
|
||||||
rettype := ""
|
|
||||||
for _, param := range out {
|
|
||||||
p := parseParam(param)
|
|
||||||
if p.Type == "error" {
|
|
||||||
errvar = p.Name
|
|
||||||
} else {
|
|
||||||
retvar = p.Name
|
|
||||||
rettype = p.Type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// System call name.
|
|
||||||
if sysname == "" {
|
|
||||||
sysname = funct
|
|
||||||
}
|
|
||||||
sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`)
|
|
||||||
sysname = strings.ToLower(sysname) // All libc functions are lowercase.
|
|
||||||
|
|
||||||
cRettype := ""
|
|
||||||
if rettype == "unsafe.Pointer" {
|
|
||||||
cRettype = "uintptr_t"
|
|
||||||
} else if rettype == "uintptr" {
|
|
||||||
cRettype = "uintptr_t"
|
|
||||||
} else if regexp.MustCompile(`^_`).FindStringSubmatch(rettype) != nil {
|
|
||||||
cRettype = "uintptr_t"
|
|
||||||
} else if rettype == "int" {
|
|
||||||
cRettype = "int"
|
|
||||||
} else if rettype == "int32" {
|
|
||||||
cRettype = "int"
|
|
||||||
} else if rettype == "int64" {
|
|
||||||
cRettype = "long long"
|
|
||||||
} else if rettype == "uint32" {
|
|
||||||
cRettype = "unsigned int"
|
|
||||||
} else if rettype == "uint64" {
|
|
||||||
cRettype = "unsigned long long"
|
|
||||||
} else {
|
|
||||||
cRettype = "int"
|
|
||||||
}
|
|
||||||
if sysname == "exit" {
|
|
||||||
cRettype = "void"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change p.Types to c
|
|
||||||
var cIn []string
|
|
||||||
for _, param := range in {
|
|
||||||
p := parseParam(param)
|
|
||||||
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if p.Type == "string" {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
cIn = append(cIn, "uintptr_t", "size_t")
|
|
||||||
} else if p.Type == "unsafe.Pointer" {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if p.Type == "uintptr" {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if p.Type == "int" {
|
|
||||||
cIn = append(cIn, "int")
|
|
||||||
} else if p.Type == "int32" {
|
|
||||||
cIn = append(cIn, "int")
|
|
||||||
} else if p.Type == "int64" {
|
|
||||||
cIn = append(cIn, "long long")
|
|
||||||
} else if p.Type == "uint32" {
|
|
||||||
cIn = append(cIn, "unsigned int")
|
|
||||||
} else if p.Type == "uint64" {
|
|
||||||
cIn = append(cIn, "unsigned long long")
|
|
||||||
} else {
|
|
||||||
cIn = append(cIn, "int")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if funct != "fcntl" && funct != "FcntlInt" && funct != "readlen" && funct != "writelen" {
|
|
||||||
if sysname == "select" {
|
|
||||||
// select is a keyword of Go. Its name is
|
|
||||||
// changed to c_select.
|
|
||||||
cExtern += "#define c_select select\n"
|
|
||||||
}
|
|
||||||
// Imports of system calls from libc
|
|
||||||
cExtern += fmt.Sprintf("%s %s", cRettype, sysname)
|
|
||||||
cIn := strings.Join(cIn, ", ")
|
|
||||||
cExtern += fmt.Sprintf("(%s);\n", cIn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// So file name.
|
|
||||||
if *aix {
|
|
||||||
if modname == "" {
|
|
||||||
modname = "libc.a/shr_64.o"
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s: only syscall using libc are available\n", funct)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strconvfunc := "C.CString"
|
|
||||||
|
|
||||||
// Go function header.
|
|
||||||
if outps != "" {
|
|
||||||
outps = fmt.Sprintf(" (%s)", outps)
|
|
||||||
}
|
|
||||||
if text != "" {
|
|
||||||
text += "\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
text += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outps)
|
|
||||||
|
|
||||||
// Prepare arguments to Syscall.
|
|
||||||
var args []string
|
|
||||||
n := 0
|
|
||||||
argN := 0
|
|
||||||
for _, param := range in {
|
|
||||||
p := parseParam(param)
|
|
||||||
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
args = append(args, "C.uintptr_t(uintptr(unsafe.Pointer("+p.Name+")))")
|
|
||||||
} else if p.Type == "string" && errvar != "" {
|
|
||||||
text += fmt.Sprintf("\t_p%d := uintptr(unsafe.Pointer(%s(%s)))\n", n, strconvfunc, p.Name)
|
|
||||||
args = append(args, fmt.Sprintf("C.uintptr_t(_p%d)", n))
|
|
||||||
n++
|
|
||||||
} else if p.Type == "string" {
|
|
||||||
fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
|
|
||||||
text += fmt.Sprintf("\t_p%d := uintptr(unsafe.Pointer(%s(%s)))\n", n, strconvfunc, p.Name)
|
|
||||||
args = append(args, fmt.Sprintf("C.uintptr_t(_p%d)", n))
|
|
||||||
n++
|
|
||||||
} else if m := regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type); m != nil {
|
|
||||||
// Convert slice into pointer, length.
|
|
||||||
// Have to be careful not to take address of &a[0] if len == 0:
|
|
||||||
// pass nil in that case.
|
|
||||||
text += fmt.Sprintf("\tvar _p%d *%s\n", n, m[1])
|
|
||||||
text += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = &%s[0]\n\t}\n", p.Name, n, p.Name)
|
|
||||||
args = append(args, fmt.Sprintf("C.uintptr_t(uintptr(unsafe.Pointer(_p%d)))", n))
|
|
||||||
n++
|
|
||||||
text += fmt.Sprintf("\tvar _p%d int\n", n)
|
|
||||||
text += fmt.Sprintf("\t_p%d = len(%s)\n", n, p.Name)
|
|
||||||
args = append(args, fmt.Sprintf("C.size_t(_p%d)", n))
|
|
||||||
n++
|
|
||||||
} else if p.Type == "int64" && endianness != "" {
|
|
||||||
if endianness == "big-endian" {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
|
|
||||||
}
|
|
||||||
n++
|
|
||||||
} else if p.Type == "bool" {
|
|
||||||
text += fmt.Sprintf("\tvar _p%d uint32\n", n)
|
|
||||||
text += fmt.Sprintf("\tif %s {\n\t\t_p%d = 1\n\t} else {\n\t\t_p%d = 0\n\t}\n", p.Name, n, n)
|
|
||||||
args = append(args, fmt.Sprintf("_p%d", n))
|
|
||||||
} else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
args = append(args, fmt.Sprintf("C.uintptr_t(uintptr(%s))", p.Name))
|
|
||||||
} else if p.Type == "unsafe.Pointer" {
|
|
||||||
args = append(args, fmt.Sprintf("C.uintptr_t(uintptr(%s))", p.Name))
|
|
||||||
} else if p.Type == "int" {
|
|
||||||
if (argN == 2) && ((funct == "readlen") || (funct == "writelen")) {
|
|
||||||
args = append(args, fmt.Sprintf("C.size_t(%s)", p.Name))
|
|
||||||
} else if argN == 0 && funct == "fcntl" {
|
|
||||||
args = append(args, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
|
|
||||||
} else if (argN == 2) && ((funct == "fcntl") || (funct == "FcntlInt")) {
|
|
||||||
args = append(args, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("C.int(%s)", p.Name))
|
|
||||||
}
|
|
||||||
} else if p.Type == "int32" {
|
|
||||||
args = append(args, fmt.Sprintf("C.int(%s)", p.Name))
|
|
||||||
} else if p.Type == "int64" {
|
|
||||||
args = append(args, fmt.Sprintf("C.longlong(%s)", p.Name))
|
|
||||||
} else if p.Type == "uint32" {
|
|
||||||
args = append(args, fmt.Sprintf("C.uint(%s)", p.Name))
|
|
||||||
} else if p.Type == "uint64" {
|
|
||||||
args = append(args, fmt.Sprintf("C.ulonglong(%s)", p.Name))
|
|
||||||
} else if p.Type == "uintptr" {
|
|
||||||
args = append(args, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("C.int(%s)", p.Name))
|
|
||||||
}
|
|
||||||
argN++
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actual call.
|
|
||||||
arglist := strings.Join(args, ", ")
|
|
||||||
call := ""
|
|
||||||
if sysname == "exit" {
|
|
||||||
if errvar != "" {
|
|
||||||
call += "er :="
|
|
||||||
} else {
|
|
||||||
call += ""
|
|
||||||
}
|
|
||||||
} else if errvar != "" {
|
|
||||||
call += "r0,er :="
|
|
||||||
} else if retvar != "" {
|
|
||||||
call += "r0,_ :="
|
|
||||||
} else {
|
|
||||||
call += ""
|
|
||||||
}
|
|
||||||
if sysname == "select" {
|
|
||||||
// select is a keyword of Go. Its name is
|
|
||||||
// changed to c_select.
|
|
||||||
call += fmt.Sprintf("C.c_%s(%s)", sysname, arglist)
|
|
||||||
} else {
|
|
||||||
call += fmt.Sprintf("C.%s(%s)", sysname, arglist)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign return values.
|
|
||||||
body := ""
|
|
||||||
for i := 0; i < len(out); i++ {
|
|
||||||
p := parseParam(out[i])
|
|
||||||
reg := ""
|
|
||||||
if p.Name == "err" {
|
|
||||||
reg = "e1"
|
|
||||||
} else {
|
|
||||||
reg = "r0"
|
|
||||||
}
|
|
||||||
if reg != "e1" {
|
|
||||||
body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify return
|
|
||||||
if sysname != "exit" && errvar != "" {
|
|
||||||
if regexp.MustCompile(`^uintptr`).FindStringSubmatch(cRettype) != nil {
|
|
||||||
body += "\tif (uintptr(r0) ==^uintptr(0) && er != nil) {\n"
|
|
||||||
body += fmt.Sprintf("\t\t%s = er\n", errvar)
|
|
||||||
body += "\t}\n"
|
|
||||||
} else {
|
|
||||||
body += "\tif (r0 ==-1 && er != nil) {\n"
|
|
||||||
body += fmt.Sprintf("\t\t%s = er\n", errvar)
|
|
||||||
body += "\t}\n"
|
|
||||||
}
|
|
||||||
} else if errvar != "" {
|
|
||||||
body += "\tif (er != nil) {\n"
|
|
||||||
body += fmt.Sprintf("\t\t%s = er\n", errvar)
|
|
||||||
body += "\t}\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
text += fmt.Sprintf("\t%s\n", call)
|
|
||||||
text += body
|
|
||||||
|
|
||||||
text += "\treturn\n"
|
|
||||||
text += "}\n"
|
|
||||||
}
|
|
||||||
if err := s.Err(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
file.Close()
|
|
||||||
}
|
|
||||||
imp := ""
|
|
||||||
if pack != "unix" {
|
|
||||||
imp = "import \"golang.org/x/sys/unix\"\n"
|
|
||||||
|
|
||||||
}
|
|
||||||
fmt.Printf(srcTemplate, cmdLine(), buildTags(), pack, cExtern, imp, text)
|
|
||||||
}
|
|
||||||
|
|
||||||
const srcTemplate = `// %s
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s
|
|
||||||
|
|
||||||
package %s
|
|
||||||
|
|
||||||
|
|
||||||
%s
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
%s
|
|
||||||
|
|
||||||
%s
|
|
||||||
`
|
|
@ -1,614 +0,0 @@
|
|||||||
// Copyright 2019 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.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
/*
|
|
||||||
This program reads a file containing function prototypes
|
|
||||||
(like syscall_aix.go) and generates system call bodies.
|
|
||||||
The prototypes are marked by lines beginning with "//sys"
|
|
||||||
and read like func declarations if //sys is replaced by func, but:
|
|
||||||
* The parameter lists must give a name for each argument.
|
|
||||||
This includes return parameters.
|
|
||||||
* The parameter lists must give a type for each argument:
|
|
||||||
the (x, y, z int) shorthand is not allowed.
|
|
||||||
* If the return parameter is an error number, it must be named err.
|
|
||||||
* If go func name needs to be different than its libc name,
|
|
||||||
* or the function is not in libc, name could be specified
|
|
||||||
* at the end, after "=" sign, like
|
|
||||||
//sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
|
|
||||||
|
|
||||||
|
|
||||||
This program will generate three files and handle both gc and gccgo implementation:
|
|
||||||
- zsyscall_aix_ppc64.go: the common part of each implementation (error handler, pointer creation)
|
|
||||||
- zsyscall_aix_ppc64_gc.go: gc part with //go_cgo_import_dynamic and a call to syscall6
|
|
||||||
- zsyscall_aix_ppc64_gccgo.go: gccgo part with C function and conversion to C type.
|
|
||||||
|
|
||||||
The generated code looks like this
|
|
||||||
|
|
||||||
zsyscall_aix_ppc64.go
|
|
||||||
func asyscall(...) (n int, err error) {
|
|
||||||
// Pointer Creation
|
|
||||||
r1, e1 := callasyscall(...)
|
|
||||||
// Type Conversion
|
|
||||||
// Error Handler
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
zsyscall_aix_ppc64_gc.go
|
|
||||||
//go:cgo_import_dynamic libc_asyscall asyscall "libc.a/shr_64.o"
|
|
||||||
//go:linkname libc_asyscall libc_asyscall
|
|
||||||
var asyscall syscallFunc
|
|
||||||
|
|
||||||
func callasyscall(...) (r1 uintptr, e1 Errno) {
|
|
||||||
r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_asyscall)), "nb_args", ... )
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
zsyscall_aix_ppc64_ggcgo.go
|
|
||||||
|
|
||||||
// int asyscall(...)
|
|
||||||
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
func callasyscall(...) (r1 uintptr, e1 Errno) {
|
|
||||||
r1 = uintptr(C.asyscall(...))
|
|
||||||
e1 = syscall.GetErrno()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
b32 = flag.Bool("b32", false, "32bit big-endian")
|
|
||||||
l32 = flag.Bool("l32", false, "32bit little-endian")
|
|
||||||
aix = flag.Bool("aix", false, "aix")
|
|
||||||
tags = flag.String("tags", "", "build tags")
|
|
||||||
)
|
|
||||||
|
|
||||||
// cmdLine returns this programs's commandline arguments
|
|
||||||
func cmdLine() string {
|
|
||||||
return "go run mksyscall_aix_ppc64.go " + strings.Join(os.Args[1:], " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildTags returns build tags
|
|
||||||
func buildTags() string {
|
|
||||||
return *tags
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is function parameter
|
|
||||||
type Param struct {
|
|
||||||
Name string
|
|
||||||
Type string
|
|
||||||
}
|
|
||||||
|
|
||||||
// usage prints the program usage
|
|
||||||
func usage() {
|
|
||||||
fmt.Fprintf(os.Stderr, "usage: go run mksyscall_aix_ppc64.go [-b32 | -l32] [-tags x,y] [file ...]\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseParamList parses parameter list and returns a slice of parameters
|
|
||||||
func parseParamList(list string) []string {
|
|
||||||
list = strings.TrimSpace(list)
|
|
||||||
if list == "" {
|
|
||||||
return []string{}
|
|
||||||
}
|
|
||||||
return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseParam splits a parameter into name and type
|
|
||||||
func parseParam(p string) Param {
|
|
||||||
ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
|
|
||||||
if ps == nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
return Param{ps[1], ps[2]}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Usage = usage
|
|
||||||
flag.Parse()
|
|
||||||
if len(flag.Args()) <= 0 {
|
|
||||||
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
|
|
||||||
usage()
|
|
||||||
}
|
|
||||||
|
|
||||||
endianness := ""
|
|
||||||
if *b32 {
|
|
||||||
endianness = "big-endian"
|
|
||||||
} else if *l32 {
|
|
||||||
endianness = "little-endian"
|
|
||||||
}
|
|
||||||
|
|
||||||
pack := ""
|
|
||||||
// GCCGO
|
|
||||||
textgccgo := ""
|
|
||||||
cExtern := "/*\n#include <stdint.h>\n"
|
|
||||||
// GC
|
|
||||||
textgc := ""
|
|
||||||
dynimports := ""
|
|
||||||
linknames := ""
|
|
||||||
var vars []string
|
|
||||||
// COMMON
|
|
||||||
textcommon := ""
|
|
||||||
for _, path := range flag.Args() {
|
|
||||||
file, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
s := bufio.NewScanner(file)
|
|
||||||
for s.Scan() {
|
|
||||||
t := s.Text()
|
|
||||||
t = strings.TrimSpace(t)
|
|
||||||
t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
|
|
||||||
if p := regexp.MustCompile(`^package (\S+)$`).FindStringSubmatch(t); p != nil && pack == "" {
|
|
||||||
pack = p[1]
|
|
||||||
}
|
|
||||||
nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
|
|
||||||
if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Line must be of the form
|
|
||||||
// func Open(path string, mode int, perm int) (fd int, err error)
|
|
||||||
// Split into name, in params, out params.
|
|
||||||
f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$`).FindStringSubmatch(t)
|
|
||||||
if f == nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
funct, inps, outps, modname, sysname := f[2], f[3], f[4], f[5], f[6]
|
|
||||||
|
|
||||||
// Split argument lists on comma.
|
|
||||||
in := parseParamList(inps)
|
|
||||||
out := parseParamList(outps)
|
|
||||||
|
|
||||||
inps = strings.Join(in, ", ")
|
|
||||||
outps = strings.Join(out, ", ")
|
|
||||||
|
|
||||||
if sysname == "" {
|
|
||||||
sysname = funct
|
|
||||||
}
|
|
||||||
|
|
||||||
onlyCommon := false
|
|
||||||
if funct == "readlen" || funct == "writelen" || funct == "FcntlInt" || funct == "FcntlFlock" {
|
|
||||||
// This function call another syscall which is already implemented.
|
|
||||||
// Therefore, the gc and gccgo part must not be generated.
|
|
||||||
onlyCommon = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try in vain to keep people from editing this file.
|
|
||||||
// The theory is that they jump into the middle of the file
|
|
||||||
// without reading the header.
|
|
||||||
|
|
||||||
textcommon += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
|
|
||||||
if !onlyCommon {
|
|
||||||
textgccgo += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
|
|
||||||
textgc += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if value return, err return available
|
|
||||||
errvar := ""
|
|
||||||
rettype := ""
|
|
||||||
for _, param := range out {
|
|
||||||
p := parseParam(param)
|
|
||||||
if p.Type == "error" {
|
|
||||||
errvar = p.Name
|
|
||||||
} else {
|
|
||||||
rettype = p.Type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`)
|
|
||||||
sysname = strings.ToLower(sysname) // All libc functions are lowercase.
|
|
||||||
|
|
||||||
// GCCGO Prototype return type
|
|
||||||
cRettype := ""
|
|
||||||
if rettype == "unsafe.Pointer" {
|
|
||||||
cRettype = "uintptr_t"
|
|
||||||
} else if rettype == "uintptr" {
|
|
||||||
cRettype = "uintptr_t"
|
|
||||||
} else if regexp.MustCompile(`^_`).FindStringSubmatch(rettype) != nil {
|
|
||||||
cRettype = "uintptr_t"
|
|
||||||
} else if rettype == "int" {
|
|
||||||
cRettype = "int"
|
|
||||||
} else if rettype == "int32" {
|
|
||||||
cRettype = "int"
|
|
||||||
} else if rettype == "int64" {
|
|
||||||
cRettype = "long long"
|
|
||||||
} else if rettype == "uint32" {
|
|
||||||
cRettype = "unsigned int"
|
|
||||||
} else if rettype == "uint64" {
|
|
||||||
cRettype = "unsigned long long"
|
|
||||||
} else {
|
|
||||||
cRettype = "int"
|
|
||||||
}
|
|
||||||
if sysname == "exit" {
|
|
||||||
cRettype = "void"
|
|
||||||
}
|
|
||||||
|
|
||||||
// GCCGO Prototype arguments type
|
|
||||||
var cIn []string
|
|
||||||
for i, param := range in {
|
|
||||||
p := parseParam(param)
|
|
||||||
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if p.Type == "string" {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
cIn = append(cIn, "uintptr_t", "size_t")
|
|
||||||
} else if p.Type == "unsafe.Pointer" {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if p.Type == "uintptr" {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if p.Type == "int" {
|
|
||||||
if (i == 0 || i == 2) && funct == "fcntl" {
|
|
||||||
// These fcntl arguments needs to be uintptr to be able to call FcntlInt and FcntlFlock
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else {
|
|
||||||
cIn = append(cIn, "int")
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if p.Type == "int32" {
|
|
||||||
cIn = append(cIn, "int")
|
|
||||||
} else if p.Type == "int64" {
|
|
||||||
cIn = append(cIn, "long long")
|
|
||||||
} else if p.Type == "uint32" {
|
|
||||||
cIn = append(cIn, "unsigned int")
|
|
||||||
} else if p.Type == "uint64" {
|
|
||||||
cIn = append(cIn, "unsigned long long")
|
|
||||||
} else {
|
|
||||||
cIn = append(cIn, "int")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !onlyCommon {
|
|
||||||
// GCCGO Prototype Generation
|
|
||||||
// Imports of system calls from libc
|
|
||||||
if sysname == "select" {
|
|
||||||
// select is a keyword of Go. Its name is
|
|
||||||
// changed to c_select.
|
|
||||||
cExtern += "#define c_select select\n"
|
|
||||||
}
|
|
||||||
cExtern += fmt.Sprintf("%s %s", cRettype, sysname)
|
|
||||||
cIn := strings.Join(cIn, ", ")
|
|
||||||
cExtern += fmt.Sprintf("(%s);\n", cIn)
|
|
||||||
}
|
|
||||||
// GC Library name
|
|
||||||
if modname == "" {
|
|
||||||
modname = "libc.a/shr_64.o"
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s: only syscall using libc are available\n", funct)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
sysvarname := fmt.Sprintf("libc_%s", sysname)
|
|
||||||
|
|
||||||
if !onlyCommon {
|
|
||||||
// GC Runtime import of function to allow cross-platform builds.
|
|
||||||
dynimports += fmt.Sprintf("//go:cgo_import_dynamic %s %s \"%s\"\n", sysvarname, sysname, modname)
|
|
||||||
// GC Link symbol to proc address variable.
|
|
||||||
linknames += fmt.Sprintf("//go:linkname %s %s\n", sysvarname, sysvarname)
|
|
||||||
// GC Library proc address variable.
|
|
||||||
vars = append(vars, sysvarname)
|
|
||||||
}
|
|
||||||
|
|
||||||
strconvfunc := "BytePtrFromString"
|
|
||||||
strconvtype := "*byte"
|
|
||||||
|
|
||||||
// Go function header.
|
|
||||||
if outps != "" {
|
|
||||||
outps = fmt.Sprintf(" (%s)", outps)
|
|
||||||
}
|
|
||||||
if textcommon != "" {
|
|
||||||
textcommon += "\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
textcommon += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outps)
|
|
||||||
|
|
||||||
// Prepare arguments tocall.
|
|
||||||
var argscommon []string // Arguments in the common part
|
|
||||||
var argscall []string // Arguments for call prototype
|
|
||||||
var argsgc []string // Arguments for gc call (with syscall6)
|
|
||||||
var argsgccgo []string // Arguments for gccgo call (with C.name_of_syscall)
|
|
||||||
n := 0
|
|
||||||
argN := 0
|
|
||||||
for _, param := range in {
|
|
||||||
p := parseParam(param)
|
|
||||||
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(%s))", p.Name))
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
|
|
||||||
argsgc = append(argsgc, p.Name)
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
|
|
||||||
} else if p.Type == "string" && errvar != "" {
|
|
||||||
textcommon += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
|
|
||||||
textcommon += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name)
|
|
||||||
textcommon += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
|
|
||||||
|
|
||||||
argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
|
|
||||||
argscall = append(argscall, fmt.Sprintf("_p%d uintptr ", n))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("_p%d", n))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n))
|
|
||||||
n++
|
|
||||||
} else if p.Type == "string" {
|
|
||||||
fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
|
|
||||||
textcommon += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
|
|
||||||
textcommon += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name)
|
|
||||||
textcommon += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
|
|
||||||
|
|
||||||
argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
|
|
||||||
argscall = append(argscall, fmt.Sprintf("_p%d uintptr", n))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("_p%d", n))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n))
|
|
||||||
n++
|
|
||||||
} else if m := regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type); m != nil {
|
|
||||||
// Convert slice into pointer, length.
|
|
||||||
// Have to be careful not to take address of &a[0] if len == 0:
|
|
||||||
// pass nil in that case.
|
|
||||||
textcommon += fmt.Sprintf("\tvar _p%d *%s\n", n, m[1])
|
|
||||||
textcommon += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = &%s[0]\n\t}\n", p.Name, n, p.Name)
|
|
||||||
argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n), fmt.Sprintf("len(%s)", p.Name))
|
|
||||||
argscall = append(argscall, fmt.Sprintf("_p%d uintptr", n), fmt.Sprintf("_lenp%d int", n))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("_p%d", n), fmt.Sprintf("uintptr(_lenp%d)", n))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n), fmt.Sprintf("C.size_t(_lenp%d)", n))
|
|
||||||
n++
|
|
||||||
} else if p.Type == "int64" && endianness != "" {
|
|
||||||
fmt.Fprintf(os.Stderr, path+":"+funct+" uses int64 with 32 bits mode. Case not yet implemented\n")
|
|
||||||
} else if p.Type == "bool" {
|
|
||||||
fmt.Fprintf(os.Stderr, path+":"+funct+" uses bool. Case not yet implemented\n")
|
|
||||||
} else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil || p.Type == "unsafe.Pointer" {
|
|
||||||
argscommon = append(argscommon, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
|
|
||||||
argsgc = append(argsgc, p.Name)
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
|
|
||||||
} else if p.Type == "int" {
|
|
||||||
if (argN == 0 || argN == 2) && ((funct == "fcntl") || (funct == "FcntlInt") || (funct == "FcntlFlock")) {
|
|
||||||
// These fcntl arguments need to be uintptr to be able to call FcntlInt and FcntlFlock
|
|
||||||
argscommon = append(argscommon, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
|
|
||||||
argsgc = append(argsgc, p.Name)
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
|
|
||||||
|
|
||||||
} else {
|
|
||||||
argscommon = append(argscommon, p.Name)
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s int", p.Name))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name))
|
|
||||||
}
|
|
||||||
} else if p.Type == "int32" {
|
|
||||||
argscommon = append(argscommon, p.Name)
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s int32", p.Name))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name))
|
|
||||||
} else if p.Type == "int64" {
|
|
||||||
argscommon = append(argscommon, p.Name)
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s int64", p.Name))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.longlong(%s)", p.Name))
|
|
||||||
} else if p.Type == "uint32" {
|
|
||||||
argscommon = append(argscommon, p.Name)
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s uint32", p.Name))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uint(%s)", p.Name))
|
|
||||||
} else if p.Type == "uint64" {
|
|
||||||
argscommon = append(argscommon, p.Name)
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s uint64", p.Name))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.ulonglong(%s)", p.Name))
|
|
||||||
} else if p.Type == "uintptr" {
|
|
||||||
argscommon = append(argscommon, p.Name)
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
|
|
||||||
argsgc = append(argsgc, p.Name)
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
|
|
||||||
} else {
|
|
||||||
argscommon = append(argscommon, fmt.Sprintf("int(%s)", p.Name))
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s int", p.Name))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name))
|
|
||||||
}
|
|
||||||
argN++
|
|
||||||
}
|
|
||||||
nargs := len(argsgc)
|
|
||||||
|
|
||||||
// COMMON function generation
|
|
||||||
argscommonlist := strings.Join(argscommon, ", ")
|
|
||||||
callcommon := fmt.Sprintf("call%s(%s)", sysname, argscommonlist)
|
|
||||||
ret := []string{"_", "_"}
|
|
||||||
body := ""
|
|
||||||
doErrno := false
|
|
||||||
for i := 0; i < len(out); i++ {
|
|
||||||
p := parseParam(out[i])
|
|
||||||
reg := ""
|
|
||||||
if p.Name == "err" {
|
|
||||||
reg = "e1"
|
|
||||||
ret[1] = reg
|
|
||||||
doErrno = true
|
|
||||||
} else {
|
|
||||||
reg = "r0"
|
|
||||||
ret[0] = reg
|
|
||||||
}
|
|
||||||
if p.Type == "bool" {
|
|
||||||
reg = fmt.Sprintf("%s != 0", reg)
|
|
||||||
}
|
|
||||||
if reg != "e1" {
|
|
||||||
body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ret[0] == "_" && ret[1] == "_" {
|
|
||||||
textcommon += fmt.Sprintf("\t%s\n", callcommon)
|
|
||||||
} else {
|
|
||||||
textcommon += fmt.Sprintf("\t%s, %s := %s\n", ret[0], ret[1], callcommon)
|
|
||||||
}
|
|
||||||
textcommon += body
|
|
||||||
|
|
||||||
if doErrno {
|
|
||||||
textcommon += "\tif e1 != 0 {\n"
|
|
||||||
textcommon += "\t\terr = errnoErr(e1)\n"
|
|
||||||
textcommon += "\t}\n"
|
|
||||||
}
|
|
||||||
textcommon += "\treturn\n"
|
|
||||||
textcommon += "}\n"
|
|
||||||
|
|
||||||
if onlyCommon {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// CALL Prototype
|
|
||||||
callProto := fmt.Sprintf("func call%s(%s) (r1 uintptr, e1 Errno) {\n", sysname, strings.Join(argscall, ", "))
|
|
||||||
|
|
||||||
// GC function generation
|
|
||||||
asm := "syscall6"
|
|
||||||
if nonblock != nil {
|
|
||||||
asm = "rawSyscall6"
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(argsgc) <= 6 {
|
|
||||||
for len(argsgc) < 6 {
|
|
||||||
argsgc = append(argsgc, "0")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s: too many arguments to system call", funct)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
argsgclist := strings.Join(argsgc, ", ")
|
|
||||||
callgc := fmt.Sprintf("%s(uintptr(unsafe.Pointer(&%s)), %d, %s)", asm, sysvarname, nargs, argsgclist)
|
|
||||||
|
|
||||||
textgc += callProto
|
|
||||||
textgc += fmt.Sprintf("\tr1, _, e1 = %s\n", callgc)
|
|
||||||
textgc += "\treturn\n}\n"
|
|
||||||
|
|
||||||
// GCCGO function generation
|
|
||||||
argsgccgolist := strings.Join(argsgccgo, ", ")
|
|
||||||
var callgccgo string
|
|
||||||
if sysname == "select" {
|
|
||||||
// select is a keyword of Go. Its name is
|
|
||||||
// changed to c_select.
|
|
||||||
callgccgo = fmt.Sprintf("C.c_%s(%s)", sysname, argsgccgolist)
|
|
||||||
} else {
|
|
||||||
callgccgo = fmt.Sprintf("C.%s(%s)", sysname, argsgccgolist)
|
|
||||||
}
|
|
||||||
textgccgo += callProto
|
|
||||||
textgccgo += fmt.Sprintf("\tr1 = uintptr(%s)\n", callgccgo)
|
|
||||||
textgccgo += "\te1 = syscall.GetErrno()\n"
|
|
||||||
textgccgo += "\treturn\n}\n"
|
|
||||||
}
|
|
||||||
if err := s.Err(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
file.Close()
|
|
||||||
}
|
|
||||||
imp := ""
|
|
||||||
if pack != "unix" {
|
|
||||||
imp = "import \"golang.org/x/sys/unix\"\n"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print zsyscall_aix_ppc64.go
|
|
||||||
err := ioutil.WriteFile("zsyscall_aix_ppc64.go",
|
|
||||||
[]byte(fmt.Sprintf(srcTemplate1, cmdLine(), buildTags(), pack, imp, textcommon)),
|
|
||||||
0644)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print zsyscall_aix_ppc64_gc.go
|
|
||||||
vardecls := "\t" + strings.Join(vars, ",\n\t")
|
|
||||||
vardecls += " syscallFunc"
|
|
||||||
err = ioutil.WriteFile("zsyscall_aix_ppc64_gc.go",
|
|
||||||
[]byte(fmt.Sprintf(srcTemplate2, cmdLine(), buildTags(), pack, imp, dynimports, linknames, vardecls, textgc)),
|
|
||||||
0644)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print zsyscall_aix_ppc64_gccgo.go
|
|
||||||
err = ioutil.WriteFile("zsyscall_aix_ppc64_gccgo.go",
|
|
||||||
[]byte(fmt.Sprintf(srcTemplate3, cmdLine(), buildTags(), pack, cExtern, imp, textgccgo)),
|
|
||||||
0644)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const srcTemplate1 = `// %s
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s
|
|
||||||
|
|
||||||
package %s
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
%s
|
|
||||||
|
|
||||||
%s
|
|
||||||
`
|
|
||||||
const srcTemplate2 = `// %s
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
package %s
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
%s
|
|
||||||
%s
|
|
||||||
%s
|
|
||||||
type syscallFunc uintptr
|
|
||||||
|
|
||||||
var (
|
|
||||||
%s
|
|
||||||
)
|
|
||||||
|
|
||||||
// Implemented in runtime/syscall_aix.go.
|
|
||||||
func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
|
||||||
func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
|
||||||
|
|
||||||
%s
|
|
||||||
`
|
|
||||||
const srcTemplate3 = `// %s
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s
|
|
||||||
// +build gccgo
|
|
||||||
|
|
||||||
package %s
|
|
||||||
|
|
||||||
%s
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
%s
|
|
||||||
|
|
||||||
%s
|
|
||||||
`
|
|
@ -1,341 +0,0 @@
|
|||||||
// Copyright 2019 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.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
/*
|
|
||||||
This program reads a file containing function prototypes
|
|
||||||
(like syscall_solaris.go) and generates system call bodies.
|
|
||||||
The prototypes are marked by lines beginning with "//sys"
|
|
||||||
and read like func declarations if //sys is replaced by func, but:
|
|
||||||
* The parameter lists must give a name for each argument.
|
|
||||||
This includes return parameters.
|
|
||||||
* The parameter lists must give a type for each argument:
|
|
||||||
the (x, y, z int) shorthand is not allowed.
|
|
||||||
* If the return parameter is an error number, it must be named err.
|
|
||||||
* If go func name needs to be different than its libc name,
|
|
||||||
* or the function is not in libc, name could be specified
|
|
||||||
* at the end, after "=" sign, like
|
|
||||||
//sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
|
|
||||||
*/
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
b32 = flag.Bool("b32", false, "32bit big-endian")
|
|
||||||
l32 = flag.Bool("l32", false, "32bit little-endian")
|
|
||||||
tags = flag.String("tags", "", "build tags")
|
|
||||||
illumos = flag.Bool("illumos", false, "illumos specific code generation")
|
|
||||||
)
|
|
||||||
|
|
||||||
// cmdLine returns this programs's commandline arguments
|
|
||||||
func cmdLine() string {
|
|
||||||
return "go run mksyscall_solaris.go " + strings.Join(os.Args[1:], " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildTags returns build tags
|
|
||||||
func buildTags() string {
|
|
||||||
return *tags
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is function parameter
|
|
||||||
type Param struct {
|
|
||||||
Name string
|
|
||||||
Type string
|
|
||||||
}
|
|
||||||
|
|
||||||
// usage prints the program usage
|
|
||||||
func usage() {
|
|
||||||
fmt.Fprintf(os.Stderr, "usage: go run mksyscall_solaris.go [-b32 | -l32] [-tags x,y] [file ...]\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseParamList parses parameter list and returns a slice of parameters
|
|
||||||
func parseParamList(list string) []string {
|
|
||||||
list = strings.TrimSpace(list)
|
|
||||||
if list == "" {
|
|
||||||
return []string{}
|
|
||||||
}
|
|
||||||
return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseParam splits a parameter into name and type
|
|
||||||
func parseParam(p string) Param {
|
|
||||||
ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
|
|
||||||
if ps == nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
return Param{ps[1], ps[2]}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Usage = usage
|
|
||||||
flag.Parse()
|
|
||||||
if len(flag.Args()) <= 0 {
|
|
||||||
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
|
|
||||||
usage()
|
|
||||||
}
|
|
||||||
|
|
||||||
endianness := ""
|
|
||||||
if *b32 {
|
|
||||||
endianness = "big-endian"
|
|
||||||
} else if *l32 {
|
|
||||||
endianness = "little-endian"
|
|
||||||
}
|
|
||||||
|
|
||||||
pack := ""
|
|
||||||
text := ""
|
|
||||||
dynimports := ""
|
|
||||||
linknames := ""
|
|
||||||
var vars []string
|
|
||||||
for _, path := range flag.Args() {
|
|
||||||
file, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
s := bufio.NewScanner(file)
|
|
||||||
for s.Scan() {
|
|
||||||
t := s.Text()
|
|
||||||
t = strings.TrimSpace(t)
|
|
||||||
t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
|
|
||||||
if p := regexp.MustCompile(`^package (\S+)$`).FindStringSubmatch(t); p != nil && pack == "" {
|
|
||||||
pack = p[1]
|
|
||||||
}
|
|
||||||
nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
|
|
||||||
if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Line must be of the form
|
|
||||||
// func Open(path string, mode int, perm int) (fd int, err error)
|
|
||||||
// Split into name, in params, out params.
|
|
||||||
f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$`).FindStringSubmatch(t)
|
|
||||||
if f == nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
funct, inps, outps, modname, sysname := f[2], f[3], f[4], f[5], f[6]
|
|
||||||
|
|
||||||
// Split argument lists on comma.
|
|
||||||
in := parseParamList(inps)
|
|
||||||
out := parseParamList(outps)
|
|
||||||
|
|
||||||
inps = strings.Join(in, ", ")
|
|
||||||
outps = strings.Join(out, ", ")
|
|
||||||
|
|
||||||
// Try in vain to keep people from editing this file.
|
|
||||||
// The theory is that they jump into the middle of the file
|
|
||||||
// without reading the header.
|
|
||||||
text += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
|
|
||||||
|
|
||||||
// So file name.
|
|
||||||
if modname == "" {
|
|
||||||
modname = "libc"
|
|
||||||
}
|
|
||||||
|
|
||||||
// System call name.
|
|
||||||
if sysname == "" {
|
|
||||||
sysname = funct
|
|
||||||
}
|
|
||||||
|
|
||||||
// System call pointer variable name.
|
|
||||||
sysvarname := fmt.Sprintf("proc%s", sysname)
|
|
||||||
|
|
||||||
strconvfunc := "BytePtrFromString"
|
|
||||||
strconvtype := "*byte"
|
|
||||||
|
|
||||||
sysname = strings.ToLower(sysname) // All libc functions are lowercase.
|
|
||||||
|
|
||||||
// Runtime import of function to allow cross-platform builds.
|
|
||||||
dynimports += fmt.Sprintf("//go:cgo_import_dynamic libc_%s %s \"%s.so\"\n", sysname, sysname, modname)
|
|
||||||
// Link symbol to proc address variable.
|
|
||||||
linknames += fmt.Sprintf("//go:linkname %s libc_%s\n", sysvarname, sysname)
|
|
||||||
// Library proc address variable.
|
|
||||||
vars = append(vars, sysvarname)
|
|
||||||
|
|
||||||
// Go function header.
|
|
||||||
outlist := strings.Join(out, ", ")
|
|
||||||
if outlist != "" {
|
|
||||||
outlist = fmt.Sprintf(" (%s)", outlist)
|
|
||||||
}
|
|
||||||
if text != "" {
|
|
||||||
text += "\n"
|
|
||||||
}
|
|
||||||
text += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outlist)
|
|
||||||
|
|
||||||
// Check if err return available
|
|
||||||
errvar := ""
|
|
||||||
for _, param := range out {
|
|
||||||
p := parseParam(param)
|
|
||||||
if p.Type == "error" {
|
|
||||||
errvar = p.Name
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare arguments to Syscall.
|
|
||||||
var args []string
|
|
||||||
n := 0
|
|
||||||
for _, param := range in {
|
|
||||||
p := parseParam(param)
|
|
||||||
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
args = append(args, "uintptr(unsafe.Pointer("+p.Name+"))")
|
|
||||||
} else if p.Type == "string" && errvar != "" {
|
|
||||||
text += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
|
|
||||||
text += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name)
|
|
||||||
text += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
|
|
||||||
n++
|
|
||||||
} else if p.Type == "string" {
|
|
||||||
fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
|
|
||||||
text += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
|
|
||||||
text += fmt.Sprintf("\t_p%d, _ = %s(%s)\n", n, strconvfunc, p.Name)
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
|
|
||||||
n++
|
|
||||||
} else if s := regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type); s != nil {
|
|
||||||
// Convert slice into pointer, length.
|
|
||||||
// Have to be careful not to take address of &a[0] if len == 0:
|
|
||||||
// pass nil in that case.
|
|
||||||
text += fmt.Sprintf("\tvar _p%d *%s\n", n, s[1])
|
|
||||||
text += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = &%s[0]\n\t}\n", p.Name, n, p.Name)
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n), fmt.Sprintf("uintptr(len(%s))", p.Name))
|
|
||||||
n++
|
|
||||||
} else if p.Type == "int64" && endianness != "" {
|
|
||||||
if endianness == "big-endian" {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
|
|
||||||
}
|
|
||||||
} else if p.Type == "bool" {
|
|
||||||
text += fmt.Sprintf("\tvar _p%d uint32\n", n)
|
|
||||||
text += fmt.Sprintf("\tif %s {\n\t\t_p%d = 1\n\t} else {\n\t\t_p%d = 0\n\t}\n", p.Name, n, n)
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(_p%d)", n))
|
|
||||||
n++
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nargs := len(args)
|
|
||||||
|
|
||||||
// Determine which form to use; pad args with zeros.
|
|
||||||
asm := "sysvicall6"
|
|
||||||
if nonblock != nil {
|
|
||||||
asm = "rawSysvicall6"
|
|
||||||
}
|
|
||||||
if len(args) <= 6 {
|
|
||||||
for len(args) < 6 {
|
|
||||||
args = append(args, "0")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s: too many arguments to system call\n", path)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actual call.
|
|
||||||
arglist := strings.Join(args, ", ")
|
|
||||||
call := fmt.Sprintf("%s(uintptr(unsafe.Pointer(&%s)), %d, %s)", asm, sysvarname, nargs, arglist)
|
|
||||||
|
|
||||||
// Assign return values.
|
|
||||||
body := ""
|
|
||||||
ret := []string{"_", "_", "_"}
|
|
||||||
doErrno := false
|
|
||||||
for i := 0; i < len(out); i++ {
|
|
||||||
p := parseParam(out[i])
|
|
||||||
reg := ""
|
|
||||||
if p.Name == "err" {
|
|
||||||
reg = "e1"
|
|
||||||
ret[2] = reg
|
|
||||||
doErrno = true
|
|
||||||
} else {
|
|
||||||
reg = fmt.Sprintf("r%d", i)
|
|
||||||
ret[i] = reg
|
|
||||||
}
|
|
||||||
if p.Type == "bool" {
|
|
||||||
reg = fmt.Sprintf("%d != 0", reg)
|
|
||||||
}
|
|
||||||
if p.Type == "int64" && endianness != "" {
|
|
||||||
// 64-bit number in r1:r0 or r0:r1.
|
|
||||||
if i+2 > len(out) {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s: not enough registers for int64 return\n", path)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
if endianness == "big-endian" {
|
|
||||||
reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i, i+1)
|
|
||||||
} else {
|
|
||||||
reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i+1, i)
|
|
||||||
}
|
|
||||||
ret[i] = fmt.Sprintf("r%d", i)
|
|
||||||
ret[i+1] = fmt.Sprintf("r%d", i+1)
|
|
||||||
}
|
|
||||||
if reg != "e1" {
|
|
||||||
body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ret[0] == "_" && ret[1] == "_" && ret[2] == "_" {
|
|
||||||
text += fmt.Sprintf("\t%s\n", call)
|
|
||||||
} else {
|
|
||||||
text += fmt.Sprintf("\t%s, %s, %s := %s\n", ret[0], ret[1], ret[2], call)
|
|
||||||
}
|
|
||||||
text += body
|
|
||||||
|
|
||||||
if doErrno {
|
|
||||||
text += "\tif e1 != 0 {\n"
|
|
||||||
text += "\t\terr = e1\n"
|
|
||||||
text += "\t}\n"
|
|
||||||
}
|
|
||||||
text += "\treturn\n"
|
|
||||||
text += "}\n"
|
|
||||||
}
|
|
||||||
if err := s.Err(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
file.Close()
|
|
||||||
}
|
|
||||||
imp := ""
|
|
||||||
if pack != "unix" {
|
|
||||||
imp = "import \"golang.org/x/sys/unix\"\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
syscallimp := ""
|
|
||||||
if !*illumos {
|
|
||||||
syscallimp = "\"syscall\""
|
|
||||||
}
|
|
||||||
|
|
||||||
vardecls := "\t" + strings.Join(vars, ",\n\t")
|
|
||||||
vardecls += " syscallFunc"
|
|
||||||
fmt.Printf(srcTemplate, cmdLine(), buildTags(), pack, syscallimp, imp, dynimports, linknames, vardecls, text)
|
|
||||||
}
|
|
||||||
|
|
||||||
const srcTemplate = `// %s
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s
|
|
||||||
|
|
||||||
package %s
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
%s
|
|
||||||
)
|
|
||||||
%s
|
|
||||||
%s
|
|
||||||
%s
|
|
||||||
var (
|
|
||||||
%s
|
|
||||||
)
|
|
||||||
|
|
||||||
%s
|
|
||||||
`
|
|
@ -1,355 +0,0 @@
|
|||||||
// Copyright 2019 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.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// Parse the header files for OpenBSD and generate a Go usable sysctl MIB.
|
|
||||||
//
|
|
||||||
// Build a MIB with each entry being an array containing the level, type and
|
|
||||||
// a hash that will contain additional entries if the current entry is a node.
|
|
||||||
// We then walk this MIB and create a flattened sysctl name to OID hash.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
goos, goarch string
|
|
||||||
)
|
|
||||||
|
|
||||||
// cmdLine returns this programs's commandline arguments.
|
|
||||||
func cmdLine() string {
|
|
||||||
return "go run mksysctl_openbsd.go " + strings.Join(os.Args[1:], " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildTags returns build tags.
|
|
||||||
func buildTags() string {
|
|
||||||
return fmt.Sprintf("%s,%s", goarch, goos)
|
|
||||||
}
|
|
||||||
|
|
||||||
// reMatch performs regular expression match and stores the substring slice to value pointed by m.
|
|
||||||
func reMatch(re *regexp.Regexp, str string, m *[]string) bool {
|
|
||||||
*m = re.FindStringSubmatch(str)
|
|
||||||
if *m != nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
type nodeElement struct {
|
|
||||||
n int
|
|
||||||
t string
|
|
||||||
pE *map[string]nodeElement
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
debugEnabled bool
|
|
||||||
mib map[string]nodeElement
|
|
||||||
node *map[string]nodeElement
|
|
||||||
nodeMap map[string]string
|
|
||||||
sysCtl []string
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ctlNames1RE = regexp.MustCompile(`^#define\s+(CTL_NAMES)\s+{`)
|
|
||||||
ctlNames2RE = regexp.MustCompile(`^#define\s+(CTL_(.*)_NAMES)\s+{`)
|
|
||||||
ctlNames3RE = regexp.MustCompile(`^#define\s+((.*)CTL_NAMES)\s+{`)
|
|
||||||
netInetRE = regexp.MustCompile(`^netinet/`)
|
|
||||||
netInet6RE = regexp.MustCompile(`^netinet6/`)
|
|
||||||
netRE = regexp.MustCompile(`^net/`)
|
|
||||||
bracesRE = regexp.MustCompile(`{.*}`)
|
|
||||||
ctlTypeRE = regexp.MustCompile(`{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}`)
|
|
||||||
fsNetKernRE = regexp.MustCompile(`^(fs|net|kern)_`)
|
|
||||||
)
|
|
||||||
|
|
||||||
func debug(s string) {
|
|
||||||
if debugEnabled {
|
|
||||||
fmt.Fprintln(os.Stderr, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Walk the MIB and build a sysctl name to OID mapping.
|
|
||||||
func buildSysctl(pNode *map[string]nodeElement, name string, oid []int) {
|
|
||||||
lNode := pNode // local copy of pointer to node
|
|
||||||
var keys []string
|
|
||||||
for k := range *lNode {
|
|
||||||
keys = append(keys, k)
|
|
||||||
}
|
|
||||||
sort.Strings(keys)
|
|
||||||
|
|
||||||
for _, key := range keys {
|
|
||||||
nodename := name
|
|
||||||
if name != "" {
|
|
||||||
nodename += "."
|
|
||||||
}
|
|
||||||
nodename += key
|
|
||||||
|
|
||||||
nodeoid := append(oid, (*pNode)[key].n)
|
|
||||||
|
|
||||||
if (*pNode)[key].t == `CTLTYPE_NODE` {
|
|
||||||
if _, ok := nodeMap[nodename]; ok {
|
|
||||||
lNode = &mib
|
|
||||||
ctlName := nodeMap[nodename]
|
|
||||||
for _, part := range strings.Split(ctlName, ".") {
|
|
||||||
lNode = ((*lNode)[part]).pE
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
lNode = (*pNode)[key].pE
|
|
||||||
}
|
|
||||||
buildSysctl(lNode, nodename, nodeoid)
|
|
||||||
} else if (*pNode)[key].t != "" {
|
|
||||||
oidStr := []string{}
|
|
||||||
for j := range nodeoid {
|
|
||||||
oidStr = append(oidStr, fmt.Sprintf("%d", nodeoid[j]))
|
|
||||||
}
|
|
||||||
text := "\t{ \"" + nodename + "\", []_C_int{ " + strings.Join(oidStr, ", ") + " } }, \n"
|
|
||||||
sysCtl = append(sysCtl, text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Get the OS (using GOOS_TARGET if it exist)
|
|
||||||
goos = os.Getenv("GOOS_TARGET")
|
|
||||||
if goos == "" {
|
|
||||||
goos = os.Getenv("GOOS")
|
|
||||||
}
|
|
||||||
// Get the architecture (using GOARCH_TARGET if it exists)
|
|
||||||
goarch = os.Getenv("GOARCH_TARGET")
|
|
||||||
if goarch == "" {
|
|
||||||
goarch = os.Getenv("GOARCH")
|
|
||||||
}
|
|
||||||
// Check if GOOS and GOARCH environment variables are defined
|
|
||||||
if goarch == "" || goos == "" {
|
|
||||||
fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
mib = make(map[string]nodeElement)
|
|
||||||
headers := [...]string{
|
|
||||||
`sys/sysctl.h`,
|
|
||||||
`sys/socket.h`,
|
|
||||||
`sys/tty.h`,
|
|
||||||
`sys/malloc.h`,
|
|
||||||
`sys/mount.h`,
|
|
||||||
`sys/namei.h`,
|
|
||||||
`sys/sem.h`,
|
|
||||||
`sys/shm.h`,
|
|
||||||
`sys/vmmeter.h`,
|
|
||||||
`uvm/uvmexp.h`,
|
|
||||||
`uvm/uvm_param.h`,
|
|
||||||
`uvm/uvm_swap_encrypt.h`,
|
|
||||||
`ddb/db_var.h`,
|
|
||||||
`net/if.h`,
|
|
||||||
`net/if_pfsync.h`,
|
|
||||||
`net/pipex.h`,
|
|
||||||
`netinet/in.h`,
|
|
||||||
`netinet/icmp_var.h`,
|
|
||||||
`netinet/igmp_var.h`,
|
|
||||||
`netinet/ip_ah.h`,
|
|
||||||
`netinet/ip_carp.h`,
|
|
||||||
`netinet/ip_divert.h`,
|
|
||||||
`netinet/ip_esp.h`,
|
|
||||||
`netinet/ip_ether.h`,
|
|
||||||
`netinet/ip_gre.h`,
|
|
||||||
`netinet/ip_ipcomp.h`,
|
|
||||||
`netinet/ip_ipip.h`,
|
|
||||||
`netinet/pim_var.h`,
|
|
||||||
`netinet/tcp_var.h`,
|
|
||||||
`netinet/udp_var.h`,
|
|
||||||
`netinet6/in6.h`,
|
|
||||||
`netinet6/ip6_divert.h`,
|
|
||||||
`netinet6/pim6_var.h`,
|
|
||||||
`netinet/icmp6.h`,
|
|
||||||
`netmpls/mpls.h`,
|
|
||||||
}
|
|
||||||
|
|
||||||
ctls := [...]string{
|
|
||||||
`kern`,
|
|
||||||
`vm`,
|
|
||||||
`fs`,
|
|
||||||
`net`,
|
|
||||||
//debug /* Special handling required */
|
|
||||||
`hw`,
|
|
||||||
//machdep /* Arch specific */
|
|
||||||
`user`,
|
|
||||||
`ddb`,
|
|
||||||
//vfs /* Special handling required */
|
|
||||||
`fs.posix`,
|
|
||||||
`kern.forkstat`,
|
|
||||||
`kern.intrcnt`,
|
|
||||||
`kern.malloc`,
|
|
||||||
`kern.nchstats`,
|
|
||||||
`kern.seminfo`,
|
|
||||||
`kern.shminfo`,
|
|
||||||
`kern.timecounter`,
|
|
||||||
`kern.tty`,
|
|
||||||
`kern.watchdog`,
|
|
||||||
`net.bpf`,
|
|
||||||
`net.ifq`,
|
|
||||||
`net.inet`,
|
|
||||||
`net.inet.ah`,
|
|
||||||
`net.inet.carp`,
|
|
||||||
`net.inet.divert`,
|
|
||||||
`net.inet.esp`,
|
|
||||||
`net.inet.etherip`,
|
|
||||||
`net.inet.gre`,
|
|
||||||
`net.inet.icmp`,
|
|
||||||
`net.inet.igmp`,
|
|
||||||
`net.inet.ip`,
|
|
||||||
`net.inet.ip.ifq`,
|
|
||||||
`net.inet.ipcomp`,
|
|
||||||
`net.inet.ipip`,
|
|
||||||
`net.inet.mobileip`,
|
|
||||||
`net.inet.pfsync`,
|
|
||||||
`net.inet.pim`,
|
|
||||||
`net.inet.tcp`,
|
|
||||||
`net.inet.udp`,
|
|
||||||
`net.inet6`,
|
|
||||||
`net.inet6.divert`,
|
|
||||||
`net.inet6.ip6`,
|
|
||||||
`net.inet6.icmp6`,
|
|
||||||
`net.inet6.pim6`,
|
|
||||||
`net.inet6.tcp6`,
|
|
||||||
`net.inet6.udp6`,
|
|
||||||
`net.mpls`,
|
|
||||||
`net.mpls.ifq`,
|
|
||||||
`net.key`,
|
|
||||||
`net.pflow`,
|
|
||||||
`net.pfsync`,
|
|
||||||
`net.pipex`,
|
|
||||||
`net.rt`,
|
|
||||||
`vm.swapencrypt`,
|
|
||||||
//vfsgenctl /* Special handling required */
|
|
||||||
}
|
|
||||||
|
|
||||||
// Node name "fixups"
|
|
||||||
ctlMap := map[string]string{
|
|
||||||
"ipproto": "net.inet",
|
|
||||||
"net.inet.ipproto": "net.inet",
|
|
||||||
"net.inet6.ipv6proto": "net.inet6",
|
|
||||||
"net.inet6.ipv6": "net.inet6.ip6",
|
|
||||||
"net.inet.icmpv6": "net.inet6.icmp6",
|
|
||||||
"net.inet6.divert6": "net.inet6.divert",
|
|
||||||
"net.inet6.tcp6": "net.inet.tcp",
|
|
||||||
"net.inet6.udp6": "net.inet.udp",
|
|
||||||
"mpls": "net.mpls",
|
|
||||||
"swpenc": "vm.swapencrypt",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Node mappings
|
|
||||||
nodeMap = map[string]string{
|
|
||||||
"net.inet.ip.ifq": "net.ifq",
|
|
||||||
"net.inet.pfsync": "net.pfsync",
|
|
||||||
"net.mpls.ifq": "net.ifq",
|
|
||||||
}
|
|
||||||
|
|
||||||
mCtls := make(map[string]bool)
|
|
||||||
for _, ctl := range ctls {
|
|
||||||
mCtls[ctl] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, header := range headers {
|
|
||||||
debug("Processing " + header)
|
|
||||||
file, err := os.Open(filepath.Join("/usr/include", header))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
s := bufio.NewScanner(file)
|
|
||||||
for s.Scan() {
|
|
||||||
var sub []string
|
|
||||||
if reMatch(ctlNames1RE, s.Text(), &sub) ||
|
|
||||||
reMatch(ctlNames2RE, s.Text(), &sub) ||
|
|
||||||
reMatch(ctlNames3RE, s.Text(), &sub) {
|
|
||||||
if sub[1] == `CTL_NAMES` {
|
|
||||||
// Top level.
|
|
||||||
node = &mib
|
|
||||||
} else {
|
|
||||||
// Node.
|
|
||||||
nodename := strings.ToLower(sub[2])
|
|
||||||
ctlName := ""
|
|
||||||
if reMatch(netInetRE, header, &sub) {
|
|
||||||
ctlName = "net.inet." + nodename
|
|
||||||
} else if reMatch(netInet6RE, header, &sub) {
|
|
||||||
ctlName = "net.inet6." + nodename
|
|
||||||
} else if reMatch(netRE, header, &sub) {
|
|
||||||
ctlName = "net." + nodename
|
|
||||||
} else {
|
|
||||||
ctlName = nodename
|
|
||||||
ctlName = fsNetKernRE.ReplaceAllString(ctlName, `$1.`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if val, ok := ctlMap[ctlName]; ok {
|
|
||||||
ctlName = val
|
|
||||||
}
|
|
||||||
if _, ok := mCtls[ctlName]; !ok {
|
|
||||||
debug("Ignoring " + ctlName + "...")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Walk down from the top of the MIB.
|
|
||||||
node = &mib
|
|
||||||
for _, part := range strings.Split(ctlName, ".") {
|
|
||||||
if _, ok := (*node)[part]; !ok {
|
|
||||||
debug("Missing node " + part)
|
|
||||||
(*node)[part] = nodeElement{n: 0, t: "", pE: &map[string]nodeElement{}}
|
|
||||||
}
|
|
||||||
node = (*node)[part].pE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate current node with entries.
|
|
||||||
i := -1
|
|
||||||
for !strings.HasPrefix(s.Text(), "}") {
|
|
||||||
s.Scan()
|
|
||||||
if reMatch(bracesRE, s.Text(), &sub) {
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
if !reMatch(ctlTypeRE, s.Text(), &sub) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
(*node)[sub[1]] = nodeElement{n: i, t: sub[2], pE: &map[string]nodeElement{}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = s.Err()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
file.Close()
|
|
||||||
}
|
|
||||||
buildSysctl(&mib, "", []int{})
|
|
||||||
|
|
||||||
sort.Strings(sysCtl)
|
|
||||||
text := strings.Join(sysCtl, "")
|
|
||||||
|
|
||||||
fmt.Printf(srcTemplate, cmdLine(), buildTags(), text)
|
|
||||||
}
|
|
||||||
|
|
||||||
const srcTemplate = `// %s
|
|
||||||
// Code generated by the command above; DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
type mibentry struct {
|
|
||||||
ctlname string
|
|
||||||
ctloid []_C_int
|
|
||||||
}
|
|
||||||
|
|
||||||
var sysctlMib = []mibentry {
|
|
||||||
%s
|
|
||||||
}
|
|
||||||
`
|
|
@ -1,190 +0,0 @@
|
|||||||
// Copyright 2018 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.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// Generate system call table for DragonFly, NetBSD,
|
|
||||||
// FreeBSD, OpenBSD or Darwin from master list
|
|
||||||
// (for example, /usr/src/sys/kern/syscalls.master or
|
|
||||||
// sys/syscall.h).
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
goos, goarch string
|
|
||||||
)
|
|
||||||
|
|
||||||
// cmdLine returns this programs's commandline arguments
|
|
||||||
func cmdLine() string {
|
|
||||||
return "go run mksysnum.go " + strings.Join(os.Args[1:], " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildTags returns build tags
|
|
||||||
func buildTags() string {
|
|
||||||
return fmt.Sprintf("%s,%s", goarch, goos)
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkErr(err error) {
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// source string and substring slice for regexp
|
|
||||||
type re struct {
|
|
||||||
str string // source string
|
|
||||||
sub []string // matched sub-string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match performs regular expression match
|
|
||||||
func (r *re) Match(exp string) bool {
|
|
||||||
r.sub = regexp.MustCompile(exp).FindStringSubmatch(r.str)
|
|
||||||
if r.sub != nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// fetchFile fetches a text file from URL
|
|
||||||
func fetchFile(URL string) io.Reader {
|
|
||||||
resp, err := http.Get(URL)
|
|
||||||
checkErr(err)
|
|
||||||
defer resp.Body.Close()
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
|
||||||
checkErr(err)
|
|
||||||
return strings.NewReader(string(body))
|
|
||||||
}
|
|
||||||
|
|
||||||
// readFile reads a text file from path
|
|
||||||
func readFile(path string) io.Reader {
|
|
||||||
file, err := os.Open(os.Args[1])
|
|
||||||
checkErr(err)
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
|
|
||||||
func format(name, num, proto string) string {
|
|
||||||
name = strings.ToUpper(name)
|
|
||||||
// There are multiple entries for enosys and nosys, so comment them out.
|
|
||||||
nm := re{str: name}
|
|
||||||
if nm.Match(`^SYS_E?NOSYS$`) {
|
|
||||||
name = fmt.Sprintf("// %s", name)
|
|
||||||
}
|
|
||||||
if name == `SYS_SYS_EXIT` {
|
|
||||||
name = `SYS_EXIT`
|
|
||||||
}
|
|
||||||
return fmt.Sprintf(" %s = %s; // %s\n", name, num, proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Get the OS (using GOOS_TARGET if it exist)
|
|
||||||
goos = os.Getenv("GOOS_TARGET")
|
|
||||||
if goos == "" {
|
|
||||||
goos = os.Getenv("GOOS")
|
|
||||||
}
|
|
||||||
// Get the architecture (using GOARCH_TARGET if it exists)
|
|
||||||
goarch = os.Getenv("GOARCH_TARGET")
|
|
||||||
if goarch == "" {
|
|
||||||
goarch = os.Getenv("GOARCH")
|
|
||||||
}
|
|
||||||
// Check if GOOS and GOARCH environment variables are defined
|
|
||||||
if goarch == "" || goos == "" {
|
|
||||||
fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
file := strings.TrimSpace(os.Args[1])
|
|
||||||
var syscalls io.Reader
|
|
||||||
if strings.HasPrefix(file, "https://") || strings.HasPrefix(file, "http://") {
|
|
||||||
// Download syscalls.master file
|
|
||||||
syscalls = fetchFile(file)
|
|
||||||
} else {
|
|
||||||
syscalls = readFile(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
var text, line string
|
|
||||||
s := bufio.NewScanner(syscalls)
|
|
||||||
for s.Scan() {
|
|
||||||
t := re{str: line}
|
|
||||||
if t.Match(`^(.*)\\$`) {
|
|
||||||
// Handle continuation
|
|
||||||
line = t.sub[1]
|
|
||||||
line += strings.TrimLeft(s.Text(), " \t")
|
|
||||||
} else {
|
|
||||||
// New line
|
|
||||||
line = s.Text()
|
|
||||||
}
|
|
||||||
t = re{str: line}
|
|
||||||
if t.Match(`\\$`) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t = re{str: line}
|
|
||||||
|
|
||||||
switch goos {
|
|
||||||
case "dragonfly":
|
|
||||||
if t.Match(`^([0-9]+)\s+STD\s+({ \S+\s+(\w+).*)$`) {
|
|
||||||
num, proto := t.sub[1], t.sub[2]
|
|
||||||
name := fmt.Sprintf("SYS_%s", t.sub[3])
|
|
||||||
text += format(name, num, proto)
|
|
||||||
}
|
|
||||||
case "freebsd":
|
|
||||||
if t.Match(`^([0-9]+)\s+\S+\s+(?:(?:NO)?STD|COMPAT10)\s+({ \S+\s+(\w+).*)$`) {
|
|
||||||
num, proto := t.sub[1], t.sub[2]
|
|
||||||
name := fmt.Sprintf("SYS_%s", t.sub[3])
|
|
||||||
text += format(name, num, proto)
|
|
||||||
}
|
|
||||||
case "openbsd":
|
|
||||||
if t.Match(`^([0-9]+)\s+STD\s+(NOLOCK\s+)?({ \S+\s+\*?(\w+).*)$`) {
|
|
||||||
num, proto, name := t.sub[1], t.sub[3], t.sub[4]
|
|
||||||
text += format(name, num, proto)
|
|
||||||
}
|
|
||||||
case "netbsd":
|
|
||||||
if t.Match(`^([0-9]+)\s+((STD)|(NOERR))\s+(RUMP\s+)?({\s+\S+\s*\*?\s*\|(\S+)\|(\S*)\|(\w+).*\s+})(\s+(\S+))?$`) {
|
|
||||||
num, proto, compat := t.sub[1], t.sub[6], t.sub[8]
|
|
||||||
name := t.sub[7] + "_" + t.sub[9]
|
|
||||||
if t.sub[11] != "" {
|
|
||||||
name = t.sub[7] + "_" + t.sub[11]
|
|
||||||
}
|
|
||||||
name = strings.ToUpper(name)
|
|
||||||
if compat == "" || compat == "13" || compat == "30" || compat == "50" {
|
|
||||||
text += fmt.Sprintf(" %s = %s; // %s\n", name, num, proto)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "darwin":
|
|
||||||
if t.Match(`^#define\s+SYS_(\w+)\s+([0-9]+)`) {
|
|
||||||
name, num := t.sub[1], t.sub[2]
|
|
||||||
name = strings.ToUpper(name)
|
|
||||||
text += fmt.Sprintf(" SYS_%s = %s;\n", name, num)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
fmt.Fprintf(os.Stderr, "unrecognized GOOS=%s\n", goos)
|
|
||||||
os.Exit(1)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := s.Err()
|
|
||||||
checkErr(err)
|
|
||||||
|
|
||||||
fmt.Printf(template, cmdLine(), buildTags(), text)
|
|
||||||
}
|
|
||||||
|
|
||||||
const template = `// %s
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
const(
|
|
||||||
%s)`
|
|
@ -1,15 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
|
||||||
|
|
||||||
// For Unix, get the pagesize from the runtime.
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
func Getpagesize() int {
|
|
||||||
return syscall.Getpagesize()
|
|
||||||
}
|
|
@ -1,163 +0,0 @@
|
|||||||
// Copyright 2016 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 unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Pledge implements the pledge syscall.
|
|
||||||
//
|
|
||||||
// The pledge syscall does not accept execpromises on OpenBSD releases
|
|
||||||
// before 6.3.
|
|
||||||
//
|
|
||||||
// execpromises must be empty when Pledge is called on OpenBSD
|
|
||||||
// releases predating 6.3, otherwise an error will be returned.
|
|
||||||
//
|
|
||||||
// For more information see pledge(2).
|
|
||||||
func Pledge(promises, execpromises string) error {
|
|
||||||
maj, min, err := majmin()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = pledgeAvailable(maj, min, execpromises)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
pptr, err := syscall.BytePtrFromString(promises)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// This variable will hold either a nil unsafe.Pointer or
|
|
||||||
// an unsafe.Pointer to a string (execpromises).
|
|
||||||
var expr unsafe.Pointer
|
|
||||||
|
|
||||||
// If we're running on OpenBSD > 6.2, pass execpromises to the syscall.
|
|
||||||
if maj > 6 || (maj == 6 && min > 2) {
|
|
||||||
exptr, err := syscall.BytePtrFromString(execpromises)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
expr = unsafe.Pointer(exptr)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0)
|
|
||||||
if e != 0 {
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PledgePromises implements the pledge syscall.
|
|
||||||
//
|
|
||||||
// This changes the promises and leaves the execpromises untouched.
|
|
||||||
//
|
|
||||||
// For more information see pledge(2).
|
|
||||||
func PledgePromises(promises string) error {
|
|
||||||
maj, min, err := majmin()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = pledgeAvailable(maj, min, "")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// This variable holds the execpromises and is always nil.
|
|
||||||
var expr unsafe.Pointer
|
|
||||||
|
|
||||||
pptr, err := syscall.BytePtrFromString(promises)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0)
|
|
||||||
if e != 0 {
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PledgeExecpromises implements the pledge syscall.
|
|
||||||
//
|
|
||||||
// This changes the execpromises and leaves the promises untouched.
|
|
||||||
//
|
|
||||||
// For more information see pledge(2).
|
|
||||||
func PledgeExecpromises(execpromises string) error {
|
|
||||||
maj, min, err := majmin()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = pledgeAvailable(maj, min, execpromises)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// This variable holds the promises and is always nil.
|
|
||||||
var pptr unsafe.Pointer
|
|
||||||
|
|
||||||
exptr, err := syscall.BytePtrFromString(execpromises)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(pptr), uintptr(unsafe.Pointer(exptr)), 0)
|
|
||||||
if e != 0 {
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// majmin returns major and minor version number for an OpenBSD system.
|
|
||||||
func majmin() (major int, minor int, err error) {
|
|
||||||
var v Utsname
|
|
||||||
err = Uname(&v)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
major, err = strconv.Atoi(string(v.Release[0]))
|
|
||||||
if err != nil {
|
|
||||||
err = errors.New("cannot parse major version number returned by uname")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
minor, err = strconv.Atoi(string(v.Release[2]))
|
|
||||||
if err != nil {
|
|
||||||
err = errors.New("cannot parse minor version number returned by uname")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// pledgeAvailable checks for availability of the pledge(2) syscall
|
|
||||||
// based on the running OpenBSD version.
|
|
||||||
func pledgeAvailable(maj, min int, execpromises string) error {
|
|
||||||
// If OpenBSD <= 5.9, pledge is not available.
|
|
||||||
if (maj == 5 && min != 9) || maj < 5 {
|
|
||||||
return fmt.Errorf("pledge syscall is not available on OpenBSD %d.%d", maj, min)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If OpenBSD <= 6.2 and execpromises is not empty,
|
|
||||||
// return an error - execpromises is not available before 6.3
|
|
||||||
if (maj < 6 || (maj == 6 && min <= 2)) && execpromises != "" {
|
|
||||||
return fmt.Errorf("cannot use execpromises on OpenBSD %d.%d", maj, min)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
// Copyright 2012 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.
|
|
||||||
|
|
||||||
// +build darwin,race linux,race freebsd,race
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const raceenabled = true
|
|
||||||
|
|
||||||
func raceAcquire(addr unsafe.Pointer) {
|
|
||||||
runtime.RaceAcquire(addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func raceReleaseMerge(addr unsafe.Pointer) {
|
|
||||||
runtime.RaceReleaseMerge(addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func raceReadRange(addr unsafe.Pointer, len int) {
|
|
||||||
runtime.RaceReadRange(addr, len)
|
|
||||||
}
|
|
||||||
|
|
||||||
func raceWriteRange(addr unsafe.Pointer, len int) {
|
|
||||||
runtime.RaceWriteRange(addr, len)
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
// Copyright 2012 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.
|
|
||||||
|
|
||||||
// +build aix darwin,!race linux,!race freebsd,!race netbsd openbsd solaris dragonfly
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const raceenabled = false
|
|
||||||
|
|
||||||
func raceAcquire(addr unsafe.Pointer) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func raceReleaseMerge(addr unsafe.Pointer) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func raceReadRange(addr unsafe.Pointer, len int) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func raceWriteRange(addr unsafe.Pointer, len int) {
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue